-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathtbb.R
More file actions
159 lines (124 loc) · 4.8 KB
/
Copy pathtbb.R
File metadata and controls
159 lines (124 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#' Get the Path to a TBB Library
#'
#' Retrieve the path to a TBB library. This can be useful for \R packages
#' using RcppParallel that wish to use, or re-use, the version of TBB that
#' RcppParallel has been configured to use.
#'
#' @param name
#' The name of the TBB library to be resolved. Normally, this is one of
#' `tbb`, `tbbmalloc`, or `tbbmalloc_proxy`. When `NULL`, the library
#' path containing the TBB libraries is returned instead.
#'
#' @export
tbbLibraryPath <- function(name = NULL) {
# library paths for different OSes
sysname <- Sys.info()[["sysname"]]
# find root for TBB install
tbbRoot <- Sys.getenv("TBB_LIB", unset = tbbRoot())
if (is.null(name))
return(tbbRoot)
# form library names
tbbLibNames <- list(
"Darwin" = paste0("lib", name, ".dylib"),
"Windows" = paste0(name, ".dll"),
"SunOS" = paste0("lib", name, ".so"),
"Linux" = paste0("lib", name, c(".so.2", ".so"))
)
# skip systems that we know not to be compatible
isCompatible <- !is_sparc() && !is.null(tbbLibNames[[sysname]])
if (!isCompatible)
return(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)
tbbName <- archSystemFile("lib", libName)
if (file.exists(tbbName))
return(tbbName)
}
}
tbbCxxFlags <- function() {
if (!TBB_ENABLED)
return("-DRCPP_PARALLEL_USE_TBB=0")
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)) {
tbbInc <- system.file("include", package = "RcppParallel")
}
# add include path
if (nzchar(tbbInc) && file.exists(tbbInc)) {
# prefer new interface if version.h exists -- we keep this
# for compatibility with packages like StanHeaders, rstan
versionPath <- file.path(tbbInc, "tbb/version.h")
if (file.exists(versionPath))
flags <- c(flags, "-DTBB_INTERFACE_NEW")
# now add the include path
flags <- c(flags, paste0("-I", asBuildPath(tbbInc)))
}
# return flags as string
paste(flags, collapse = " ")
}
# Return the linker flags required for TBB on this platform
tbbLdFlags <- function() {
# on Windows every symbol must be resolved at link time -- there is no
# equivalent of lazy binding or '-undefined dynamic_lookup' -- so a
# downstream package needs both the TBB libraries it calls into and
# RcppParallel itself, for the entry points we compile (e.g.
# isProcessForkedChild). elsewhere those resolve from the process at load
# time and only TBB needs naming
if (is_windows()) {
libsPath <- archSystemFile("libs")
ldFlags <- sprintf("-L%s -lRcppParallel", asBuildPath(libsPath))
# only name the TBB libraries when there are TBB libraries to name;
# asking the linker for one that isn't there would fail the downstream
# build outright. configure always enables TBB, so this should not
# happen -- but a wrong answer here is only discovered by whoever is
# compiling against us, so check rather than assume
if (TBB_ENABLED && !is.null(tbbLibraryPath("tbb"))) {
fmt <- "%s -L%s -l%s -l%s"
ldFlags <- sprintf(
fmt,
ldFlags,
asBuildPath(tbbLibraryPath()),
TBB_NAME,
TBB_MALLOC_NAME
)
}
return(ldFlags)
}
# shortcut if TBB_LIB defined
tbbLib <- Sys.getenv("TBB_LINK_LIB", Sys.getenv("TBB_LIB", unset = TBB_LIB))
if (nzchar(tbbLib)) {
if (R.version$os == "emscripten") {
fmt <- "-L%1$s -l%2$s"
return(sprintf(fmt, asBuildPath(tbbLib), TBB_NAME))
}
fmt <- "-L%1$s -Wl,-rpath,%1$s -l%2$s -l%3$s"
return(sprintf(fmt, asBuildPath(tbbLib), TBB_NAME, TBB_MALLOC_NAME))
}
# explicitly link on macOS
# https://github.com/RcppCore/RcppParallel/issues/206
#
# the bundled libraries record an '@rpath'-relative install name (e.g.
# '@rpath/libtbb.dylib'), so '-L' alone is not enough: the client library
# ends up with no runtime search path for TBB at all, and only loads
# because RcppParallel -- and hence TBB -- normally happens to be loaded
# into the process first. Emit a matching '-rpath' so the client can
# resolve TBB on its own. (#209)
if (is_mac()) {
fmt <- "-L%1$s -Wl,-rpath,%1$s -l%2$s -l%3$s"
return(sprintf(fmt, asBuildPath(tbbLibraryPath()), TBB_NAME, TBB_MALLOC_NAME))
}
# nothing required on other platforms
""
}
tbbRoot <- function() {
if (nzchar(TBB_LIB))
return(TBB_LIB)
archSystemFile("lib")
}