0

I have a c++ program, which uses the FFTW3 library, which I would like to translate to Fortran. I am using Ubuntu 22.04.1.

I installed the FFTW3 library as detailed in Installation on UNIX The c++ main program is named ksbenchmark.cpp and, using g++, I compile it and link it (to the math and fftw3 libraries) with

g++ -o my_executable.out ksbenchmark.cpp -lm -lfftw3

which works great.

I have translate the c++ code in Fortran, the source file being named ksbenchmrk.f90.

If I issue

  gfortran ksbenchmark.f90 -lfftw3 -lm

I get error messages

/usr/bin/ld: /tmp/cca2xMGa.o: in function `ksintegrate_':
ksbenchmark.f90:(.text+0x59): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksbenchmark.f90:(.text+0x94): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksbenchmark.f90:(.text+0xcf): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksbenchmark.f90:(.text+0x4de): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksbenchmark.f90:(.text+0x5db): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksbenchmark.f90:(.text+0x626): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksbenchmark.f90:(.text+0x780): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksbenchmark.f90:(.text+0xa1c): undefined reference to `dfftw_execute_'
collect2: error: ld returned 1 exit status

I have spent the afternoon reading about it, and it seems I may have to use -I and -L flags such as

  gfortran test.f90 -L/new/path/to/lib -I/new/path/to/include -lfftw3 -lm

as illustrated in the post Problems linking FFTW with gfortran (symbol(s) not found for architecture x86_64).

The first question is, what paths to use?

I can find files referring to fftw3 in /usr/local/lib as well as in /usr/local/include, but the attempt

   gfortran ksbenchmark.f90 -L/usr/local/lib -I/usr/local/include -lfftw3 -lm

returns the same error as before

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
/usr/bin/ld: /tmp/ccW2DYGP.o: in function `ksintegrate_':
ksintegrate.f90:(.text+0x62): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksintegrate.f90:(.text+0x9d): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksintegrate.f90:(.text+0xd8): undefined reference to `dfftw_plan_dft_1d_'
/usr/bin/ld: ksintegrate.f90:(.text+0x4df): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksintegrate.f90:(.text+0x5f7): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksintegrate.f90:(.text+0x643): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksintegrate.f90:(.text+0x79d): undefined reference to `dfftw_execute_'
/usr/bin/ld: ksintegrate.f90:(.text+0xa5b): undefined reference to `dfftw_execute_'
collect2: error: ld returned 1 exit status

I am unable to understand which paths to the library are to be used. How to find where the library is saved? Why does not g++ need any paths to the library?

I apologise for how trivial the question might seem, I am a total newbie can ensure I put a significant effort in trying to sort this out. Any hint would be most appreciated, thanks

EDIT

Following Vladimir F Героям слава's advice, I tried using the nm command to verify the library contains what is expected to. In /usr/local/lib I found libfftw3.a and libfftw3.la files.

Issuing nm libfftw3.a I get quite a long list.

I tried looking for one of the commands I get an error about, dfftw_plan_dft_1d

nm -S libfftw3.a | grep dfftw_plan_dft_1d

and indeed it returns hits

00000000000003a0 0000000000000026 T _Z18dfftw_plan_dft_1d_PP11fftw_plan_sPiPA2_dS4_S2_S2_
0000000000002df0 0000000000000026 T _Z19dfftw_plan_dft_1d__PP11fftw_plan_sPiPA2_dS4_S2_S2_
user37292
  • 248
  • 2
  • 12
  • First please check that those symbols are indeed present in the library you are tryink to link. Of course, they should be, but if they cannot be found... You are using the legacy interface. The modern Fortran (not FORTRAN) interface is different. – Vladimir F Героям слава Nov 21 '22 at 06:15
  • @ Vladimir F Героям слава, those symbols should be indeed present in the library. I am not so sure how I would explicitly check as , If I understand correctly, the library is shipped as an object file (from the original C). Example of usage of the library in Fortran are available here, https://www.fftw.org/fftw3_doc/Fortran-Examples.html, where the command `dfftw_plan_dft_1d` is mentioned, which is the first one I get an error message about. – user37292 Nov 21 '22 at 09:25
  • The fftw3 library is split into several smaller library files. Try the `nm` command to confirm what is inside. – Vladimir F Героям слава Nov 21 '22 at 09:30
  • @ Vladimir F Героям слава, thanks for the advice, I think I confirmed, I added to the main post for clarity, thanks a lot – user37292 Nov 21 '22 at 09:53
  • Your library exports [mangled C++ names](https://en.wikipedia.org/wiki/Name_mangling#C++). instead of the normal unadorned symbols. It shouldn't. It was probably built incorrectly although I have no idea what you should do to make it happen. To find out where the library is located, try `-Wl,--trace` flag with your compilation command. – n. m. could be an AI Nov 21 '22 at 12:34
  • @n.m. that is interesting thanks. I am not familiar with those flags, cannot find them on e.g. https://gcc.gnu.org/onlinedocs/gfortran/Option-Summary.html#Option-Summary. Is `-Wl` anything like `-Wall`? I tried that an get a bunch of warning on what seem Fortran specific details, such as `Array ‘nn1’ at (1) is larger than limit set by ‘-fmax-stack-var-size=’`, but nothing on library location or so. Would you please be kind enough to give us some more detail? Thanks a lot – user37292 Nov 21 '22 at 14:04
  • `-Wl` just passes an option (`--trace` in this case) to the linker, it has nothing to do with warnings. – n. m. could be an AI Nov 21 '22 at 14:06
  • @n.m. ok got it, I get a bunch of paths, one only referencing fftw3, `/usr/local/lib/libfftw3.a` – user37292 Nov 21 '22 at 14:11
  • Then that's your libfftw3.a. If it only exports these mangled names, that's a problem. I just checked a prebuilt version for Ubuntu, it doesn't do that. – n. m. could be an AI Nov 21 '22 at 15:01
  • @n.m. thanks for your great advice. I installed the library following the instructions in http://www.fftw.org/fftw2_doc/fftw_6.html. The fact is, I would like to repeat the installation or look for a pre-built version but may I ask one last thing, how would I go about removing it? I fear it is not as simple as deleting the files in `/usr/local/lib` and `/usr/local/include`....many thanks – user37292 Nov 21 '22 at 15:29
  • It is really that simple but you need to know which files to remove. (This is the reason why I always recommend against configure-make-make install with default parameters). But you can: install again, keep the installation log, and then remove files mentioned there. – n. m. could be an AI Nov 21 '22 at 16:19
  • @n.m , It worked! I found how to get a log file, ran `sudo make install >log.txt 2>&1`, and from the log of the installation managed to get which files it was overwriting, deleted everything re-installed and I am now in business. Thanks a lot. I would accept your answer if you copied and pasted your comments into one, thank you – user37292 Nov 23 '22 at 09:57

0 Answers0