Conversation
Add a new subcommand that generates a CMakeLists.txt file from an fpm project. This allows building fpm projects with CMake for better IDE integration or deployment to environments where fpm is not available. The generated CMakeLists.txt includes: - Library target (if src/ sources exist) - Executable targets (from app/) - Test targets with enable_testing() and add_test() Limitations documented in help text: - fpm dependencies not auto-handled in CMake - Metapackages/registry deps not translated - Complex preprocessing may need adjustment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, `get_sources_for_exe` only included sources where `exe_name` matched the executable name. However, `exe_name` is only set for source files containing a `program` statement, not for helper modules. This caused CMake builds to fail for test executables like `fpm-test` that depend on multiple source files (e.g., main.f90 + testsuite.f90 + test_*.f90 modules). The fix changes the logic to: 1. Find the main program file by matching exe_name 2. Extract its directory path 3. Include ALL source files from that directory with the same scope This matches fpm's native build behavior where all sources in an executable's source directory are compiled together. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This reverts commit dbc6628.
Previously only detected fpm.toml changes. Now detects source file additions, deletions, renames, and content changes by hashing source file paths and content digests already computed by build_model. Changes: - Add compute_project_hash() that combines manifest + source digests - Move staleness check after build_model to access source digests - Update CMake header from "Manifest hash:" to "Project hash:" - Maintain backward compatibility with old format (triggers regeneration) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…with my own personal branch
Wrap add_subdirectory calls in if(NOT TARGET) guards to prevent duplicate target definitions when packages have mutual dependencies. This allows CMake builds to succeed from either direction in circular dependency scenarios while maintaining correct behavior for normal and diamond dependencies. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Tests were only initializing compiler and build_dir fields, leaving other allocatable character fields unallocated. This caused runtime errors on macOS when build_model() passed these unallocated fields to new_compiler() as character(len=*) arguments. Fortran standard requires allocatable actual arguments to be allocated when passed to non-allocatable dummy arguments. macOS gfortran has stricter runtime checks and caught this violation. Added init_test_settings() helper that properly initializes all fields following the production build_settings() pattern. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
On Windows CI/CD, CMake was defaulting to Visual Studio generators which cannot find the GCC/gfortran compiler. Detect Windows/MSYS2 environments and explicitly use the MinGW Makefiles generator for Fortran support. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When fpm generate cmake runs on Windows, it writes source file paths with Windows-style backslashes (e.g., .\.\src\lib.f) to CMakeLists.txt files. CMake interprets these backslashes as escape sequences, causing syntax errors like "Invalid character escape '\s'". This fix modifies the clean_path() function in cmake.f90 to call unix_path() before cleaning leading ./ prefixes. The unix_path() function converts all backslashes to forward slashes, which CMake accepts on all platforms including Windows. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extends commit 238c65d to cover include directories, metapackage paths, and dependency subdirectory paths written to CMakeLists.txt files. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
High-priority fixes: - Propagate I/O errors from write_lines_to_file instead of silent failure - Check fpm generate exit code in test_cmake.sh before proceeding to cmake - Fix integer overflow in hash table using iand() instead of abs() - Optimize staleness check to read only first 5 lines for non-fpm CMake files Medium-priority fixes: - Use preprocessor config name as serialization key instead of positional index - Propagate errors from generate_dependency_cmake Low-priority fixes: - Replace O(n*m) source lookup with O(n) hash map in compute_project_hash Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extract duplicated compiler-to-cpp-flag mapping into get_cpp_flag(), remove dead code (unused is_header_only, temp_dirs, FPM_SCOPE_EXAMPLE), fix portability bug using is_dir() instead of inquire(file=) for dirs, replace magic number with named project_hash_marker constant, handle C/C++ header files in language detection, detect dependency languages from sources instead of hardcoding Fortran, use original test name in add_test NAME, and fix test_cmake.sh cleanup of dependency files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GNU ld processes arguments left-to-right, so library flags (e.g. MPI's -lmpi_usempif08) must come after the object files that reference them. Previously, model%link_flags was prepended before the objects, causing "undefined reference" errors in metapackage_mpi builds. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
# Conflicts: # src/fpm/manifest/dependency.f90
Replaces O(n²) insertion sort + chain-hashing with O(n) XOR-based hash combination. This eliminates the sort_strings subroutine and hash table allocations while maintaining deterministic hashing. Uses XOR to combine per-file hashes (path + digest), which is safe since file paths are unique. Hash values will change for existing projects (one-time CMake regeneration cost). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Thanks for working on this, we need this. Is this PR working? Let us know when this is ready for review. |
|
Hi @certik, yes, this PR is working. Out of 72 example packages in the fpm repo, 71 build and run correctly with generated cmake. Only Perhaps we should discuss one concern before starting the review. As mentioned in the description, the cmake staleness detection has false positives. There are at least three options:
The current implementation uses fpm's digest of every source file to detect cmake staleness. Of course, most small changes to a single source file will not actually require regenerating |
Summary
Adds
fpm generate --cmakecommand to export fpm projects as CMake build files, enabling CMake-based builds for better IDE integration and deployment to environments without fpm.Features
fpm buildto re-build will also cause a staleness warningfpm build,fpm test, andfpm runTest Coverage
Performance
Optimized with hash tables for O(n) dependency resolution and source lookups.
Fixes #1240