Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
48be4a2
profiles: remove all previous fields; replace with a list of features
perazz Sep 7, 2025
5f6f5d1
test profiles serialization
perazz Sep 7, 2025
1c37b21
remove .features field from the profiles manifest
perazz Sep 7, 2025
f7790cd
add `features` to the CLI settings
perazz Sep 7, 2025
698e9ce
CLI features: make it a string array
perazz Sep 7, 2025
152e4ca
add CLI tests
perazz Sep 7, 2025
b3a97c4
implement default profiles
perazz Sep 7, 2025
bbbec6a
validate profiles; add default "debug" and "release"
perazz Sep 7, 2025
9c4cac1
feature collection: extend export_config
perazz Sep 7, 2025
1f4a489
merge features into package configuration
perazz Sep 7, 2025
07988e1
implement features in the dependency config
perazz Sep 7, 2025
cc73d56
apply features to the dependency config
perazz Sep 7, 2025
546482b
test dependency propagation
perazz Sep 7, 2025
f2bb830
fix profile/feature CLI
perazz Sep 7, 2025
9449c6e
add tests on invalid chains
perazz Sep 8, 2025
258f35c
fix merging of preprocessor collections
perazz Sep 8, 2025
6efba86
test merging of preprocessor collections
perazz Sep 8, 2025
9beb972
ensure metapackage names are always set
perazz Sep 8, 2025
6ff7d70
do not allow multiple definitions
perazz Sep 8, 2025
d748c92
preprocessing fix: must be on if *any* features - even not active - h…
perazz Sep 8, 2025
cf4a704
fix
perazz Sep 8, 2025
f3356a7
Update test_features.f90
perazz Sep 8, 2025
a117115
generalize test for windows
perazz Sep 8, 2025
663fa0f
intel fix
perazz Sep 8, 2025
a4b3614
fix
perazz Sep 8, 2025
81af006
create features test
perazz Sep 8, 2025
2c2159f
add macos fix
perazz Sep 8, 2025
ca94a39
fix features test
perazz Sep 8, 2025
9ec4ebb
fix most tests
perazz Sep 8, 2025
8e37737
update features_with_dependency test
perazz Sep 9, 2025
270f102
Merge branch 'main' into features_application
perazz Sep 11, 2025
1a1676f
intel fix: do not access unallocated `flags`
perazz Sep 11, 2025
1135492
typo
perazz Sep 11, 2025
e83c1c6
deactivate blank case
perazz Sep 11, 2025
dcca0fe
metapackage fix: clean before reading manifest, not after; refactor i…
perazz Sep 11, 2025
1c664a7
gcc-15 fix
perazz Sep 11, 2025
6ae0ba1
intel fix: change program name
perazz Sep 11, 2025
4af88df
Update src/fpm_targets.f90
perazz Sep 15, 2025
2e94e79
fix example
perazz Sep 21, 2025
d5ca48a
generalize compile flags
perazz Sep 21, 2025
f556321
new test: compiler flags
perazz Sep 21, 2025
acb7f34
example package: features_per_compiler
perazz Sep 21, 2025
b1942b5
do not check `=native`: it is unrolled by gfortran
perazz Sep 21, 2025
dd363fb
Merge branch 'main' into features_application
perazz Sep 24, 2025
cb2e5fc
Merge branch 'main' into features_application
perazz Sep 27, 2025
f847311
catch error messages correctly
perazz Sep 27, 2025
cc75c63
adjust feature test
perazz Sep 27, 2025
86653e6
ensure `-fPIC` with llvm_unknown
perazz Sep 27, 2025
c112e6f
use allocatable
perazz Sep 27, 2025
670c67f
more gcc-15 array initializer fixes
perazz Sep 27, 2025
db45d55
better identify debug flags
perazz Sep 27, 2025
ad69e28
gcc-10 fix: explicit character allocation
perazz Sep 27, 2025
b587fdf
ifx crash: fix `fPIC` logic
perazz Sep 28, 2025
fc5f5c4
debug print
perazz Sep 28, 2025
a9d702d
Update platform.f90
perazz Sep 28, 2025
0ae4f8e
more output
perazz Sep 28, 2025
4551e49
Update feature_collection.f90
perazz Sep 28, 2025
150bca5
ifx 2025.2
perazz Sep 28, 2025
c3b16be
avoid `xHost` on Intel compilers
perazz Sep 28, 2025
bf8757c
do not use `-fast` on `ifx`
perazz Sep 28, 2025
4f21bf2
Update main.f90
perazz Sep 28, 2025
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
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ jobs:
- {compiler: gcc, version: 13}
- {compiler: gcc, version: 14}
- {compiler: gcc, version: 15}
- {compiler: intel, version: 2025.1}
- {compiler: intel, version: 2025.2}
exclude:
- os: macos-13 # No Intel on MacOS anymore since 2024
toolchain: {compiler: intel, version: '2025.1'}
toolchain: {compiler: intel, version: '2025.2'}
- os: windows-latest # Doesn't pass build and tests yet
toolchain: {compiler: intel, version: '2025.1'}
toolchain: {compiler: intel, version: '2025.2'}
- os: windows-latest # gcc 14 not available on Windows yet
toolchain: {compiler: gcc, version: 14}
- os: windows-latest # gcc 15 not available on Windows yet
Expand Down
4 changes: 2 additions & 2 deletions ci/meta_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pushd metapackage_stdlib
popd

