Skip to content

Commit b26d7cd

Browse files
authored
build tbb stub from static library on older toolchains (#258)
Rtools42-era toolchains provide an older (non-oneTBB) copy of TBB, so tbb-compat.cpp -- which wraps the oneTBB runtime -- cannot build there, and the install would fail at the stub link. But the old static library already provides the old ABI, so re-export it wholesale instead. Also: - remove stale tbb-compat build artifacts before building the stub; 'make' would otherwise consider a tbb.dll built by a different toolchain (or against a different TBB) up-to-date and re-ship it - clean tbb-compat artifacts in cleanup.R - return invisibly from useTbbPreamble(), so 'NULL' is no longer printed when install.libs.R is run via R -f - standardize on lowercase 'tbb' in logging messages
1 parent 83dede3 commit b26d7cd

4 files changed

Lines changed: 72 additions & 14 deletions

File tree

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# RcppParallel (development version)
22

3+
* Fixed installation on Windows toolchains providing an older (non-oneTBB)
4+
copy of TBB, e.g. Rtools42: the tbb stub library is now built by
5+
re-exporting the static TBB library, rather than wrapping the oneTBB
6+
runtime (which is unavailable there). In addition, stale stub build
7+
artifacts from a different toolchain are no longer reused.
8+
39
* Fixed installation on Windows systems whose Rtools does not provide TBB
410
(R < 4.2.0): configure no longer requires cmake there, and the tbb stub
511
library is no longer built when the TBB backend is disabled.

R/zzz.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,27 @@ loadTbbLibrary <- function(name) {
2525
# which on Windows points at Rtools and holds only static libraries
2626
path <- archSystemFile("lib", paste0(name, ".dll"))
2727
if (!file.exists(path)) {
28-
verboseMessage("TBB library '%s' not found in package 'lib' folder; skipping", name)
28+
verboseMessage("tbb library '%s' not found in package 'lib' folder; skipping", name)
2929
return(NULL)
3030
}
3131

32-
verboseMessage("loading TBB library '%s'", path)
32+
verboseMessage("loading tbb library '%s'", path)
3333
return(dyn.load(path, local = FALSE, now = TRUE))
3434

3535
}
3636

3737
path <- tbbLibraryPath(name)
3838
if (is.null(path)) {
39-
verboseMessage("TBB library '%s' could not be resolved; skipping", name)
39+
verboseMessage("tbb library '%s' could not be resolved; skipping", name)
4040
return(NULL)
4141
}
4242

4343
if (!file.exists(path)) {
44-
warning("TBB library ", shQuote(name), " not found.")
44+
warning("tbb library ", shQuote(name), " not found.")
4545
return(NULL)
4646
}
4747

48-
verboseMessage("loading TBB library '%s'", path)
48+
verboseMessage("loading tbb library '%s'", path)
4949
dyn.load(path, local = FALSE, now = TRUE)
5050

5151
}

src/install.libs.R

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,32 +85,82 @@
8585
if (file.exists(tbbDll)) {
8686
writeLines("** tbb.dll already exists; skipping tbb stub library")
8787
} else {
88-
writeLines("** creating tbb stub library")
89-
status <- system("R CMD SHLIB -o tbb-compat/tbb.dll tbb-compat/tbb-compat.cpp")
90-
if (status != 0)
91-
stop("error building tbb stub library")
92-
file.copy("tbb-compat/tbb.dll", file.path(tbbDest, "tbb.dll"))
88+
buildTbbStub(tbbDest)
9389
}
9490
}
9591

9692
}
9793

