Skip to content

Commit 91a889c

Browse files
committed
Use cargo's PROFILE env instead of our own PECOS_PROFILE
1 parent 4d76bff commit 91a889c

6 files changed

Lines changed: 139 additions & 102 deletions

File tree

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ opt-level = 3 # Maximum optimization
154154
lto = true # Link-time optimization (same as "fat")
155155
codegen-units = 1 # Single codegen unit for better optimization
156156

157+
# Native profile: release + CPU-specific optimizations
158+
# Use with: cargo build --profile native
159+
# Build scripts detect this via PROFILE=native env var and add -march=native for C++ code
160+
[profile.native]
161+
inherits = "release"
162+
157163
[workspace.lints.clippy]
158164
# For more details see: https://doc.rust-lang.org/clippy/lints.html
159165
suspicious = { level = "warn", priority = -1 }

Makefile

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -74,80 +74,80 @@ else
7474
endif
7575

7676
# Build profile configuration
77-
# Usage: make build PROFILE=dev|release|native (default: dev)
78-
# The PECOS_PROFILE env var is passed to build scripts so they can set appropriate
79-
# compiler flags for both Rust and C++ code.
80-
PROFILE ?= dev
77+
# Usage: make build PROFILE=debug|release|native (default: debug)
78+
# Build scripts detect the profile via Cargo's PROFILE env var.
79+
PROFILE ?= debug
8180

8281
# Profile-specific Cargo/Maturin settings
83-
# C++ flags are handled by build scripts reading PECOS_PROFILE
82+
# - debug: uses default cargo (debug) profile - fast compile, no optimization
83+
# - release: uses --release flag - full optimization
84+
# - native: uses --profile native (custom profile inheriting from release) + CPU-specific opts
85+
#
86+
# For native profile, we also pass -C target-cpu=native to Rust via RUSTFLAGS.
87+
# Build scripts detect PROFILE=native and add -march=native for C++ code.
8488
ifeq ($(PROFILE),native)
8589
MATURIN_RELEASE_FLAG := --release
86-
CARGO_RELEASE_FLAG := --release
90+
CARGO_PROFILE_FLAG := --profile native
8791
RUSTFLAGS_EXTRA := -C target-cpu=native
8892
PROFILE_DESC := native (release + CPU optimizations)
8993
else ifeq ($(PROFILE),release)
9094
MATURIN_RELEASE_FLAG := --release
91-
CARGO_RELEASE_FLAG := --release
95+
CARGO_PROFILE_FLAG := --release
9296
RUSTFLAGS_EXTRA :=
9397
PROFILE_DESC := release (optimized)
9498
else
95-
# dev profile (default)
99+
# debug profile (default)
96100
MATURIN_RELEASE_FLAG :=
97-
CARGO_RELEASE_FLAG :=
101+
CARGO_PROFILE_FLAG :=
98102
RUSTFLAGS_EXTRA :=
99-
PROFILE_DESC := dev (fast compile, unoptimized)
103+
PROFILE_DESC := debug (fast compile, unoptimized)
100104
endif
101105

102106
# Helper to build FFI crates with the correct profile
103-
# PECOS_PROFILE is read by build.rs scripts to set C++ compiler flags
107+
# Build scripts detect profile via Cargo's PROFILE env var
104108
define BUILD_FFI_CRATES
105109
@if command -v julia >/dev/null 2>&1; then \
106110
echo "Julia detected, building Julia FFI library ($(PROFILE))..."; \
107111
cd julia/pecos-julia-ffi && \
108-
PECOS_PROFILE=$(PROFILE) \
109112
RUSTFLAGS="$$RUSTFLAGS $(RUSTFLAGS_EXTRA)" \
110-
cargo build $(CARGO_RELEASE_FLAG); \
113+
cargo build $(CARGO_PROFILE_FLAG); \
111114
echo "Julia FFI library built successfully"; \
112115
else \
113116
echo "Julia not detected, skipping Julia build"; \
114117
fi
115118
@if command -v go >/dev/null 2>&1; then \
116119
echo "Go detected, building Go FFI library ($(PROFILE))..."; \
117120
cd go/pecos-go-ffi && \
118-
PECOS_PROFILE=$(PROFILE) \
119121
RUSTFLAGS="$$RUSTFLAGS $(RUSTFLAGS_EXTRA)" \
120-
cargo build $(CARGO_RELEASE_FLAG); \
122+
cargo build $(CARGO_PROFILE_FLAG); \
121123
echo "Go FFI library built successfully"; \
122124
else \
123125
echo "Go not detected, skipping Go build"; \
124126
fi
125127
endef
126128

