From c276b03348c920ba7eefb168cb2b9d45d178bce9 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Sat, 18 Jan 2025 12:29:41 -0800 Subject: [PATCH] provide some backwards compatibility with existing binaries (#233) * first steps at backwards compat * more exports for linux * include stub library on Windows * tweaks * dll export * clean up when we're done * overwrite --- R/tbb.R | 8 + R/zzz.R | 9 +- RcppParallel.Rproj | 1 + src/install.libs.R | 26 +++- src/tbb-compat/tbb-compat.cpp | 143 ++++++++++++++++++ src/tbb/include/oneapi/tbb/detail/_task.h | 4 +- .../oneapi/tbb/task_scheduler_observer.h | 122 ++++++++++++++- src/tbb/src/tbb/CMakeLists.txt | 2 - src/tbb/src/tbb/def/lin32-tbb.def | 20 +++ src/tbb/src/tbb/def/lin64-tbb.def | 20 +++ src/tbb/src/tbb/def/mac64-tbb.def | 20 +++ src/tbb/src/tbb/observer_proxy.cpp | 11 ++ src/tbb/src/tbbbind/CMakeLists.txt | 2 - src/tbb/src/tbbmalloc/CMakeLists.txt | 2 - src/tbb/src/tbbmalloc_proxy/CMakeLists.txt | 4 - tools/config/cleanup.R | 4 +- tools/config/configure.R | 5 +- 17 files changed, 378 insertions(+), 25 deletions(-) create mode 100644 src/tbb-compat/tbb-compat.cpp diff --git a/R/tbb.R b/R/tbb.R index 7b28ea1b..9f4fc8db 100644 --- a/R/tbb.R +++ b/R/tbb.R @@ -37,9 +37,17 @@ tbbLibraryPath <- function(name = NULL) { # find the request library (if any) libNames <- tbbLibNames[[sysname]] for (libName in libNames) { + tbbName <- file.path(tbbRoot, libName) if (file.exists(tbbName)) return(tbbName) + + arch <- if (nzchar(.Platform$r_arch)) .Platform$r_arch + suffix <- paste(c("lib", arch, libName), collapse = "/") + tbbName <- system.file(suffix, package = "RcppParallel") + if (file.exists(tbbName)) + return(tbbName) + } } diff --git a/R/zzz.R b/R/zzz.R index 31c40a3e..c30a2983 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -27,6 +27,11 @@ loadTbbLibrary <- function(name) { .onLoad <- function(libname, pkgname) { + # on Windows, load RcppParallel first + if (.Platform$OS.type == "windows") { + .dllInfo <<- library.dynam("RcppParallel", pkgname, libname) + } + # load tbb, tbbmalloc .tbbDllInfo <<- loadTbbLibrary("tbb") .tbbMallocDllInfo <<- loadTbbLibrary("tbbmalloc") @@ -37,7 +42,9 @@ loadTbbLibrary <- function(name) { .tbbMallocProxyDllInfo <<- loadTbbLibrary("tbbmalloc_proxy") # load RcppParallel library if available - .dllInfo <<- library.dynam("RcppParallel", pkgname, libname) + if (.Platform$OS.type != "windows") { + .dllInfo <<- library.dynam("RcppParallel", pkgname, libname) + } } diff --git a/RcppParallel.Rproj b/RcppParallel.Rproj index fc2c81ee..dcbdb2bd 100644 --- a/RcppParallel.Rproj +++ b/RcppParallel.Rproj @@ -14,6 +14,7 @@ RnwWeave: Sweave LaTeX: pdfLaTeX BuildType: Package +PackageCleanBeforeInstall: No PackageInstallArgs: --with-keep.source --clean PackageCheckArgs: --as-cran PackageRoxygenize: rd,collate,namespace diff --git a/src/install.libs.R b/src/install.libs.R index b8f50f46..ceec728c 100644 --- a/src/install.libs.R +++ b/src/install.libs.R @@ -57,7 +57,7 @@ tbbLibs <- tbbLibs[!nzchar(Sys.readlink(tbbLibs))] # copy / link the libraries - useSymlinks <- Sys.getenv("TBB_USE_SYMLINKS", unset = "TRUE") + useSymlinks <- Sys.getenv("TBB_USE_SYMLINKS", unset = .Platform$OS.type != "windows") if (useSymlinks) { file.symlink(tbbLibs, tbbDest) } else { @@ -68,6 +68,19 @@ } + # on Windows, we create a stub library that links to us so that + # older binaries (like rstan) can still load + if (.Platform$OS.type == "windows") { + tbbDll <- file.path(tbbDest, "tbb.dll") + if (!file.exists(tbbDll)) { + writeLines("** creating tbb stub library") + status <- system("R CMD SHLIB tbb-compat/tbb-compat.cpp") + if (status != 0) + stop("error building tbb stub library") + file.rename("tbb-compat/tbb-compat.dll", file.path(tbbDest, "tbb.dll")) + } + } + } useTbbPreamble <- function(tbbInc) { @@ -99,7 +112,7 @@ useBundledTbb <- function() { "-DTBB_EXAMPLES=0", "-DTBB_STRICT=0", ".." - ) + ) writeLines("*** configuring tbb") owd <- setwd("tbb/build-tbb") @@ -133,17 +146,14 @@ useBundledTbb <- function() { ) tbbFiles <- list.files( - "tbb/build-tbb", + file.path(getwd(), "tbb/build-tbb"), pattern = shlibPattern, recursive = TRUE, full.names = TRUE ) - tbbDir <- dirname(tbbFiles[[1L]]) - - dir.create("tbb/build", showWarnings = FALSE) - unlink("tbb/build/lib_release", recursive = TRUE) - file.rename(tbbDir, "tbb/build/lib_release") + dir.create("tbb/build/lib_release", recursive = TRUE, showWarnings = FALSE) + file.copy(tbbFiles, "tbb/build/lib_release", overwrite = TRUE) unlink("tbb/build-tbb", recursive = TRUE) writeLines("*** finished building tbb") diff --git a/src/tbb-compat/tbb-compat.cpp b/src/tbb-compat/tbb-compat.cpp new file mode 100644 index 00000000..621143d2 --- /dev/null +++ b/src/tbb-compat/tbb-compat.cpp @@ -0,0 +1,143 @@ + +#include + +#include "../tbb/include/oneapi/tbb/detail/_namespace_injection.h" +#include "../tbb/include/oneapi/tbb/task_arena.h" + +#include "../tbb/src/tbb/observer_proxy.h" +#include "../tbb/src/tbb/main.h" +#include "../tbb/src/tbb/thread_data.h" + +#ifdef _WIN32 +# define DLL_EXPORT __declspec(dllexport) +#else +# define DLL_EXPORT +#endif + +namespace tbb { + +namespace interface6 { +class task_scheduler_observer; +} + +namespace internal { + +class task_scheduler_observer_v3 { + friend class tbb::detail::r1::observer_proxy; + friend class tbb::detail::r1::observer_list; + friend class interface6::task_scheduler_observer; + + //! Pointer to the proxy holding this observer. + /** Observers are proxied by the scheduler to maintain persistent lists of them. **/ + tbb::detail::r1::observer_proxy* my_proxy; + + //! Counter preventing the observer from being destroyed while in use by the scheduler. + /** Valid only when observation is on. **/ + std::atomic my_busy_count; + +public: + //! Enable or disable observation + /** For local observers the method can be used only when the current thread + has the task scheduler initialized or is attached to an arena. + Repeated calls with the same state are no-ops. **/ + void __TBB_EXPORTED_METHOD observe( bool state=true ); + + //! Returns true if observation is enabled, false otherwise. + bool is_observing() const {return my_proxy!=NULL;} + + //! Construct observer with observation disabled. + task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store(0); } + + //! Entry notification + /** Invoked from inside observe(true) call and whenever a worker enters the arena + this observer is associated with. If a thread is already in the arena when + the observer is activated, the entry notification is called before it + executes the first stolen task. + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_entry( bool /*is_worker*/ ) {} + + //! Exit notification + /** Invoked from inside observe(false) call and whenever a worker leaves the + arena this observer is associated with. + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_exit( bool /*is_worker*/ ) {} + + //! Destructor automatically switches observation off if it is enabled. + virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);} +}; + +} // namespace internal + +namespace interface6 { + +class task_scheduler_observer : public internal::task_scheduler_observer_v3 { + friend class internal::task_scheduler_observer_v3; + friend class tbb::detail::r1::observer_proxy; + friend class tbb::detail::r1::observer_list; + + /** Negative numbers with the largest absolute value to minimize probability + of coincidence in case of a bug in busy count usage. **/ + // TODO: take more high bits for version number + static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1); + + //! contains task_arena pointer or tag indicating local or global semantics of the observer + intptr_t my_context_tag; + enum { global_tag = 0, implicit_tag = 1 }; + +public: + //! Construct local or global observer in inactive state (observation disabled). + /** For a local observer entry/exit notifications are invoked whenever a worker + thread joins/leaves the arena of the observer's owner thread. If a thread is + already in the arena when the observer is activated, the entry notification is + called before it executes the first stolen task. **/ + /** TODO: Obsolete. + Global observer semantics is obsolete as it violates master thread isolation + guarantees and is not composable. Thus the current default behavior of the + constructor is obsolete too and will be changed in one of the future versions + of the library. **/ + explicit task_scheduler_observer( bool local = false ) { + my_context_tag = local? implicit_tag : global_tag; + } + + //! Construct local observer for a given arena in inactive state (observation disabled). + /** entry/exit notifications are invoked whenever a thread joins/leaves arena. + If a thread is already in the arena when the observer is activated, the entry notification + is called before it executes the first stolen task. **/ + explicit task_scheduler_observer( task_arena & a) { + my_context_tag = (intptr_t)&a; + } + + /** Destructor protects instance of the observer from concurrent notification. + It is recommended to disable observation before destructor of a derived class starts, + otherwise it can lead to concurrent notification callback on partly destroyed object **/ + virtual ~task_scheduler_observer() { if(my_proxy) observe(false); } + + //! Enable or disable observation + /** Warning: concurrent invocations of this method are not safe. + Repeated calls with the same state are no-ops. **/ + void observe( bool state=true ) { + if( state && !my_proxy ) { + __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance"); + my_busy_count.store(v6_trait); + } + internal::task_scheduler_observer_v3::observe(state); + } +}; + +} // namespace interface6 + +} // namespace tbb + +namespace tbb { +namespace internal { + +DLL_EXPORT +void __TBB_EXPORTED_FUNC task_scheduler_observer_v3::observe( bool enable ) { + auto* tso = (tbb::detail::d1::task_scheduler_observer*) (this); + tbb::detail::r1::observe(*tso, enable); +} + +} // namespace internal +} // namespace tbb diff --git a/src/tbb/include/oneapi/tbb/detail/_task.h b/src/tbb/include/oneapi/tbb/detail/_task.h index e1bb70c5..103a9868 100644 --- a/src/tbb/include/oneapi/tbb/detail/_task.h +++ b/src/tbb/include/oneapi/tbb/detail/_task.h @@ -124,12 +124,14 @@ class wait_context { } } +public: bool continue_execution() const { std::uint64_t r = m_ref_count.load(std::memory_order_acquire); __TBB_ASSERT_EX((r & overflow_mask) == 0, "Overflow is detected"); return r > 0; } - + +private: friend class r1::thread_data; friend class r1::task_dispatcher; friend class r1::external_waiter; diff --git a/src/tbb/include/oneapi/tbb/task_scheduler_observer.h b/src/tbb/include/oneapi/tbb/task_scheduler_observer.h index a228cfe1..f4f91e96 100644 --- a/src/tbb/include/oneapi/tbb/task_scheduler_observer.h +++ b/src/tbb/include/oneapi/tbb/task_scheduler_observer.h @@ -17,9 +17,12 @@ #ifndef __TBB_task_scheduler_observer_H #define __TBB_task_scheduler_observer_H +#include + #include "detail/_namespace_injection.h" + #include "task_arena.h" -#include + namespace tbb { namespace detail { @@ -113,4 +116,121 @@ inline namespace v1 { } // namespace tbb +// Provided for backwards compatibility. +namespace tbb { +namespace interface6 { +class task_scheduler_observer; +} +namespace internal { + +class task_scheduler_observer_v3 { + friend class tbb::detail::r1::observer_proxy; + friend class tbb::detail::r1::observer_list; + friend class interface6::task_scheduler_observer; + + //! Pointer to the proxy holding this observer. + /** Observers are proxied by the scheduler to maintain persistent lists of them. **/ + tbb::detail::r1::observer_proxy* my_proxy; + + //! Counter preventing the observer from being destroyed while in use by the scheduler. + /** Valid only when observation is on. **/ + std::atomic my_busy_count; + +public: + //! Enable or disable observation + /** For local observers the method can be used only when the current thread + has the task scheduler initialized or is attached to an arena. + + Repeated calls with the same state are no-ops. **/ + void __TBB_EXPORTED_METHOD observe( bool state=true ); + + //! Returns true if observation is enabled, false otherwise. + bool is_observing() const {return my_proxy!=NULL;} + + //! Construct observer with observation disabled. + task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store(0); } + + //! Entry notification + /** Invoked from inside observe(true) call and whenever a worker enters the arena + this observer is associated with. If a thread is already in the arena when + the observer is activated, the entry notification is called before it + executes the first stolen task. + + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_entry( bool /*is_worker*/ ) {} + + //! Exit notification + /** Invoked from inside observe(false) call and whenever a worker leaves the + arena this observer is associated with. + + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_exit( bool /*is_worker*/ ) {} + + //! Destructor automatically switches observation off if it is enabled. + virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);} +}; + +} // namespace internal + +namespace interface6 { +class task_scheduler_observer : public internal::task_scheduler_observer_v3 { + friend class internal::task_scheduler_observer_v3; + friend class tbb::detail::r1::observer_proxy; + friend class tbb::detail::r1::observer_list; + + /** Negative numbers with the largest absolute value to minimize probability + of coincidence in case of a bug in busy count usage. **/ + // TODO: take more high bits for version number + static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1); + + //! contains task_arena pointer or tag indicating local or global semantics of the observer + intptr_t my_context_tag; + enum { global_tag = 0, implicit_tag = 1 }; + +public: + //! Construct local or global observer in inactive state (observation disabled). + /** For a local observer entry/exit notifications are invoked whenever a worker + thread joins/leaves the arena of the observer's owner thread. If a thread is + already in the arena when the observer is activated, the entry notification is + called before it executes the first stolen task. **/ + /** TODO: Obsolete. + Global observer semantics is obsolete as it violates master thread isolation + guarantees and is not composable. Thus the current default behavior of the + constructor is obsolete too and will be changed in one of the future versions + of the library. **/ + explicit task_scheduler_observer( bool local = false ) { + my_context_tag = local? implicit_tag : global_tag; + } + + //! Construct local observer for a given arena in inactive state (observation disabled). + /** entry/exit notifications are invoked whenever a thread joins/leaves arena. + If a thread is already in the arena when the observer is activated, the entry notification + is called before it executes the first stolen task. **/ + explicit task_scheduler_observer( task_arena & a) { + my_context_tag = (intptr_t)&a; + } + + /** Destructor protects instance of the observer from concurrent notification. + It is recommended to disable observation before destructor of a derived class starts, + otherwise it can lead to concurrent notification callback on partly destroyed object **/ + virtual ~task_scheduler_observer() { if(my_proxy) observe(false); } + + //! Enable or disable observation + /** Warning: concurrent invocations of this method are not safe. + Repeated calls with the same state are no-ops. **/ + void observe( bool state=true ) { + if( state && !my_proxy ) { + __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance"); + my_busy_count.store(v6_trait); + } + internal::task_scheduler_observer_v3::observe(state); + } +}; + +} //namespace interface6 + +} // namespace tbb + #endif /* __TBB_task_scheduler_observer_H */ diff --git a/src/tbb/src/tbb/CMakeLists.txt b/src/tbb/src/tbb/CMakeLists.txt index 8c84a0b2..63fd4c73 100644 --- a/src/tbb/src/tbb/CMakeLists.txt +++ b/src/tbb/src/tbb/CMakeLists.txt @@ -90,8 +90,6 @@ target_compile_options(tbb # Avoid use of target_link_libraries here as it changes /DEF option to \DEF on Windows. set_target_properties(tbb PROPERTIES DEFINE_SYMBOL "" - VERSION ${TBB_BINARY_VERSION}.${TBB_BINARY_MINOR_VERSION} - SOVERSION ${TBB_BINARY_VERSION} ) tbb_handle_ipo(tbb) diff --git a/src/tbb/src/tbb/def/lin32-tbb.def b/src/tbb/src/tbb/def/lin32-tbb.def index 737e8ec2..2aef269a 100644 --- a/src/tbb/src/tbb/def/lin32-tbb.def +++ b/src/tbb/src/tbb/def/lin32-tbb.def @@ -17,6 +17,26 @@ { global: +/* Needed for backwards compatibility */ +_ZNSt13runtime_errorD1Ev; +_ZTISt13runtime_error; +_ZTSSt13runtime_error; +_ZNSt16invalid_argumentD1Ev; +_ZTISt16invalid_argument; +_ZTSSt16invalid_argument; +_ZNSt11range_errorD1Ev; +_ZTISt11range_error; +_ZTSSt11range_error; +_ZNSt12length_errorD1Ev; +_ZTISt12length_error; +_ZTSSt12length_error; +_ZNSt12out_of_rangeD1Ev; +_ZTISt12out_of_range; +_ZTSSt12out_of_range; + +/* Needed by rstan */ +_ZN3tbb8internal26task_scheduler_observer_v37observeEb; + /* Assertions (assert.cpp) */ _ZN3tbb6detail2r117assertion_failureEPKciS3_S3_; diff --git a/src/tbb/src/tbb/def/lin64-tbb.def b/src/tbb/src/tbb/def/lin64-tbb.def index 41aca2e9..365ef6c3 100644 --- a/src/tbb/src/tbb/def/lin64-tbb.def +++ b/src/tbb/src/tbb/def/lin64-tbb.def @@ -17,6 +17,26 @@ { global: +/* Needed for backwards compatibility */ +_ZNSt13runtime_errorD1Ev; +_ZTISt13runtime_error; +_ZTSSt13runtime_error; +_ZNSt16invalid_argumentD1Ev; +_ZTISt16invalid_argument; +_ZTSSt16invalid_argument; +_ZNSt11range_errorD1Ev; +_ZTISt11range_error; +_ZTSSt11range_error; +_ZNSt12length_errorD1Ev; +_ZTISt12length_error; +_ZTSSt12length_error; +_ZNSt12out_of_rangeD1Ev; +_ZTISt12out_of_range; +_ZTSSt12out_of_range; + +/* Needed by rstan */ +_ZN3tbb8internal26task_scheduler_observer_v37observeEb; + /* Assertions (assert.cpp) */ _ZN3tbb6detail2r117assertion_failureEPKciS3_S3_; diff --git a/src/tbb/src/tbb/def/mac64-tbb.def b/src/tbb/src/tbb/def/mac64-tbb.def index 38bc48d3..c98e886f 100644 --- a/src/tbb/src/tbb/def/mac64-tbb.def +++ b/src/tbb/src/tbb/def/mac64-tbb.def @@ -19,6 +19,26 @@ # be listed WITHOUT one leading underscore. __TBB_SYMBOL macro should add underscore when # necessary, depending on the intended usage. +# Needed for backwards compatibility +__ZNSt13runtime_errorD1Ev +__ZTISt13runtime_error +__ZTSSt13runtime_error +__ZNSt16invalid_argumentD1Ev +__ZTISt16invalid_argument +__ZTSSt16invalid_argument +__ZNSt11range_errorD1Ev +__ZTISt11range_error +__ZTSSt11range_error +__ZNSt12length_errorD1Ev +__ZTISt12length_error +__ZTSSt12length_error +__ZNSt12out_of_rangeD1Ev +__ZTISt12out_of_range +__ZTSSt12out_of_range + +# Needed by rstan +__ZN3tbb8internal26task_scheduler_observer_v37observeEb + # Assertions (assert.cpp) __ZN3tbb6detail2r117assertion_failureEPKciS3_S3_ diff --git a/src/tbb/src/tbb/observer_proxy.cpp b/src/tbb/src/tbb/observer_proxy.cpp index 2717d740..012c9e4a 100644 --- a/src/tbb/src/tbb/observer_proxy.cpp +++ b/src/tbb/src/tbb/observer_proxy.cpp @@ -317,3 +317,14 @@ void __TBB_EXPORTED_FUNC observe(d1::task_scheduler_observer &tso, bool enable) } // namespace r1 } // namespace detail } // namespace tbb + +namespace tbb { +namespace internal { + +void __TBB_EXPORTED_FUNC task_scheduler_observer_v3::observe( bool enable ) { + auto* tso = (tbb::detail::d1::task_scheduler_observer*) (this); + tbb::detail::r1::observe(*tso, enable); +} + +} // namespace internal +} // namespace tbb \ No newline at end of file diff --git a/src/tbb/src/tbbbind/CMakeLists.txt b/src/tbb/src/tbbbind/CMakeLists.txt index 993dc8b8..b5e9261a 100644 --- a/src/tbb/src/tbbbind/CMakeLists.txt +++ b/src/tbb/src/tbbbind/CMakeLists.txt @@ -53,8 +53,6 @@ function(tbbbind_build TBBBIND_NAME REQUIRED_HWLOC_TARGET) # Avoid use of target_link_libraries here as it changes /DEF option to \DEF on Windows. set_target_properties(${TBBBIND_NAME} PROPERTIES DEFINE_SYMBOL "" - VERSION ${TBBBIND_BINARY_VERSION}.${TBB_BINARY_MINOR_VERSION} - SOVERSION ${TBBBIND_BINARY_VERSION} ) tbb_handle_ipo(${TBBBIND_NAME}) diff --git a/src/tbb/src/tbbmalloc/CMakeLists.txt b/src/tbb/src/tbbmalloc/CMakeLists.txt index 76044fce..26c1891d 100644 --- a/src/tbb/src/tbbmalloc/CMakeLists.txt +++ b/src/tbb/src/tbbmalloc/CMakeLists.txt @@ -70,8 +70,6 @@ enable_language(C) # Avoid use of target_link_libraries here as it changes /DEF option to \DEF on Windows. set_target_properties(tbbmalloc PROPERTIES DEFINE_SYMBOL "" - VERSION ${TBBMALLOC_BINARY_VERSION}.${TBB_BINARY_MINOR_VERSION} - SOVERSION ${TBBMALLOC_BINARY_VERSION} LINKER_LANGUAGE C ) diff --git a/src/tbb/src/tbbmalloc_proxy/CMakeLists.txt b/src/tbb/src/tbbmalloc_proxy/CMakeLists.txt index 554ddc85..609e4f37 100644 --- a/src/tbb/src/tbbmalloc_proxy/CMakeLists.txt +++ b/src/tbb/src/tbbmalloc_proxy/CMakeLists.txt @@ -54,10 +54,6 @@ target_compile_options(tbbmalloc_proxy ${TBB_COMMON_COMPILE_FLAGS} ) -set_target_properties(tbbmalloc_proxy PROPERTIES - VERSION ${TBBMALLOC_BINARY_VERSION}.${TBB_BINARY_MINOR_VERSION} - SOVERSION ${TBBMALLOC_BINARY_VERSION}) - if (UNIX AND NOT APPLE) # Avoid use of target_link_libraries here as it changes /DEF option to \DEF on Windows. set_target_properties(tbbmalloc_proxy PROPERTIES diff --git a/tools/config/cleanup.R b/tools/config/cleanup.R index 29dc8ead..7746f1bc 100644 --- a/tools/config/cleanup.R +++ b/tools/config/cleanup.R @@ -2,8 +2,8 @@ # Clean up files generated during configuration here. # Use 'remove_file()' to remove files generated during configuration. -unlink("src/tbb/build", recursive = TRUE) -unlink("src/tbb/build-tbb", recursive = TRUE) +# unlink("src/tbb/build", recursive = TRUE) +# unlink("src/tbb/build-tbb", recursive = TRUE) unlink("inst/lib", recursive = TRUE) unlink("inst/libs", recursive = TRUE) unlink("inst/include/index.html", recursive = TRUE) diff --git a/tools/config/configure.R b/tools/config/configure.R index 7b509670..ec295df6 100644 --- a/tools/config/configure.R +++ b/tools/config/configure.R @@ -247,6 +247,7 @@ pkgLibs <- if (!is.na(tbbLib)) { } + # on Windows, we may need to link to ssp; otherwise, # we see errors like # @@ -320,7 +321,7 @@ if (.Platform$OS.type == "windows" && is.na(tbbLib)) { # macOS needs some extra flags set if (Sys.info()[["sysname"]] == "Darwin") { - define(PKG_LIBS_EXTRA = "-Wl,-rpath,\"@loader_path/../lib\"") + define(PKG_LIBS_EXTRA = "-Wl,-rpath,@loader_path/../lib") } else { define(PKG_LIBS_EXTRA = "") -} \ No newline at end of file +}