94+
# Build the tbb.dll stub that downstream packages link ('-ltbb' via e.g.
95+
# StanHeaders) and that older binaries resolve their imports against.
96+
buildTbbStub <- function(tbbDest) {
97+
98+
# remove artifacts from prior builds, which may have been produced
99+
# by a different toolchain or against a different TBB; 'make' would
100+
# otherwise consider them up-to-date and re-ship them as-is
101+
unlink(c("tbb-compat/tbb.dll", Sys.glob("tbb-compat/*.o")))
102+
103+
tbbInc <- Sys.getenv("TBB_INC")
104+
if (!nzchar(tbbInc))
105+
tbbInc <- TBB_INC
106+
107+
if (file.exists(file.path(tbbInc, "oneapi"))) {
108+
109+
# with oneTBB, the stub provides the old TBB ABI's
110+
# task_scheduler_observer entry point on top of the new runtime
111+
writeLines("** creating tbb stub library")
112+
status <- system("R CMD SHLIB -o tbb-compat/tbb.dll tbb-compat/tbb-compat.cpp")
113+
if (status != 0)
114+
stop("error building tbb stub library")
115+
116+
} else {
117+
118+
# with older versions of TBB (e.g. Rtools42), tbb-compat.cpp cannot
119+
# build -- there is no oneTBB runtime to wrap -- but the static
120+
# library already provides the old ABI, so re-export it wholesale
121+
writeLines("** creating tbb stub library (from static tbb)")
122+
123+
tbbLib <- Sys.getenv("TBB_LIB")
124+
if (!nzchar(tbbLib))
125+
tbbLib <- TBB_LIB
126+
127+
cxx <- system("R CMD config CXX", intern = TRUE)
128+
archive <- file.path(tbbLib, sprintf("lib%s.a", TBB_NAME))
129+
command <- paste(
130+
cxx,
131+
"-shared -static-libgcc",
132+
"-o tbb-compat/tbb.dll",
133+
"-Wl,--whole-archive", shQuote(archive), "-Wl,--no-whole-archive",
134+
"-lssp"
135+
)
136+
137+
writeLines(command)
138+
status <- system(command)
139+
if (status != 0)
140+
stop("error building tbb stub library")
141+
142+
}
143+
144+
file.copy("tbb-compat/tbb.dll", file.path(tbbDest, "tbb.dll"))
145+
146+
}
147+
98148
# Report which TBB libraries are about to be installed, and from where.
99149
# Stale or unexpected libraries copied here have historically been a
100150
# subtle source of load failures in downstream packages, so make the
101151
# provenance easy to spot in installation logs.
102152
logTbbLibraries <- function(tbbLibs, source) {
103153
if (length(tbbLibs)) {
104-
fmt <- "** copying TBB libraries from '%s' [%s]"
154+
fmt <- "** copying tbb libraries from '%s' [%s]"
105155
writeLines(sprintf(fmt, source, paste(basename(tbbLibs), collapse = ", ")))
106156
} else {
107-
writeLines(sprintf("** no TBB libraries found in '%s'", source))
157+
writeLines(sprintf("** no tbb libraries found in '%s'", source))
108158
}
109159
}
110160

111161
useTbbPreamble <- function(tbbInc) {
112162

113-
writeLines(sprintf("** copying TBB headers from '%s'", tbbInc))
163+
writeLines(sprintf("** copying tbb headers from '%s'", tbbInc))
114164
dir.create("../inst/include", recursive = TRUE, showWarnings = FALSE)
115165
for (suffix in c("oneapi", "serial", "tbb")) {
116166
tbbPath <- file.path(tbbInc, suffix)
@@ -119,7 +169,7 @@ useTbbPreamble <- function(tbbInc) {
119169
}
120170
}
121171

122-
patchTbbMachineHeader("../inst/include/oneapi/tbb/detail/_machine.h")
172+
invisible(patchTbbMachineHeader("../inst/include/oneapi/tbb/detail/_machine.h"))
123173

124174
}
125175

tools/config/cleanup.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# install, so nothing is lost by removing these
88
unlink("src/tbb/build", recursive = TRUE)
99
unlink("src/tbb/build-tbb", recursive = TRUE)
10+
unlink("src/tbb-compat/tbb.dll")
11+
unlink(Sys.glob("src/tbb-compat/*.o"))
1012
unlink("inst/lib", recursive = TRUE)
1113
unlink("inst/libs", recursive = TRUE)
1214
unlink("inst/include/index.html", recursive = TRUE)

0 commit comments

Comments
 (0)