Skip to content

feat: exec Fortran compiles via argv (posix_spawn/CreateProcess)#1299

Open
krystophny wants to merge 2 commits into
fortran-lang:mainfrom
krystophny:perf/argv-fortran-compile
Open

feat: exec Fortran compiles via argv (posix_spawn/CreateProcess)#1299
krystophny wants to merge 2 commits into
fortran-lang:mainfrom
krystophny:perf/argv-fortran-compile

Conversation

@krystophny

Copy link
Copy Markdown
Contributor

Summary

  • Execute the Fortran compile command through a direct argv spawn instead of
    a /bin/sh -c (or cmd /c) string, on both Unix and Windows
  • posix_spawnp (Unix) and CreateProcess (Windows) are the
    async/multithread-safe replacements for fork+exec
  • If the spawn is unavailable or fails, falls back to the existing shell
    run(), so this can only degrade to prior behavior, never break the build
  • Bootstrap builds (no C) stay on the shell path

Why this is a safety fix, not just a speedup

execute_command_line uses system(3), which forks, and concurrent fork from
a multithreaded (OpenMP) process is documented non-thread-safe. Commit
bb891e3f records a real observed failure (ar argument truncation on macOS-14
gcc 13 in CI) and works around it by wrapping link/archive in
critical(run_command), noting the compile path carries the same latent race.

Spawning the compiler by argv removes that race on the compile path and removes
the shell entirely, so quoting/escaping fragility and the shell command-length
ceiling go away too.

Merge order

This is PR 1 of 3 in the argv spawn chain. Merge in order:

  1. This PR — Fortran compiles via argv
  2. Parallel link/archive via argv (feat: run link and archive in parallel via argv spawn #1300)
  3. C/C++ compiles via argv (feat: exec C/C++ compiles via argv, close the shell-fork gap #1301)

Refs: #962

Verification

Unix, OpenMP active:

$ fpm build --flag -fopenmp
[100%] Project compiled successfully.

$ fpm test --flag -fopenmp
TALLY=TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
TALLY=TTTTTTTTTTTT
TALLY;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
PASSED: all 35 tests passed

A freshly built binary builds and runs a sample project through the argv path.
The C file cross-compiles cleanly with x86_64-w64-mingw32-gcc -Wall -Wextra.

Extend the argv-based Fortran compile spawn to Windows so it no longer
falls back to the shell there. Tokenize with the OS-native lexer
(ms_split on Windows, sh_split on Unix) so backslash paths and quoting
survive, route run_argv through c_run_argv on both platforms, and add a
CreateProcessA path with per-process stdout/stderr redirect. The shell
run remains as a fallback when the spawn returns a negative status.

Windows std handles are only overridden when redirecting, to avoid
stripping the child console; out-of-range child exit codes are clamped
positive so they are not mistaken for the spawn-failure sentinel.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant