Skip to content

Commit 551c466

Browse files
alternate openmp plugin changes (#1414)
* alternate openmp plugin changes * alternative using R CMD SHLIB --------- Co-authored-by: Dirk Eddelbuettel <edd@debian.org>
1 parent d65b66a commit 551c466

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2025-12-01 Kevin Ushey <kevinushey@gmail.com>
2+
3+
* R/Attributes.R: Update OpenMP plugin for macOS
4+
15
2025-11-29 Dirk Eddelbuettel <edd@debian.org>
26

37
* R/RcppLdpath.R: Revisit deprecation warnings via 'message()' to be

R/Attributes.R

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,74 @@ compileAttributes <- function(pkgdir = ".", verbose = getOption("verbose")) {
586586
list(env = list(PKG_CXXFLAGS ="-std=c++2b"))
587587
}
588588

589+
.openmpPluginDefault <- function() {
590+
list(env = list(PKG_CXXFLAGS = "-fopenmp", PKG_LIBS = "-fopenmp"))
591+
}
592+
593+
.openmpPluginDarwin <- function() {
594+
595+
# generate a test script for compilation
596+
script <- tempfile("openmp-detect-", fileext = ".cpp")
597+
writeLines("", con = script)
598+
on.exit(unlink(script, force = TRUE), add = TRUE)
599+
600+
# get the C++ compiler from R
601+
r <- file.path(R.home("bin"), "R")
602+
output <- tryCatch(
603+
system2(r, c("CMD", "SHLIB", "--dry-run", shQuote(script)), stdout = TRUE),
604+
condition = identity
605+
)
606+
if (inherits(output, "condition"))
607+
return(.openmpPluginDefault())
608+
609+
# extract the compiler invocation from the shlib output
610+
# use some heuristics here...
611+
index <- grep("make would use", output)
612+
compile <- output[[index + 1L]]
613+
614+
# use everything up to the first include flag, which is normally
615+
# the R headers from CPPFLAGS
616+
idx <- regexpr(" -I", compile, fixed = TRUE)
617+
cxx <- substring(compile, 1L, idx - 1L)
618+
619+
# check the compiler version
620+
command <- paste(cxx, "--version")
621+
version <- tryCatch(
622+
system(command, intern = TRUE),
623+
condition = identity
624+
)
625+
if (inherits(version, "condition"))
626+
return(.openmpPluginDefault())
627+
628+
# if we're using Apple clang, use alternate flags
629+
# assume libomp was installed following https://mac.r-project.org/openmp/
630+
if (any(grepl("Apple clang", version))) {
631+
cxxflags <- "-Xclang -fopenmp"
632+
libs <- "-lomp"
633+
}
634+
635+
# if we're using Homebrew clang, add in libomp include paths
636+
else if (any(grepl("Homebrew clang", version))) {
637+
machine <- Sys.info()[["machine"]]
638+
prefix <- if (machine == "arm64") "/opt/homebrew" else "/usr/local"
639+
cxxflags <- sprintf("-I%s/opt/libomp/include -fopenmp", prefix)
640+
libs <- sprintf("-L%s/opt/libomp/lib -fopenmp", prefix)
641+
642+
# otherwise, use default -fopenmp flags for other compilers (LLVM clang; gcc)
643+
} else {
644+
cxxflags <- "-fopenmp"
645+
libs <- "-fopenmp"
646+
}
647+
648+
list(env = list(PKG_CXXFLAGS = cxxflags, PKG_LIBS = libs))
649+
650+
}
651+
589652
## built-in OpenMP plugin
590-
.plugins[["openmp"]] <- function() {
591-
list(env = list(PKG_CXXFLAGS="-fopenmp",
592-
PKG_LIBS="-fopenmp"))
653+
.plugins[["openmp"]] <- if (Sys.info()[["sysname"]] == "Darwin") {
654+
.openmpPluginDarwin
655+
} else {
656+
.openmpPluginDefault
593657
}
594658

595659
.plugins[["unwindProtect"]] <- function() { # nocov start

0 commit comments

Comments
 (0)