127129
.PHONY: build
128-
build: installreqs ## Build PECOS (use PROFILE=dev|release|native, default: dev)
130+
build: installreqs ## Build PECOS (use PROFILE=debug|release|native, default: debug)
129131
@echo "Building with profile: $(PROFILE_DESC)"
130132
@$(SETUP_LLVM); $(UNSET_CONDA) cd python/pecos-rslib/ && \
131-
PECOS_PROFILE=$(PROFILE) \
132133
RUSTFLAGS="$$RUSTFLAGS $(RUSTFLAGS_EXTRA)" \
133134
uv run maturin develop --uv $(MATURIN_RELEASE_FLAG)
134135
@$(UNSET_CONDA) uv pip install -e "./python/quantum-pecos[all]"
135136
$(BUILD_FFI_CRATES)
136137

137138
.PHONY: build-cuda
138-
build-cuda: installreqs ## Build PECOS with CUDA support (use PROFILE=dev|release|native, default: dev)
139+
build-cuda: installreqs ## Build PECOS with CUDA support (use PROFILE=debug|release|native, default: debug)
139140
@echo "Building with CUDA support, profile: $(PROFILE_DESC)"
140141
@$(SETUP_LLVM); $(UNSET_CONDA) cd python/pecos-rslib/ && \
141-
PECOS_PROFILE=$(PROFILE) \
142142
RUSTFLAGS="$$RUSTFLAGS $(RUSTFLAGS_EXTRA)" \
143143
uv run maturin develop --uv $(MATURIN_RELEASE_FLAG)
144144
@$(UNSET_CONDA) uv pip install -e "./python/quantum-pecos[all,cuda]"
145145
$(BUILD_FFI_CRATES)
146146

147147
# Convenience aliases for common build profiles
148-
.PHONY: build-dev
149-
build-dev: ## Alias for: make build PROFILE=dev
150-
@$(MAKE) build PROFILE=dev
148+
.PHONY: build-debug
149+
build-debug: ## Alias for: make build PROFILE=debug
150+
@$(MAKE) build PROFILE=debug
151151

152152
.PHONY: build-release
153153
build-release: ## Alias for: make build PROFILE=release
@@ -157,9 +157,9 @@ build-release: ## Alias for: make build PROFILE=release
157157
build-native: ## Alias for: make build PROFILE=native
158158
@$(MAKE) build PROFILE=native
159159

160-
.PHONY: build-cuda-dev
161-
build-cuda-dev: ## Alias for: make build-cuda PROFILE=dev
162-
@$(MAKE) build-cuda PROFILE=dev
160+
.PHONY: build-cuda-debug
161+
build-cuda-debug: ## Alias for: make build-cuda PROFILE=debug
162+
@$(MAKE) build-cuda PROFILE=debug
163163

164164
.PHONY: build-cuda-release
165165
build-cuda-release: ## Alias for: make build-cuda PROFILE=release
@@ -771,7 +771,7 @@ pip-install-uv: ## Install uv using pip and create a venv. (Recommended to inst
771771
uv sync
772772

773773
.PHONY: dev
774-
dev: clean build-dev test ## Run the typical sequence of commands to check everything is running correctly
774+
dev: clean build-debug test ## Run the typical sequence of commands to check everything is running correctly
775775

