fortran-lang / minpack

Modernized Minpack: for solving nonlinear equations and nonlinear least squares problems
https://fortran-lang.github.io/minpack/
Other
90 stars 18 forks source link

Warn if Fortran compiler does not support C-API #56

Closed awvwgk closed 2 years ago

awvwgk commented 2 years ago

Will be turned into an error in case Python bindings are enabled.

Related to #54

@nicholaswogan @certik could you check on your Mac whether it correctly produces a warning / error with GFortran 11?

certik commented 2 years ago

Sure. What should I test exactly?

awvwgk commented 2 years ago

Try to setup a build (there is an environment file for conda in config/ci/meson-env.yaml) with

meson setup _build -Dpython=true

It is supposed to fail with an error if nested functions are not supported.

The plain build should work, but skip the C bindings with a warning:

meson setup _build --prefix=$PWD/_dist
meson compile -C _build
meson test -C _build
meson install -C _build

The file $PWD/_dist/include/minpack.h should be absent. This way the Python API can't be built with setuptools against an installation which doesn't support the C bindings completely.

certik commented 2 years ago

I installed gfortran using (due to https://github.com/conda-forge/gfortran_osx-64-feedstock/issues/40#issuecomment-1056077006):

mamba create -n minpack gfortran compiler-rt=11.0.1 libcxx=11.0.1 meson ninja

Then I load it and run meson:

(minpack) fortran-lang/minpack(main) $ meson setup _build -Dpython=true
The Meson build system
Version: 0.61.2
Source dir: /Users/ondrej/repos/fortran-lang/minpack
Build dir: /Users/ondrej/repos/fortran-lang/minpack/_build
Build type: native build
Project name: minpack
Project version: 2.0.0

meson.build:1:0: ERROR: Unable to detect GNU compiler type:
arm64-apple-darwin20.0.0-gfortran: fatal error: cannot execute ‘cc1’: execvp: No such file or directory
compilation terminated.

A full log can be found at /Users/ondrej/repos/fortran-lang/minpack/_build/meson-logs/meson-log.txt

So it fails, but with a different error it seems.

certik commented 2 years ago

But gfortran works for me, I tested it in the same Conda environment using:

(minpack) fortran-lang/minpack(main) $ fpm new xx
 + mkdir -p xx
 + cd xx
 + mkdir -p xx/src
 + mkdir -p xx/app
 + mkdir -p xx/test
 + git config --get user.name > /var/tmp/tmp.J5u5Wx
 + git config --get user.email > /var/tmp/tmp.BkI0OG
 + git config --get user.name > /var/tmp/tmp.p9JQIL
 + git init xx
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Initialized empty Git repository in /Users/ondrej/repos/fortran-lang/minpack/xx/.git/
(minpack) fortran-lang/minpack(main) $ cd xx
(minpack) minpack/xx(master) $ ls
README.md app       fpm.toml  src       test
(minpack) minpack/xx(master) $ fpm run
 + mkdir -p build/dependencies
xx.f90                                 done.
libxx.a                                done.
main.f90                               done.
xx                                     done.
[100%] Project compiled successfully.
 Hello, xx!
awvwgk commented 2 years ago

This looks like the old cc1 issue with conda-forge's GFortran (https://github.com/conda-forge/gfortran_osx-64-feedstock/issues/11). I hit this in a couple of pure Fortran recipes on conda-forge, where I must also have C compiler on MacOS. Maybe the additional pin downgrades GFortran to a version which was still broken?

certik commented 2 years ago

I have clang installed and it works. The cc1 binary is not in PATH. I couldn't figure out how meson calls gfortran that it requires this cc1 binary. The log _build/meson-logs/meson-log.txt just says:

Build started at 2022-03-12T10:02:10.685572
Main binary: /Users/ondrej/mambaforge/envs/minpack/bin/python3.10
Build Options: -Dprefix=/Users/ondrej/repos/fortran-lang/minpack/_dist
Python system: Darwin
The Meson build system
Version: 0.61.2
Source dir: /Users/ondrej/repos/fortran-lang/minpack
Build dir: /Users/ondrej/repos/fortran-lang/minpack/_build
Build type: native build
Project name: minpack
Project version: 2.0.0

meson.build:1:0: ERROR: Unable to detect GNU compiler type:
arm64-apple-darwin20.0.0-gfortran: fatal error: cannot execute ‘cc1’: execvp: No such file or directory
compilation terminated.

Since gfortran seems to work for me, I assume it's a bug in Meson?

awvwgk commented 2 years ago

It's a bug in conda-forge's GFortran setup (see https://github.com/conda-forge/gfortran_osx-64-feedstock/issues/11), they delete the C compiler from GCC, however build systems like CMake and meson trying to get the version via preprocessor will be directed to the C driver of GCC which is absent and therefore fail.

The ugly workaround I used for conda-forge's GFortran is create a dummy cc1 script

cat > cc1 <<EOF
#!/usr/bin/env bash
ARGS=()
for var in "\$@"; do
    # Ignore known bad arguments
    [ "\$var" != '-quiet' ] && ARGS+=("\$var")
done

"\$CC" "\${ARGS[@]}"
EOF
chmod +x cc1
PATH=$PWD:$PATH meson setup _build

The better workaround might be to use the cc1 script in newer GFortran packages, but only works if the cc1.bin is actually present...

certik commented 2 years ago

I see, gfortran --help -v indeed fails for me (missing cc1). With your workaround, I get:

$ PATH=$PWD:$PATH meson setup _build
The Meson build system
Version: 0.61.2
Source dir: /Users/ondrej/repos/fortran-lang/minpack
Build dir: /Users/ondrej/repos/fortran-lang/minpack/_build
Build type: native build
Project name: minpack
Project version: 2.0.0

meson.build:1:0: ERROR: Unable to detect GNU compiler type:
clang-11: warning: argument unused during compilation: '-dumpbase' [-Wunused-command-line-argument]
error: unknown target ABI 'lp64'
error: unknown target ABI 'lp64'

A full log can be found at /Users/ondrej/repos/fortran-lang/minpack/_build/meson-logs/meson-log.txt
awvwgk commented 2 years ago

Too bad, upgrading to a new GFortran package would solve this without hacks, but than you will run in that other issue https://github.com/conda-forge/gfortran_osx-64-feedstock/issues/40 again. Not sure if it is worth to troubleshoot and workaround this further (by dropping all gcc specific arguments before calling clang) if it is an upstream bug which will get fixed eventually. Also, on MacOS/Arm64 you won't get more functionality than with fpm from the meson build anyway at the moment.

certik commented 2 years ago

Yeah, I'll wait until it's fixed upstream. I am glad fpm doesn't do these checks of compilers. As we are finding out, they seem to cause more trouble than gain.

awvwgk commented 2 years ago

I guess we can just go ahead and merge for now (checked this patch by making the code snippet invalid on purpose), unless somebody wants to test it with homebrew/macports GCC on MacOS/Arm64 first.