From 83bd3972d2e7e936fbee034105df91b453b24a25 Mon Sep 17 00:00:00 2001 From: Leonidas Zhak <70497898+LeonidasZhak@users.noreply.github.com> Date: Sat, 22 Aug 2026 03:44:59 +0800 Subject: [PATCH] Fix old macOS Clang allocation flags --- NEWS.md | 4 ++++ R/tbb-autodetected.R.in | 3 ++- R/tbb-platform.R | 34 ++++++++++++++++++++++++++++++++++ R/tbb.R | 3 +++ src/Makevars.in | 3 ++- tests/test-cxx-flags.R | 18 ++++++++++++++++++ tools/config/configure.R | 11 ++++++++++- 7 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 R/tbb-platform.R create mode 100644 tests/test-cxx-flags.R diff --git a/NEWS.md b/NEWS.md index bc5515ae..05579225 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # RcppParallel (development version) +* Fixed bundled oneTBB builds and downstream compilation on macOS 10.12 and + earlier with Clang and libc++, which require `-fno-aligned-allocation`. + The flag is restricted to that compiler and platform combination. (#219) + # RcppParallel 6.2.0 diff --git a/R/tbb-autodetected.R.in b/R/tbb-autodetected.R.in index 7cc750e0..0be09b76 100644 --- a/R/tbb-autodetected.R.in +++ b/R/tbb-autodetected.R.in @@ -2,6 +2,7 @@ TBB_ENABLED <- @TBB_ENABLED@ TBB_LIB <- "@TBB_LIB@" TBB_INC <- "@TBB_INC@" +TBB_CXXFLAGS <- "@TBB_CXXFLAGS@" TBB_NAME <- "@TBB_NAME@" -TBB_MALLOC_NAME <- "@TBB_MALLOC_NAME@" \ No newline at end of file +TBB_MALLOC_NAME <- "@TBB_MALLOC_NAME@" diff --git a/R/tbb-platform.R b/R/tbb-platform.R new file mode 100644 index 00000000..26eea3bd --- /dev/null +++ b/R/tbb-platform.R @@ -0,0 +1,34 @@ +tbb_cxx_compiler <- function() { + + compiler <- Sys.getenv("CXX", unset = NA_character_) + if (!is.na(compiler) && nzchar(compiler)) + return(compiler) + + R <- file.path(R.home("bin"), "R") + output <- tryCatch( + system2(R, c("CMD", "config", "CXX"), stdout = TRUE, stderr = FALSE), + error = function(cnd) character() + ) + + if (length(output)) output[[1L]] else "" + +} + +tbb_needs_no_aligned_allocation <- function( + sysname = Sys.info()[["sysname"]], + release = Sys.info()[["release"]], + compiler = tbb_cxx_compiler()) +{ + + if (!identical(sysname, "Darwin")) + return(FALSE) + + # Darwin 16 is macOS 10.12; Darwin 17 is macOS 10.13. + darwinMajor <- suppressWarnings(as.integer(strsplit(release, ".", fixed = TRUE)[[1L]][[1L]])) + if (is.na(darwinMajor) || darwinMajor >= 17L) + return(FALSE) + + compiler <- strsplit(compiler, "[[:space:]]+", perl = TRUE)[[1L]][[1L]] + identical(basename(compiler), "clang++") + +} diff --git a/R/tbb.R b/R/tbb.R index 6f6a745c..b071833a 100644 --- a/R/tbb.R +++ b/R/tbb.R @@ -57,6 +57,9 @@ tbbCxxFlags <- function() { flags <- c("-DRCPP_PARALLEL_USE_TBB=1") + if (nzchar(TBB_CXXFLAGS)) + flags <- c(flags, TBB_CXXFLAGS) + # if TBB_INC is set, apply those library paths tbbInc <- Sys.getenv("TBB_INC", unset = TBB_INC) if (!file.exists(tbbInc)) { diff --git a/src/Makevars.in b/src/Makevars.in index 7158b732..06416fce 100644 --- a/src/Makevars.in +++ b/src/Makevars.in @@ -10,6 +10,7 @@ TBB_LIB = @TBB_LIB@ TBB_INC = @TBB_INC@ TBB_NAME = @TBB_NAME@ TBB_MALLOC_NAME = @TBB_MALLOC_NAME@ +TBB_CXXFLAGS = @TBB_CXXFLAGS@ PKG_CPPFLAGS = @PKG_CPPFLAGS@ PKG_CXXFLAGS = @PKG_CXXFLAGS@ @@ -28,7 +29,7 @@ tbb: tbb-clean @TBB_LIB="$(TBB_LIB)" TBB_INC="$(TBB_INC)" \ TBB_NAME="$(TBB_NAME)" TBB_MALLOC_NAME="$(TBB_MALLOC_NAME)" \ CC="$(CC)" CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" \ - CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \ + CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS) $(TBB_CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \ CMAKE="$(CMAKE)" "@R@" -s -f install.libs.R --args build # NOTE: we do not want to clean ../inst/lib or ../inst/libs here, diff --git a/tests/test-cxx-flags.R b/tests/test-cxx-flags.R new file mode 100644 index 00000000..61ca76f2 --- /dev/null +++ b/tests/test-cxx-flags.R @@ -0,0 +1,18 @@ +# Unit tests for the compiler and platform-specific flags returned by +# RcppParallel::CxxFlags(). + +RcppParallel:::test_init() + +# Darwin 16 is macOS 10.12, the last release affected by this libc++ issue. +assert(tbb_needs_no_aligned_allocation("Darwin", "16.7.0", "clang++")) +assert(!tbb_needs_no_aligned_allocation("Darwin", "17.0.0", "clang++")) +assert(!tbb_needs_no_aligned_allocation("Darwin", "16.7.0", "g++")) +assert(!tbb_needs_no_aligned_allocation("Linux", "16.7.0", "clang++")) + +flags <- tbbCxxFlags() +assert(is.character(flags)) +assert(length(flags) == 1L) +assert(!is.na(flags)) + +if (nzchar(TBB_CXXFLAGS)) + assert(grepl("-fno-aligned-allocation", flags, fixed = TRUE)) diff --git a/tools/config/configure.R b/tools/config/configure.R index 6293fe13..290d21fe 100644 --- a/tools/config/configure.R +++ b/tools/config/configure.R @@ -3,6 +3,8 @@ rExe <- if (.Platform$OS.type == "windows") "R.exe" else "R" define(R = file.path(R.home("bin"), rExe)) +source("R/tbb-platform.R") + # check whether user has Makevars file that might cause trouble makevars <- Sys.getenv("R_MAKEVARS_USER", unset = "~/.R/Makevars") if (file.exists(makevars)) { @@ -237,7 +239,14 @@ if (!is.na(tbbLib)) { # TBB is always enabled: either one was supplied via TBB_LIB / TBB_ROOT, or we # built the bundled copy, and failing to do either is fatal above define(TBB_ENABLED = TRUE) -define(PKG_CXXFLAGS = "-DRCPP_PARALLEL_USE_TBB=1") +tbbCxxFlags <- if (tbb_needs_no_aligned_allocation()) { + "-fno-aligned-allocation" +} else { + "" +} +define(TBB_CXXFLAGS = tbbCxxFlags) +pkgCxxFlags <- c("-DRCPP_PARALLEL_USE_TBB=1", tbbCxxFlags) +define(PKG_CXXFLAGS = paste(pkgCxxFlags[nzchar(pkgCxxFlags)], collapse = " ")) # macOS needs some extra flags set if (Sys.info()[["sysname"]] == "Darwin") {