pushd metapackage_minpack
"$fpm" build --verbose
"$fpm" run --verbose
"$fpm" build --verbose --flag " -Wno-external-argument-mismatch"
"$fpm" run --verbose --flag " -Wno-external-argument-mismatch"
popd

pushd metapackage_mpi
Expand Down
6 changes: 5 additions & 1 deletion ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ popd

# Test shared library dependencies
pushd shared_lib
"$fpm" build || EXIT_CODE=$?
"$fpm" build --verbose || EXIT_CODE=$?
test $EXIT_CODE -eq 0
popd

Expand Down Expand Up @@ -374,5 +374,9 @@ popd
# Test custom build directory functionality
bash "../ci/test_custom_build_dir.sh" "$fpm" hello_world

# Test FPM features functionality
echo "=== Testing FPM Features Functionality ==="
bash "../ci/test_features.sh" "$fpm"

# Cleanup
rm -rf ./*/build
314 changes: 314 additions & 0 deletions ci/test_features.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,314 @@
#!/usr/bin/env bash
set -exo pipefail

# Test script for FPM features functionality
# Usage: ./test_features.sh [fpm_executable]
# Note: This script should be run from the repo root or integrated into run_tests.sh

if [ "$1" ]; then
fpm="$1"
else
# Default to the fpm passed from run_tests.sh or system fpm
fpm="${fpm:-fpm}"
fi

echo "Testing FPM features functionality"

echo "=== Testing features_demo package ==="

# Test 1: Basic features - debug feature
pushd "features_demo"
echo "Test 1: Basic debug feature"
rm -rf build
"$fpm" run --features debug > output.txt
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled"; exit 1; }
echo "✓ Debug feature works"

# Test 2: Profile usage - development profile (includes debug)
echo "Test 2: Development profile (debug feature)"
rm -rf build
"$fpm" run --profile development --target features_demo > output.txt
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled in development profile"; exit 1; }
echo "✓ Development profile works"

# Test 3: Multiple features
echo "Test 3: Multiple features (debug + openmp)"
rm -rf build
"$fpm" run --features debug,openmp --target features_demo > output.txt
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled with multiple features"; exit 1; }
grep -q "OpenMP support enabled" output.txt || { echo "ERROR: OpenMP not enabled with multiple features"; exit 1; }
echo "✓ Multiple features work"

# Test 4: Feature-specific executable (debug_demo only available with debug feature)
echo "Test 4: Feature-specific executable"
rm -rf build
"$fpm" run --features debug --target debug_demo > output.txt
grep -q "Debug Demo Program" output.txt || { echo "ERROR: Debug Demo Program not found"; exit 1; }
grep -q "Debug mode: ON" output.txt || { echo "ERROR: Debug mode not ON in debug_demo"; exit 1; }
echo "✓ Feature-specific executable works"

# Test 5: Profile with multiple features - production profile (release + openmp)
echo "Test 5: Production profile (release + openmp)"
rm -rf build
"$fpm" run --profile production --target features_demo > output.txt
grep -q "RELEASE mode enabled" output.txt || { echo "ERROR: RELEASE mode not enabled in production profile"; exit 1; }
grep -q "OpenMP support enabled" output.txt || { echo "ERROR: OpenMP not enabled in production profile"; exit 1; }
# Should NOT have debug
if grep -q "DEBUG mode enabled" output.txt; then
echo "ERROR: DEBUG mode should not be enabled in production profile"
exit 1
fi
echo "✓ Production profile works"

# Test 6: No features - baseline behavior
echo "Test 6: No features (baseline)"
rm -rf build
"$fpm" run --target features_demo > output.txt
# Should have neither DEBUG nor RELEASE without explicit features
if grep -q "DEBUG mode enabled" output.txt; then
echo "ERROR: DEBUG mode should not be enabled in baseline"
exit 1
fi
if grep -q "RELEASE mode enabled" output.txt; then
echo "ERROR: RELEASE mode should not be enabled in baseline"
exit 1
fi
if ! grep -q "Features: NONE" output.txt && ! grep -q "Demo completed successfully" output.txt; then
echo "ERROR: Expected baseline features output not found"
exit 1
fi
echo "✓ Baseline (no features) works"

# Test 7: Error handling - invalid feature
echo "Test 7: Error handling for invalid feature"
rm -rf build
if ! "$fpm" run --features nonexistent --target features_demo > /dev/null 2>&1; then
echo "Correctly rejected invalid feature"
else
echo "ERROR: Should reject invalid feature" && exit 1
fi

# Test 8: Error handling - invalid profile
echo "Test 8: Error handling for invalid profile"
rm -rf build
if ! "$fpm" run --profile nonexistent --target features_demo > /dev/null 2>&1; then
echo "Correctly rejected invalid profile"
else
echo "ERROR: Should reject invalid profile" && exit 1
fi

# Test 9: Features and profile mutual exclusion
echo "Test 9: Features and profile mutual exclusion"
rm -rf build
if ! "$fpm" run --features debug --profile development --target features_demo > /dev/null 2>&1; then
echo "Correctly rejected features + profile combination"
else
echo "ERROR: Should reject features + profile combination" && exit 1
fi

# Cleanup
rm -rf build output.txt build_list.txt
popd

echo "=== Testing features_with_dependency package ==="

# Test dependency features
pushd "features_with_dependency"

# RE-ENABLE AFTER MERGING fpm WITH CPP PARSING PR
# Test 10: No features - should show NONE for both local and dependency
# echo "Test 10: Dependency package without features"
rm -rf build
#"$fpm" run | tee output.txt
# grep -q "NONE - no local features active" output.txt || { echo "ERROR: Local features NONE message not found"; exit 1; }
# grep -q "Features: NONE" output.txt || { echo "ERROR: Features NONE not found in dependency test"; exit 1; }
# echo "✓ Dependency package baseline works"

# Test 11: Debug dependency feature
echo "Test 11: Debug dependency feature"
rm -rf build
"$fpm" run --features with_feat_debug > output.txt
grep -q "WITH_DEBUG_DEPENDENCY" output.txt || { echo "ERROR: WITH_DEBUG_DEPENDENCY not found"; exit 1; }
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled in dependency test"; exit 1; }
echo "✓ Debug dependency feature works"

# Test 12: Release dependency feature
echo "Test 12: Release dependency feature"
rm -rf build
"$fpm" run --features with_feat_release > output.txt
grep -q "WITH_RELEASE_DEPENDENCY" output.txt || { echo "ERROR: WITH_RELEASE_DEPENDENCY not found"; exit 1; }
grep -q "RELEASE mode enabled" output.txt || { echo "ERROR: RELEASE mode not enabled in dependency test"; exit 1; }
echo "✓ Release dependency feature works"

# Test 13: Multi dependency feature
echo "Test 13: Multi dependency feature"
rm -rf build
"$fpm" run --features with_feat_multi > output.txt
grep -q "WITH_MULTI_DEPENDENCY" output.txt || { echo "ERROR: WITH_MULTI_DEPENDENCY not found"; exit 1; }
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled in multi dependency test"; exit 1; }
grep -q "MPI support enabled" output.txt || { echo "ERROR: MPI support not enabled in multi dependency test"; exit 1; }
echo "✓ Multi dependency feature works"

# Test 14: Profile with dependency features
echo "Test 14: Debug dependency profile"
rm -rf build
"$fpm" run --profile debug_dep > output.txt
grep -q "WITH_DEBUG_DEPENDENCY" output.txt || { echo "ERROR: WITH_DEBUG_DEPENDENCY not found in profile test"; exit 1; }
grep -q "DEBUG mode enabled" output.txt || { echo "ERROR: DEBUG mode not enabled in dependency profile test"; exit 1; }
echo "✓ Debug dependency profile works"

# Cleanup
rm -rf build output.txt
popd

echo "=== Testing features_per_compiler package ==="

# Test features per compiler package
pushd "features_per_compiler"

# Test 15: Development profile (debug + verbose)
echo "Test 15: Features per compiler - development profile"
rm -rf build
if "$fpm" run --profile development > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ DEBUG: debug flags found" output.txt || { echo "ERROR: Debug feature not detected"; exit 1; }
grep -q "✓ VERBOSE: -v flag found" output.txt || { echo "ERROR: Verbose feature not detected"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Check compiler-specific flags (will depend on detected compiler)
if grep -q "Detected compiler: gfortran" output.txt; then
grep -q "✓ Debug: -Wall found" output.txt || { echo "ERROR: gfortran debug flag -Wall not found"; exit 1; }
grep -q "✓ Debug: -fcheck=bounds found" output.txt || { echo "ERROR: gfortran debug flag -fcheck=bounds not found"; exit 1; }
fi
echo "✓ Development profile works"

# Test 16: Production profile (release + fast)
echo "Test 16: Features per compiler - production profile"
rm -rf build
if "$fpm" run --profile production > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ RELEASE: -O flags found" output.txt || { echo "ERROR: Release feature not detected"; exit 1; }
grep -q "✓ FAST: fast optimization flags found" output.txt || { echo "ERROR: Fast feature not detected"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Check compiler-specific flags (will depend on detected compiler)
if grep -q "Detected compiler: gfortran" output.txt; then
# Check for either -march=native or -mcpu (Apple Silicon uses -mcpu)
if ! (grep -q "✓ Release: -march=native found" output.txt || grep -q "✓ Release: -mcpu found" output.txt); then
echo "ERROR: gfortran release architecture flag (-march=native or -mcpu) not found"
exit 1
fi
grep -q "✓ Fast: -ffast-math found" output.txt || { echo "ERROR: gfortran fast flag -ffast-math not found"; exit 1; }
fi
echo "✓ Production profile works"

# Test 17: Testing profile (debug + strict)
echo "Test 17: Features per compiler - testing profile"
rm -rf build
if "$fpm" run --profile testing > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ DEBUG: debug flags found" output.txt || { echo "ERROR: Debug feature not detected"; exit 1; }
grep -q "✓ STRICT: standard compliance flags found" output.txt || { echo "ERROR: Strict feature not detected"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Check compiler-specific flags (will depend on detected compiler)
if grep -q "Detected compiler: gfortran" output.txt; then
grep -q "✓ Strict: -Wpedantic found" output.txt || { echo "ERROR: gfortran strict flag -Wpedantic not found"; exit 1; }
fi
echo "✓ Testing profile works"

# Test 18: Individual features - debug only
echo "Test 18: Features per compiler - debug feature only"
rm -rf build
if "$fpm" run --features debug > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ DEBUG: debug flags found" output.txt || { echo "ERROR: Debug feature not detected"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Should NOT have release or fast flags
if grep -q "✓ RELEASE: -O flags found" output.txt; then
echo "ERROR: Release flags should not be present with debug only"
exit 1
fi
echo "✓ Debug feature works"

# Test 19: Individual features - release only
echo "Test 19: Features per compiler - release feature only"
rm -rf build
if "$fpm" run --features release > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ RELEASE: -O flags found" output.txt || { echo "ERROR: Release feature not detected"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Should NOT have debug flags
if grep -q "✓ DEBUG: debug flags found" output.txt; then
echo "ERROR: Debug flags should not be present with release only"
exit 1
fi
echo "✓ Release feature works"

# Test 20: No profile/features - baseline
echo "Test 20: Features per compiler - baseline (no profile)"
rm -rf build
if "$fpm" run > output.txt 2>&1; then
echo "✓ Exit code 0 (success) as expected"
else
echo "ERROR: Expected exit code 0 but got non-zero exit code"
echo "=== Program output ==="
cat output.txt
echo "======================"
exit 1
fi
grep -q "Features Per Compiler Demo" output.txt || { echo "ERROR: Features Per Compiler Demo not found"; exit 1; }
grep -q "✓ All compiler flag checks PASSED" output.txt || { echo "ERROR: Expected all checks to pass"; exit 1; }
# Should NOT have any feature flags in baseline
if grep -q "✓ DEBUG: debug flags found" output.txt; then
echo "ERROR: Debug flags should not be present in baseline"
exit 1
fi
if grep -q "✓ RELEASE: -O flags found" output.txt; then
echo "ERROR: Release flags should not be present in baseline"
exit 1
fi
echo "✓ Baseline (no profile) works"

# Cleanup
rm -rf build output.txt
popd

echo "All FPM features tests passed!"
16 changes: 16 additions & 0 deletions example_packages/features_demo/app/debug_demo.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
program debug_demo
use features_demo
implicit none

write(*,*) 'Debug Demo Program'
write(*,*) '=================='

#ifdef DEBUG
write(*,*) 'Debug mode: ON'
#else
write(*,*) 'Debug mode: OFF'
#endif

call show_features()

end program debug_demo
12 changes: 12 additions & 0 deletions example_packages/features_demo/app/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
program main
use features_demo
implicit none

call show_features()

write(*,*) ''
write(*,*) get_build_info()
write(*,*) ''
write(*,*) 'Demo completed successfully!'

end program main
Loading
Loading