diff --git a/NEWS.md b/NEWS.md index 4bcdac2f..661b4c50 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,7 +7,8 @@ RcppParallel 6.0.0, such packages would fail to load with "LoadLibrary failure: The specified module could not be found". -* The bundled oneTBB headers now guard against GCC's `` being +* The TBB headers installed with RcppParallel (whether from Rtools or from + the bundled copy of oneTBB) now guard against GCC's `` being included before `` on Windows (mingw). Previously, translation units including `` before any TBB header would fail to compile, as the `__cpuid` macro from `` conflicts with the `__cpuid()` diff --git a/src/install.libs.R b/src/install.libs.R index 142914c4..06a7899b 100644 --- a/src/install.libs.R +++ b/src/install.libs.R @@ -88,6 +88,7 @@ } useTbbPreamble <- function(tbbInc) { + dir.create("../inst/include", recursive = TRUE, showWarnings = FALSE) for (suffix in c("oneapi", "serial", "tbb")) { tbbPath <- file.path(tbbInc, suffix) @@ -95,6 +96,45 @@ useTbbPreamble <- function(tbbInc) { file.copy(tbbPath, "../inst/include", recursive = TRUE) } } + + patchTbbMachineHeader("../inst/include/oneapi/tbb/detail/_machine.h") + +} + +# Guard the '#include ' in TBB's _machine.h against GCC's +# macro on mingw. The headers we ship may come from Rtools +# rather than from the bundled copy of oneTBB, so the guard must be +# applied to the copied headers, not just the bundled sources. +patchTbbMachineHeader <- function(path) { + + if (!file.exists(path)) + return() + + contents <- readLines(path) + if (any(grepl("push_macro", contents, fixed = TRUE))) + return() + + index <- which(contents == "#include ") + if (length(index) != 1L) + return() + + replacement <- c( + "// GCC's defines a function-like '__cpuid' macro that mangles the", + "// __cpuid() declarations in mingw's . Hide the macro while", + "// including so the two headers can coexist in any order.", + "#if defined(__MINGW32__) && defined(__cpuid)", + "#pragma push_macro(\"__cpuid\")", + "#undef __cpuid", + "#include ", + "#pragma pop_macro(\"__cpuid\")", + "#else", + "#include ", + "#endif" + ) + + contents <- append(contents[-index], replacement, after = index - 1L) + writeLines(contents, path) + } useSystemTbb <- function(tbbLib, tbbInc) {