Linking error in simple test project
Forsti5 opened this issue · 3 comments
Hello,
I'm pretty new to Fortran, CMake and Github (I usually program in Python or C++ for university courses). At the moment I'm trying to make a simple Fortran program with a test case (https://github.com/Forsti5/Fortran-Unit-Test). My program consists of a main file and a second file, which has a module with a submodule, which calculates a simple physical equation. This works pretty fine. But I also try to make a test with pFUnit (see https://github.com/Forsti5/Fortran-Unit-Test/blob/main/tests/test_projectile_motion.pf). If I compile the program with only a submodule in the *.pf file, everything works fine (at the moment this part is commented out). But If I try to make several tests in one file (similar to https://github.com/Goddard-Fortran-Ecosystem/pFUnit_demos/blob/main/Basic/tests/test_simple.pf), I get the following error:
-- The Fortran compiler identification is GNU 9.3.0
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Check for working Fortran compiler: /usr/bin/f95 - skipped
-- Checking whether /usr/bin/f95 supports Fortran 90
-- Checking whether /usr/bin/f95 supports Fortran 90 - yes
-- Found Python: /usr/bin/python3.8 (found version "3.8.10") found components: Interpreter
-- Found OpenMP_Fortran: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done
-- Generating done
-- Build files have been written to: "(some directory)"
Scanning dependencies of target sut
[ 12%] Building Fortran object src/CMakeFiles/sut.dir/projectile_motion.F90.o
[ 25%] Linking Fortran static library libsut.a
[ 25%] Built target sut
[ 37%] Generating test_projectile_motion.F90
Scanning dependencies of target main
[ 50%] Building Fortran object src/CMakeFiles/main.dir/main.F90.o
[ 62%] Linking Fortran executable main
Processing file ../../tests/test_projectile_motion.pf
... Done. Results in test_projectile_motion.F90
Scanning dependencies of target test_projectile_motion
[ 87%] Building Fortran object tests/CMakeFiles/test_projectile_motion.dir/test_projectile_motion.F90.o
[ 87%] Building Fortran object tests/CMakeFiles/test_projectile_motion.dir/test_projectile_motion_driver.F90.o
[ 87%] Built target main
[100%] Linking Fortran executable test_projectile_motion
/usr/bin/ld: CMakeFiles/test_projectile_motion.dir/test_projectile_motion_driver.F90.o: in function__loader_MOD_load_tests': test_projectile_motion_driver.F90:(.text+0xa27): undefined reference to
test_projectile_motion_suite_'
collect2: error: ld returned 1 exit status
make[2]: *** [tests/CMakeFiles/test_projectile_motion.dir/build.make:121: tests/test_projectile_motion] Error 1
make[1]: *** [CMakeFiles/Makefile2:170: tests/CMakeFiles/test_projectile_motion.dir/all] Error 2
make: *** [Makefile:101: all] Error 2
I already tried a lot of different things, but I cannot solve this issue (and I took code from https://github.com/Goddard-Fortran-Ecosystem/pFUnit_demos/tree/main/Basic for CMake, sorry for that)
Can someone help me?
Thank you very much in advance :)
I'm not 100% certain of just which scenario with the source code generates the error above
The pFUnt preprocessor that takes *.pf files and adds some boiler plate code is rather unsophisticated. By default, the preprocessor constructs a test suite procedure whose name is that of the test module with an extra "_suite" suffix. In your case this would be test_projectile_motion_mod_suite'. Unfortunately, the CMake layer then makes assumptions that the suite name is based upon the file and the main progrem then tries to find
test_projectile_motion_suite(note the missing
_mod). One solution is to rename your module (but then it will conflict with the name of your test procedure), and the other is to use the
@suite` semaphore:
@suite(name='test_projectile_motion_mod_suite')
If you place this inside your test module it will override the defaut back to that expected by the cmake layer.
This really should be improved, but there are some backward compatibility concerns. Plus, once you get used to the assumption, it really does not interfere much. Just an annoyance for the occasional new user. Sorry about that.
Thank you very much for your help. Both methods work for me 👍
The only thing I had to do, was to change the semaphore to:
@suite(name='test_projectile_motion_suite')
But then everything worked fine.
Glad things are progressing. Cheers.