diff --git a/README.md b/README.md index e9f306be..1b82c6bb 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ https://groups.google.com/d/forum/rna-star HARDWARE/SOFTWARE REQUIREMENTS ============================== - * x86-64 compatible processors - * 64 bit Linux or Mac OS X + * x86-64 compatible processors, or ARM64/AArch64 (incl. Apple Silicon) via SIMDe + * 64 bit Linux or Mac OS X (Intel or Apple Silicon) MANUAL ====== @@ -62,17 +62,27 @@ make STAR CXXFLAGS_SIMD=sse Compile under Mac OS X ---------------------- +Native build with Apple clang (recommended, works on both Apple Silicon and Intel): + ```bash # 1. Install brew (http://brew.sh/) -# 2. Install gcc with brew: -$ brew install gcc -# 3. Build STAR: -# run 'make' in the source directory -# note that the path to c++ executable has to be adjusted to its current version -$cd source -$make STARforMacStatic CXX=/usr/local/Cellar/gcc/8.2.0/bin/g++-8 -# 4. Make it availible through the terminal -$cp STAR /usr/local/bin +# 2. Install the OpenMP runtime (Apple clang has no bundled OpenMP): +brew install libomp +# 3. Build STAR (the Makefile auto-detects the libomp prefix and the CPU arch; +# on Apple Silicon it produces an arm64-native binary via SIMDe -> NEON): +cd source +make STARforMac CXX=clang++ +# 4. Make it available through the terminal: +cp STAR /usr/local/bin +``` + +Alternatively, build with Homebrew gcc: + +```bash +brew install gcc +cd source +# adjust the g++ path/version to the one installed by brew +make STARforMacStatic CXX=$(brew --prefix)/bin/g++-14 ``` All platforms - non-standard gcc diff --git a/source/Makefile b/source/Makefile index a6b5fcb3..b7b8cba8 100644 --- a/source/Makefile +++ b/source/Makefile @@ -11,18 +11,48 @@ CXXFLAGSextra ?= # user may define the compiler CXX ?= g++ +# ---- Platform / architecture detection ----------------------------------- +UNAME_S := $(shell uname -s) +UNAME_M := $(shell uname -m) + +# ---- OpenMP flags -------------------------------------------------------- +# GNU/Linux: -fopenmp links libgomp automatically. +# macOS + Apple clang: needs -Xpreprocessor -fopenmp at compile time, plus an +# explicit libomp include path and -lomp at link time (no bundled OpenMP). +ifeq ($(UNAME_S),Darwin) + LIBOMP ?= $(shell brew --prefix libomp 2>/dev/null) + ifeq ($(LIBOMP),) + ifneq ($(wildcard /opt/homebrew/opt/libomp/include/omp.h),) + LIBOMP := /opt/homebrew/opt/libomp + else + LIBOMP := /usr/local/opt/libomp + endif + endif + OPENMP_CXXFLAGS := -Xpreprocessor -fopenmp -I$(LIBOMP)/include + OPENMP_LDFLAGS := -L$(LIBOMP)/lib -lomp +else + OPENMP_CXXFLAGS := -fopenmp + OPENMP_LDFLAGS := +endif + # pre-defined flags LDFLAGS_shared := -pthread -Lhtslib -Bstatic -lhts -Bdynamic -lz LDFLAGS_static := -static -static-libgcc -pthread -Lhtslib -lhts -lz -LDFLAGS_Mac :=-pthread -lz htslib/libhts.a -LDFLAGS_Mac_static :=-pthread -lz -static-libgcc htslib/libhts.a +# macOS: Apple clang has no -static-libgcc, and a fully static binary is not +# supported. "Static" here means htslib is linked as a static archive; the +# OpenMP runtime (libomp) is linked via $(OPENMP_LDFLAGS), defined below. +LDFLAGS_Mac := -pthread -lz htslib/libhts.a $(OPENMP_LDFLAGS) +LDFLAGS_Mac_static := -pthread -lz htslib/libhts.a $(OPENMP_LDFLAGS) +LDFLAGS_Mac_dynamic := -pthread -lz htslib/libhts.a $(OPENMP_LDFLAGS) LDFLAGS_gdb := $(LDFLAGS_shared) DATE_FMT = --iso-8601=seconds ifdef SOURCE_DATE_EPOCH BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)") else - BUILD_DATE ?= $(shell date "$(DATE_FMT)") + # GNU date supports --iso-8601; BSD/macOS date does not, so fall back to + # a portable strftime format. + BUILD_DATE ?= $(shell date "$(DATE_FMT)" 2>/dev/null || date -u "+%Y-%m-%dT%H:%M:%S%z") endif BUILD_PLACE ?= $(HOSTNAME):$(shell pwd) @@ -42,10 +72,19 @@ GIT_BRANCH_COMMIT_DIFF := -D'GIT_BRANCH_COMMIT_DIFF="$(GIT_BRANCH_COMMIT_DIFF)"' # Defaults, can be overridden by make arguments or environment CXXFLAGS ?= -pipe -Wall -Wextra CFLAGS ?= -pipe -Wall -Wextra -O3 -CXXFLAGS_SIMD ?= -mavx2 +# SIMD flags: AVX2 on x86_64, NEON (via SIMDe) elsewhere. +# opal.cpp uses SIMDe with SIMDE_ENABLE_NATIVE_ALIASES; on arm64/aarch64, +# dropping -mavx2 lets SIMDe map AVX2 intrinsics onto NEON automatically. +ifeq ($(UNAME_M),x86_64) + CXXFLAGS_SIMD ?= -mavx2 +else ifeq ($(UNAME_M),amd64) + CXXFLAGS_SIMD ?= -mavx2 +else + CXXFLAGS_SIMD ?= -march=armv8-a+simd +endif # Unconditionally set essential flags and optimization options -CXXFLAGS_common := -std=c++11 -fopenmp $(COMPTIMEPLACE) $(GIT_BRANCH_COMMIT_DIFF) +CXXFLAGS_common := -std=c++11 $(OPENMP_CXXFLAGS) $(COMPTIMEPLACE) $(GIT_BRANCH_COMMIT_DIFF) CXXFLAGS_main := -O3 $(CXXFLAGS_common) CXXFLAGS_gdb := -O0 -g3 $(CXXFLAGS_common) @@ -129,8 +168,6 @@ ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),CLEAN) ifneq ($(MAKECMDGOALS),CLEAN) ifneq ($(MAKECMDGOALS),clean_solo) -ifneq ($(MAKECMDGOALS),STARforMac) -ifneq ($(MAKECMDGOALS),STARforMacGDB) Depend.list: $(SOURCES) parametersDefault.xxd htslib echo $(SOURCES) 'rm' -f ./Depend.list @@ -140,8 +177,6 @@ endif endif endif endif -endif -endif htslib : htslib/libhts.a @@ -197,3 +232,16 @@ STARlongForMacStatic : CXXFLAGS := -D'COMPILE_FOR_LONG_READS' $(CXXFLAGSextra) $ STARlongForMacStatic : LDFLAGS := $(LDFLAGSextra) $(LDFLAGS_Mac_static) $(LDFLAGS) STARlongForMacStatic : Depend.list parametersDefault.xxd $(OBJECTS) $(CXX) -o STARlong $(CXXFLAGS) $(OBJECTS) $(LDFLAGS) + +# Native macOS build (Apple clang). Links htslib statically and libomp +# dynamically. On Apple Silicon this produces an arm64-native binary; on Intel +# Macs an x86_64 binary. Build with: make STARforMac CXX=clang++ +STARforMac : CXXFLAGS := $(CXXFLAGSextra) $(CXXFLAGS_main) -D'COMPILE_FOR_MAC' $(CXXFLAGS) +STARforMac : LDFLAGS := $(LDFLAGSextra) $(LDFLAGS_Mac_dynamic) $(LDFLAGS) +STARforMac : Depend.list parametersDefault.xxd $(OBJECTS) + $(CXX) -o STAR $(CXXFLAGS) $(OBJECTS) $(LDFLAGS) + +STARlongForMac : CXXFLAGS := -D'COMPILE_FOR_LONG_READS' $(CXXFLAGSextra) $(CXXFLAGS_main) -D'COMPILE_FOR_MAC' $(CXXFLAGS) +STARlongForMac : LDFLAGS := $(LDFLAGSextra) $(LDFLAGS_Mac_dynamic) $(LDFLAGS) +STARlongForMac : Depend.list parametersDefault.xxd $(OBJECTS) + $(CXX) -o STARlong $(CXXFLAGS) $(OBJECTS) $(LDFLAGS)