Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
or related R headers were installed first
* inst/include/RcppCommon.h: Call new header as first thing

2025-11-18 James J Balamuta <[email protected]>

* R/Attributes.R: Updated OpenMP Plugin's flags on macOS

2025-11-04 Dirk Eddelbuettel <[email protected]>

* .github/workflows/macos.yaml (jobs): Roll macos-13 to macos-14
Expand Down
48 changes: 46 additions & 2 deletions R/Attributes.R
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,52 @@ compileAttributes <- function(pkgdir = ".", verbose = getOption("verbose")) {

## built-in OpenMP plugin
.plugins[["openmp"]] <- function() {
list(env = list(PKG_CXXFLAGS="-fopenmp",
PKG_LIBS="-fopenmp"))

# Default flags for non-macOS systems
cxxflags <- "-fopenmp"
libs <- "-fopenmp"

# Check if we're on macOS
if (Sys.info()[["sysname"]] == "Darwin") {
# Get the C++ compiler from R CMD config CXX
r_cmd <- file.path(R.home("bin"), "R")
cxx <- tryCatch({
system2(r_cmd, c("CMD", "config", "CXX"), stdout = TRUE, stderr = FALSE)
}, error = function(e) "")

if (length(cxx) > 0 && nzchar(cxx[1])) {
# Check compiler version using full command (this includes any flags)
compiler_version <- tryCatch({
system(paste(cxx[1], "--version"), intern = TRUE, ignore.stderr = TRUE)
}, error = function(e) character(0))

if (length(compiler_version) > 0) {
# Check for Apple clang
is_apple_clang <- any(grepl("Apple", compiler_version, ignore.case = TRUE))
Copy link
Contributor

@kevinushey kevinushey Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check also succeeds (and is checked in the conditional) for Homebrew's build of clang, since it has

> writeLines(compiler_version)
Homebrew clang version 21.1.6
Target: arm64-apple-darwin25.1.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/21.1.6/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin25.cfg

and so apple is picked up in the grep invocation from the target triple.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
is_apple_clang <- any(grepl("Apple", compiler_version, ignore.case = TRUE))
is_apple_clang <- any(grepl("Apple clang", compiler_version))

# Check for Homebrew clang
is_homebrew_clang <- any(grepl("Homebrew", compiler_version, ignore.case = TRUE))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
is_homebrew_clang <- any(grepl("Homebrew", compiler_version, ignore.case = TRUE))
is_homebrew_clang <- any(grepl("Homebrew clang", compiler_version))


if (is_apple_clang) {
# Apple clang requires -Xclang -fopenmp
cxxflags <- "-Xclang -fopenmp"
libs <- "-lomp"
} else if (is_homebrew_clang) {
# Homebrew clang needs include/lib paths for the added libomp formula
# Determine prefix based on architecture (arm64 vs x86_64)
arch <- Sys.info()[["machine"]]
brew_prefix <- if (arch == "arm64") "/opt/homebrew" else "/usr/local"

cxxflags <- paste("-Xclang -fopenmp",
paste0("-I", brew_prefix, "/opt/libomp/include"))
libs <- paste(paste0("-L", brew_prefix, "/opt/libomp/lib"), "-lomp")
}
# Otherwise it's gcc and regular -fopenmp works (defaults are fine)
}
}
}

list(env = list(PKG_CXXFLAGS = cxxflags,
PKG_LIBS = libs))
}

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