Skip to content

Commit

Permalink
Merge pull request #215 from andrjohns/tbb-winarm64
Browse files Browse the repository at this point in the history
Support building TBB on Windows arm64
  • Loading branch information
kevinushey authored May 20, 2024
2 parents 5aa08f8 + f59d3bf commit 8ace319
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 29 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
^tests/testthat/pkg/RcppParallelTest/src/.*\.s?o$
^tools/tbb$
^\.github$
^patches
12 changes: 7 additions & 5 deletions R/tbb.R
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,14 @@ tbbCxxFlags <- function() {
flags <- character()

# opt-in to TBB on Windows
if (is_windows())
if (is_windows()) {
flags <- c(flags, "-DRCPP_PARALLEL_USE_TBB=1")
if (R.version$arch == "aarch64") {
# TBB does not have assembly code for Windows ARM64
# so we need to use compiler builtins
flags <- c(flags, "-DTBB_USE_GCC_BUILTINS")
}
}

# if TBB_INC is set, apply those library paths
tbbInc <- Sys.getenv("TBB_INC", unset = TBB_INC)
Expand Down Expand Up @@ -81,10 +87,6 @@ tbbLdFlags <- function() {
return(sprintf(fmt, asBuildPath(tbbLib)))
}

# on Aarch64 builds, use the version of TBB provided by Rtools
if (is_windows() && R.version$arch == "aarch64")
return("-ltbb12 -ltbbmalloc")

# on Mac, Windows and Solaris, we need to explicitly link (#206)
needsExplicitFlags <- is_mac() || is_windows() || (is_solaris() && !is_sparc())
if (needsExplicitFlags) {
Expand Down
6 changes: 1 addition & 5 deletions R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,8 @@ loadTbbLibrary <- function(name) {

.onLoad <- function(libname, pkgname) {

tbbLibraryName <- "tbb"
if (is_windows() && R.version$arch == "aarch64")
tbbLibraryName <- "tbb12"

# load tbb, tbbmalloc
.tbbDllInfo <<- loadTbbLibrary(tbbLibraryName)
.tbbDllInfo <<- loadTbbLibrary("tbb")
.tbbMallocDllInfo <<- loadTbbLibrary("tbbmalloc")

# load tbbmalloc_proxy, but only if requested
Expand Down
3 changes: 3 additions & 0 deletions inst/include/RcppParallel.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#endif

#if RCPP_PARALLEL_USE_TBB
#if defined(WINNT) && defined(__aarch64__) && !defined(TBB_USE_GCC_BUILTINS)
#define TBB_USE_GCC_BUILTINS 1
#endif
# include "RcppParallel/TBB.h"
#endif

Expand Down
47 changes: 47 additions & 0 deletions patches/windows_arm64.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
diff --git a/src/tbb/build/Makefile.tbb b/src/tbb/build/Makefile.tbb
index 8d155f80..c58f4fb1 100644
--- a/src/tbb/build/Makefile.tbb
+++ b/src/tbb/build/Makefile.tbb
@@ -91,7 +91,11 @@ ifneq (,$(TBB.DEF))
tbb.def: $(TBB.DEF) $(TBB.LST)
$(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@

-LIB_LINK_FLAGS += $(EXPORT_KEY)tbb.def
+# LLVM on Windows doesn't need --version-script export
+# https://reviews.llvm.org/D63743
+ifeq (, $(WINARM64_CLANG))
+ LIB_LINK_FLAGS += $(EXPORT_KEY)tbb.def
+endif
$(TBB.DLL): tbb.def
endif

diff --git a/src/tbb/build/Makefile.tbbmalloc b/src/tbb/build/Makefile.tbbmalloc
index 421e95c5..e7c38fa4 100644
--- a/src/tbb/build/Makefile.tbbmalloc
+++ b/src/tbb/build/Makefile.tbbmalloc
@@ -74,7 +74,11 @@ ifneq (,$(MALLOC.DEF))
tbbmalloc.def: $(MALLOC.DEF)
$(CPLUS) $(PREPROC_ONLY) $< $(M_CPLUS_FLAGS) $(WARNING_SUPPRESS) $(INCLUDES) > $@

-MALLOC_LINK_FLAGS += $(EXPORT_KEY)tbbmalloc.def
+# LLVM on Windows doesn't need --version-script export
+# https://reviews.llvm.org/D63743
+ifeq (, $(WINARM64_CLANG))
+ MALLOC_LINK_FLAGS += $(EXPORT_KEY)tbbmalloc.def
+endif
$(MALLOC.DLL): tbbmalloc.def
endif

diff --git a/src/tbb/src/tbbmalloc/TypeDefinitions.h b/src/tbb/src/tbbmalloc/TypeDefinitions.h
index 3178442e..fd4b7956 100644
--- a/src/tbb/src/tbbmalloc/TypeDefinitions.h
+++ b/src/tbb/src/tbbmalloc/TypeDefinitions.h
@@ -25,7 +25,7 @@
# define __ARCH_ipf 1
# elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support
# define __ARCH_x86_32 1
-# elif defined(_M_ARM)
+# elif defined(_M_ARM) || defined(__aarch64__)
# define __ARCH_other 1
# else
# error Unknown processor architecture for Windows
39 changes: 23 additions & 16 deletions src/Makevars.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,28 @@ ifeq ($(OS), Windows_NT)
USE_TBB=Windows
TBB_COPY_PATTERN=tbb*.dll

ARCH=$(shell "${R_HOME}/bin/R" --vanilla -s -e 'cat(R.version$$arch)')
TBB_CXXFLAGS = @CXX11FLAGS@ -DTBB_NO_LEGACY=1
ifeq "$(ARCH)" "aarch64"
PKG_CPPFLAGS += -DTBB_USE_GCC_BUILTINS
TBB_CXXFLAGS += -DTBB_USE_GCC_BUILTINS
CLANG_CHECK := $(shell echo | $(CC) -E -dM - | findstr __clang__)
ifneq ($(CLANG_CHECK), )
WINARM64_CLANG=true
endif
endif

MAKE = make
MAKEFLAGS = -e -j1
MAKE_CMD = \
MSYS2_ARG_CONV_EXCL="*" \
CYGWIN=nodosfilewarning \
CONLY="@WINDOWS_CC@" \
CPLUS="@WINDOWS_CXX11@" \
CXXFLAGS="@CXX11FLAGS@ -DTBB_NO_LEGACY=1" \
CXXFLAGS="$(TBB_CXXFLAGS)" \
PIC_KEY="@CXX11PICFLAGS@" \
WARNING_SUPPRESS="" \
WINARM64_CLANG="$(WINARM64_CLANG)" \
$(MAKE)

else
Expand Down Expand Up @@ -77,26 +89,21 @@ ifeq ($(USE_TBB), Windows)
# rtools: turn on hacks to compensate for make and shell differences rtools<=>MinGW
# compiler: overwrite default (which is cl = MS compiler)
MAKE_ARGS += rtools=true compiler=gcc
ifeq ($(WIN), 64)
MAKE_ARGS += arch=intel64 runtime=mingw
ARCH_DIR=x64/
else
MAKE_ARGS += arch=ia32 runtime=mingw
ARCH_DIR=i386/
# TBB configure will detect mingw runtime with unknown arch on WINARM64_CLANG but not an
# issue as we are using compiler built-ins instead of arch-specific code
ifneq ($(WINARM64_CLANG), true)
ifeq ($(WIN), 64)
MAKE_ARGS += arch=intel64 runtime=mingw
ARCH_DIR=x64/
else
MAKE_ARGS += arch=ia32 runtime=mingw
ARCH_DIR=i386/
endif
endif

# Linker needs access to the tbb dll; otherwise you get errors such as:
# "undefined reference to `tbb::task_scheduler_init::terminate()'"
PKG_LIBS += -Ltbb/build/lib_release -ltbb -ltbbmalloc

# override for aarch64 (experimental) to use Rtools TBB
ARCH=$(shell "${R_HOME}/bin/R" --vanilla -s -e 'cat(R.version$$arch)')
ifeq "$(ARCH)" "aarch64"
TBB_LIB = ${R_TOOLS_SOFT}
TBB_INC = ${R_TOOLS_SOFT}
PKG_LIBS = -ltbb12 -ltbbmalloc
endif

endif

# write compiler if set
Expand Down
6 changes: 5 additions & 1 deletion src/tbb/build/Makefile.tbb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ ifneq (,$(TBB.DEF))
tbb.def: $(TBB.DEF) $(TBB.LST)
$(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@

LIB_LINK_FLAGS += $(EXPORT_KEY)tbb.def
# LLVM on Windows doesn't need --version-script export
# https://reviews.llvm.org/D63743
ifeq (, $(WINARM64_CLANG))
LIB_LINK_FLAGS += $(EXPORT_KEY)tbb.def
endif
$(TBB.DLL): tbb.def
endif

Expand Down
6 changes: 5 additions & 1 deletion src/tbb/build/Makefile.tbbmalloc
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ ifneq (,$(MALLOC.DEF))
tbbmalloc.def: $(MALLOC.DEF)
$(CPLUS) $(PREPROC_ONLY) $< $(M_CPLUS_FLAGS) $(WARNING_SUPPRESS) $(INCLUDES) > $@

MALLOC_LINK_FLAGS += $(EXPORT_KEY)tbbmalloc.def
# LLVM on Windows doesn't need --version-script export
# https://reviews.llvm.org/D63743
ifeq (, $(WINARM64_CLANG))
MALLOC_LINK_FLAGS += $(EXPORT_KEY)tbbmalloc.def
endif
$(MALLOC.DLL): tbbmalloc.def
endif

Expand Down
2 changes: 1 addition & 1 deletion src/tbb/src/tbbmalloc/TypeDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# define __ARCH_ipf 1
# elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support
# define __ARCH_x86_32 1
# elif defined(_M_ARM)
# elif defined(_M_ARM) || defined(__aarch64__)
# define __ARCH_other 1
# else
# error Unknown processor architecture for Windows
Expand Down

0 comments on commit 8ace319

Please sign in to comment.