776776
.PHONY: devl
777777
devl: dev lint ## Run the commands to make sure everything runs + lint
@@ -792,7 +792,7 @@ help: ## Show the help menu
792792
@grep -E '^[a-z.A-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-22s\033[0m %s\n", $$1, $$2}'
793793
@echo ""
794794
@echo "Note: Julia and Go support is automatically detected."
795-
@echo " - 'make build-dev' will also build Julia/Go FFI if they are installed"
795+
@echo " - 'make build-debug' will also build Julia/Go FFI if they are installed"
796796
@echo " - 'make test' will also run Julia/Go tests if they are installed"
797797
@echo " - 'make lint' checks code quality; 'make lint-fix' fixes issues"
798798
@echo " - Use 'make julia-info' or 'make go-info' for more information"

crates/pecos-cppsparsesim/build.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
use std::env;
22

3-
/// Get the PECOS build profile from environment
4-
/// Returns "dev", "release", or "native"
5-
fn get_pecos_profile() -> String {
6-
env::var("PECOS_PROFILE").unwrap_or_else(|_| {
7-
// Fall back to detecting from OPT_LEVEL if PECOS_PROFILE not set
8-
let opt_level = env::var("OPT_LEVEL").unwrap_or_else(|_| "0".to_string());
9-
if opt_level == "0" {
10-
"dev".to_string()
11-
} else {
12-
"release".to_string()
13-
}
14-
})
3+
/// Get the build profile from Cargo's environment
4+
/// Returns "debug", "release", or "native"
5+
///
6+
/// Cargo sets PROFILE env var during build script execution:
7+
/// - "debug" -> no C++ optimization, fast compile
8+
/// - "release" -> full optimization (-O3)
9+
/// - "native" -> full optimization + CPU-specific (-O3 -march=native)
10+
fn get_build_profile() -> String {
11+
match env::var("PROFILE").as_deref() {
12+
Ok("release") => "release".to_string(),
13+
Ok("native") => "native".to_string(),
14+
_ => "debug".to_string(), // debug or anything else
15+
}
1516
}
1617

17-
/// Apply PECOS profile optimization flags to a `cc::Build`
18+
/// Apply profile optimization flags to a `cc::Build`
1819
fn apply_profile_flags(build: &mut cc::Build, target: &str) {
19-
let profile = get_pecos_profile();
20+
let profile = get_build_profile();
2021

2122
if target.contains("windows") {
2223
// MSVC optimization flags
@@ -53,16 +54,24 @@ fn apply_profile_flags(build: &mut cc::Build, target: &str) {
5354
fn main() {
5455
// Build C++ source files
5556
let mut build = cc::Build::new();
57+
58+
// Use C++14 or newer to avoid issues with older cross-compilers
59+
// that don't fully support C++11 type traits like is_trivially_move_constructible
60+
let target = env::var("TARGET").unwrap_or_default();
61+
62+
// On macOS, explicitly use system clang to ensure SDK paths are correct.
63+
// The PECOS LLVM clang may be in PATH but doesn't have SDK headers configured,
64+
// causing "math.h file not found" errors during compilation.
65+
if target.contains("darwin") && env::var("CXX").is_err() && env::var("CC").is_err() {
66+
build.compiler("/usr/bin/clang++");
67+
}
68+
5669
build
5770
.cpp(true)
5871
.file("src/sparsesim.cpp")
5972
.file("src/cxx_shim.cpp")
6073
.include("src");
6174

62-
// Use C++14 or newer to avoid issues with older cross-compilers
63-
// that don't fully support C++11 type traits like is_trivially_move_constructible
64-
let target = env::var("TARGET").unwrap_or_default();
65-
6675
// For cross-compilation (especially aarch64), we need at least C++14
6776
// to ensure type traits are available
6877
if target.contains("aarch64") || target.contains("arm") {
@@ -90,6 +99,12 @@ fn main() {
9099
let mut bridge = cxx_build::bridge("src/lib.rs");
91100
bridge.file("src/cxx_shim.cpp");
92101

102+
// On macOS, explicitly use system clang to ensure SDK paths are correct.
103+
// The PECOS LLVM clang may be in PATH but doesn't have SDK headers configured.
104+
if target.contains("darwin") && env::var("CXX").is_err() && env::var("CC").is_err() {
105+
bridge.compiler("/usr/bin/clang++");
106+
}
107+
93108
// Match the same C++ standard for cxx bridge
94109
if target.contains("aarch64") || target.contains("arm") {
95110
if bridge.is_flag_supported("-std=c++17").unwrap_or(false) {
@@ -130,5 +145,4 @@ fn main() {
130145
println!("cargo:rerun-if-changed=src/sparsesim.h");
131146
println!("cargo:rerun-if-changed=src/cxx_shim.cpp");
132147
println!("cargo:rerun-if-changed=src/cxx_shim.h");
133-
println!("cargo:rerun-if-env-changed=PECOS_PROFILE");
134148
}

crates/pecos-ldpc-decoders/build_ldpc.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ use std::env;
88
use std::fs;
99
use std::path::{Path, PathBuf};
1010

11-
/// Get the PECOS build profile from environment
12-
/// Returns "dev", "release", or "native"
13-
fn get_pecos_profile() -> String {
14-
env::var("PECOS_PROFILE").unwrap_or_else(|_| {
15-
// Fall back to detecting from debug_assertions if PECOS_PROFILE not set
16-
if cfg!(debug_assertions) {
17-
"dev".to_string()
18-
} else {
19-
"release".to_string()
20-
}
21-
})
11+
/// Get the build profile from Cargo's environment
12+
/// Returns "debug", "release", or "native"
13+
///
14+
/// Cargo sets PROFILE env var during build script execution:
15+
/// - "debug" -> no C++ optimization, fast compile
16+
/// - "release" -> full optimization (-O3)
17+
/// - "native" -> full optimization + CPU-specific (-O3 -march=native)
18+
fn get_build_profile() -> String {
19+
match env::var("PROFILE").as_deref() {
20+
Ok("release") => "release".to_string(),
21+
Ok("native") => "native".to_string(),
22+
_ => "debug".to_string(), // debug or anything else
23+
}
2224
}
2325

2426
/// Main build function for LDPC
@@ -31,7 +33,6 @@ pub fn build() -> Result<()> {
3133

3234
// Also rerun if the user forces a rebuild
3335
println!("cargo:rerun-if-env-changed=FORCE_REBUILD");
34-
println!("cargo:rerun-if-env-changed=PECOS_PROFILE");
3536

3637
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
3738
let ldpc_dir = out_dir.join("ldpc");
@@ -250,6 +251,16 @@ fn build_cxx_bridge(ldpc_dir: &Path) -> Result<()> {
250251

251252
// Build the cxx bridge first to generate headers
252253
let mut build = cxx_build::bridge("src/bridge.rs");
254+
255+
let target = env::var("TARGET").unwrap_or_default();
256+
257+
// On macOS, explicitly use system clang to ensure SDK paths are correct.
258+
// The PECOS LLVM clang may be in PATH but doesn't have SDK headers configured,
259+
// causing "math.h file not found" errors during compilation.
260+
if target.contains("darwin") && env::var("CXX").is_err() && env::var("CC").is_err() {
261+
build.compiler("/usr/bin/clang++");
262+
}
263+
253264
build
254265
.file("src/bridge.cpp")
255266
.include(&src_cpp_dir)
@@ -261,7 +272,6 @@ fn build_cxx_bridge(ldpc_dir: &Path) -> Result<()> {
261272

262273
// Use C++17 when available, fall back to C++14 for older compilers
263274
// This helps with cross-compilation where older toolchains may not fully support C++17
264-
let target = env::var("TARGET").unwrap_or_default();
265275
if target.contains("aarch64") || target.contains("arm") {
266276
// For ARM targets, check what's supported
267277
if build.is_flag_supported("-std=c++17").unwrap_or(false) {
@@ -277,8 +287,8 @@ fn build_cxx_bridge(ldpc_dir: &Path) -> Result<()> {
277287
// Report ccache/sccache configuration
278288
report_cache_config();
279289

280-
// Use PECOS_PROFILE for optimization settings
281-
let profile = get_pecos_profile();
290+
// Use build profile for optimization settings
291+
let profile = get_build_profile();
282292
match profile.as_str() {
283293
"native" => {
284294
// Native profile: release optimizations + CPU-specific optimizations

crates/pecos-quest/build_quest.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,19 @@ fn generate_quest_header(quest_dir: &Path) -> Result<()> {
291291
Ok(())
292292
}
293293

294-
/// Get the PECOS build profile from environment
295-
/// Returns "dev", "release", or "native"
296-
fn get_pecos_profile() -> String {
297-
env::var("PECOS_PROFILE").unwrap_or_else(|_| {
298-
// Fall back to detecting from debug_assertions if PECOS_PROFILE not set
299-
if cfg!(debug_assertions) {
300-
"dev".to_string()
301-
} else {
302-
"release".to_string()
303-
}
304-
})
294+
/// Get the build profile from Cargo's environment
295+
/// Returns "debug", "release", or "native"
296+
///
297+
/// Cargo sets PROFILE env var during build script execution:
298+
/// - "debug" -> no C++ optimization, fast compile
299+
/// - "release" -> full optimization (-O3)
300+
/// - "native" -> full optimization + CPU-specific (-O3 -march=native)
301+
fn get_build_profile() -> String {
302+
match env::var("PROFILE").as_deref() {
303+
Ok("release") => "release".to_string(),
304+
Ok("native") => "native".to_string(),
305+
_ => "debug".to_string(), // debug or anything else
306+
}
305307
}
306308

307309
/// Main build function for `QuEST`
@@ -315,7 +317,6 @@ pub fn build() -> Result<()> {
315317

316318
// Also rerun if the user forces a rebuild
317319
println!("cargo:rerun-if-env-changed=FORCE_REBUILD");
318-
println!("cargo:rerun-if-env-changed=PECOS_PROFILE");
319320

320321
// Check for GPU feature
321322
println!("cargo:rerun-if-env-changed=QUEST_ENABLE_GPU");
@@ -393,6 +394,14 @@ fn build_cxx_bridge(quest_dir: &Path, out_dir: &Path) {
393394
// Build the cxx bridge first to generate headers
394395
let mut build = cxx_build::bridge("src/bridge.rs");
395396

397+
// On macOS, explicitly use system clang to ensure SDK paths are correct.
398+
// The PECOS LLVM clang may be in PATH but doesn't have SDK headers configured,
399+
// causing "math.h file not found" errors during compilation.
400+
let target = env::var("TARGET").unwrap_or_default();
401+
if target.contains("darwin") && env::var("CXX").is_err() && env::var("CC").is_err() {
402+
build.compiler("/usr/bin/clang++");
403+
}
404+
396405
// Determine if we're building with GPU support
397406
// Check if the gpu feature is enabled via CARGO_FEATURE_GPU env var
398407
let gpu_feature_enabled = env::var("CARGO_FEATURE_GPU").is_ok();
@@ -560,8 +569,8 @@ fn build_cxx_bridge(quest_dir: &Path, out_dir: &Path) {
560569
// This properly handles warning flags without conflicts
561570
build.warnings(false);
562571

563-
// Use PECOS_PROFILE for optimization settings
564-
let profile = get_pecos_profile();
572+
// Use build profile for optimization settings
573+
let profile = get_build_profile();
565574
match profile.as_str() {
566575
"native" => {
567576
// Native profile: release optimizations + CPU-specific optimizations

0 commit comments

Comments
 (0)