fortran-lang / fpm

Fortran Package Manager (fpm)
https://fpm.fortran-lang.org
MIT License
891 stars 100 forks source link

fpm cannot build packages with C or C++ main program with `ifort` #895

Closed perazz closed 1 year ago

perazz commented 1 year ago

Description

fpm packages that have a C or a C++ main program do not build when using ifort/icc as the project compiler.

The error returned is: multiple definition of main

This discussion on Stackoverflow suggests using an ifort-specific linker flag to tell the linker that the main program is not a Fortran one.

Expected Behaviour

fpm should work in these cases, like it does with gcc/gfortran

Version of fpm

0.8.1

Platform and Architecture

ubuntu-22.04 x86_64

Additional Information

If I build one of the C/C++ example packages I get:

root@d1d590b7d352:~/fpm-dev/example_packages/preprocess_cpp_c# fpm build --verbose
 <INFO> BUILD_NAME: build/ifort
 <INFO> COMPILER:  ifort
 <INFO> C COMPILER:  icc
 <INFO> CXX COMPILER: icpc
 <INFO> COMPILER OPTIONS:
 -fpp -warn all -check all -error-limit 1 -O0 -g -assume byterecl -traceback
 <INFO> C COMPILER OPTIONS:
 <INFO> CXX COMPILER OPTIONS:
 <INFO> LINKER OPTIONS:
 <INFO> INCLUDE DIRECTORIES:  [././include]
[  0%]                           main
 +
 ifort -fpp -warn all -check all -error-limit 1 -O0 -g -assume byterecl -traceba
 ck -I././include  build/ifort_2FFBFAF9D49EF13B/preprocess_cpp_c/app_main.c.o  -
 o build/ifort_7D9DC84655E6F8AE/app/main
ld: build/ifort_2FFBFAF9D49EF13B/preprocess_cpp_c/app_main.c.o: in function `main':
main.c:(.text+0x0): multiple definition of `main'; /opt/intel/oneapi/compiler/2023.0.0/linux/bin/intel64/../../compiler/lib/intel64_lin/for_main.o:for_main.c:(.text+0x0): first defined here
ld: /opt/intel/oneapi/compiler/2023.0.0/linux/bin/intel64/../../compiler/lib/intel64_lin/for_main.o: in function `main':
for_main.c:(.text+0x19): undefined reference to `MAIN__'
[100%]                           main  done.

ld: build/ifort_2FFBFAF9D49EF13B/preprocess_cpp_c/app_main.c.o: in function `main':
main.c:(.text+0x0): multiple definition of `main'; /opt/intel/oneapi/compiler/2023.0.0/linux/bin/intel64/../../compiler/lib/intel64_lin/for_main.o:for_main.c:(.text+0x0): first defined here
ld: /opt/intel/oneapi/compiler/2023.0.0/linux/bin/intel64/../../compiler/lib/intel64_lin/for_main.o: in function `main':
for_main.c:(.text+0x19): undefined reference to `MAIN__'
<ERROR> Compilation failed for object " main "
<ERROR>stopping due to failed compilation
1

If I add the -nofor-main flag, it works:

root@d1d590b7d352:~/fpm-dev/example_packages/preprocess_cpp_c# fpm build --verbose --link-flag "-nofor-main"
 <INFO> BUILD_NAME: build/ifort
 <INFO> COMPILER:  ifort
 <INFO> C COMPILER:  icc
 <INFO> CXX COMPILER: icpc
 <INFO> COMPILER OPTIONS:
 -fpp -warn all -check all -error-limit 1 -O0 -g -assume byterecl -traceback
 <INFO> C COMPILER OPTIONS:
 <INFO> CXX COMPILER OPTIONS:
 <INFO> LINKER OPTIONS:   -nofor-main
 <INFO> INCLUDE DIRECTORIES:  [././include]
 + mkdir -p build/ifort_DD2C7FA91F06AD19
[  0%]                           main
 + mkdir -p build/ifort_DD2C7FA91F06AD19/app/
 +
 ifort -fpp -warn all -check all -error-limit 1 -O0 -g -assume byterecl -traceba
 ck -I././include  -nofor-main build/ifort_2FFBFAF9D49EF13B/preprocess_cpp_c/app
 _main.c.o  -o build/ifort_DD2C7FA91F06AD19/app/main
[100%]                           main  done.
[100%] Project compiled successfully.
root@d1d590b7d352:~/fpm-dev/example_packages/preprocess_cpp_c#
egiovan commented 1 year ago

The same happens with pgf90, the option should be -Mnomain in that case.

perazz commented 1 year ago

Confirmed, I found that here. I will now add the same option for pgif90/nvfortran, but unfortunately we have no way to test it in the CI.

perazz commented 1 year ago

Closed by #896.