Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix compilation when compiling on Windows #161

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open

Fix compilation when compiling on Windows #161

wants to merge 40 commits into from

Conversation

StMartin81
Copy link

I have tested the changes with the 3.3.8 release version of FFTW.

The changes will require a CMake version which is at least 3.9. The reasons for this are that I use the "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS" CMake option to export all functions and additionally "OpenMP::OpenMP_C" is used to link against OpenMP.

The "Remove __declspec definitions as it does not work anyways" commit is rather large. I've tried the patch with the release version but the git version uses some generator functions, for which I'm not sure that I have modified all of them accordingly. This should also fix the problems described in openmp mingw undefined references.

When compiling FFTW as a shared library on Windows the "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS" CMake option has to be set to "ON".

Martin Stolpe added 11 commits January 22, 2019 09:08
…cluded with add_subdirectory in other CMake project
Bump required CMake version to 3.4 as this is the first version which supports CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
Bump required CMake version to 3.9 as this is the first version which supports the OpenMP::OpenMP_C syntax for target_link_libraries
Assume FFTW is build as shared library per default (FFTW_STATIC define has to be set when using the static version)
@nickdademo
Copy link

nickdademo commented Jun 16, 2019

Just checked out this branch and tried compilation on VS 2017 x64. I'm getting linking errors:

1>   Creating library C:/Projects/temp/fftw3/build/Debug/fftw3f.lib and object C:/Projects/temp/fftw3/build/Debug/fftw3f.exp
1>conf.c.obj : error LNK2001: unresolved external symbol fftwf_solvtab_dft_standard
1>conf.c.obj : error LNK2001: unresolved external symbol fftwf_solvtab_dft_avx
1>conf.c.obj : error LNK2001: unresolved external symbol fftwf_solvtab_rdft_r2cf
1>conf.c.obj : error LNK2001: unresolved external symbol fftwf_solvtab_rdft_r2cb
1>conf.c.obj : error LNK2001: unresolved external symbol fftwf_solvtab_rdft_avx

I configured with:

BUILD_SHARED_LIBS ON
BUILD_TESTS OFF

ENABLE_OPENMP ON
ENABLE_THREADS ON
WITH_COMBINED_THREADS OFF

ENABLE_FLOAT ON
ENABLE_LONG_DOUBLE OFF
ENABLE_QUAD_PRECISION OFF

ENABLE_SSE OFF
ENABLE_SSE2 ON
ENABLE_AVX OFF
ENABLE_AVX2 ON

DISABLE_FORTRAN OFF

CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON

CMake on MSYS2 also gives the same:

cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=OFF -DENABLE_OPENMP=ON -DENABLE_THREADS=ON -DWITH_COMBINED_THREADS=OFF -DENABLE_FLOAT=ON -DENABLE_LONG_DOUBLE=OFF -DENABLE_QUAD_PRECISION=OFF -DENABLE_SSE=ON -DENABLE_SSE2=ON -DENABLE_AVX=ON -DENABLE_AVX2=ON -DDISABLE_FORTRAN=OFF -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON ..

Output:

[ 90%] Linking C shared library libfftw3f.dll
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_dft_avx2_128[.refptr.fftwf_solvtab_dft_avx2_128]+0x0): undefined reference to `fftwf_solvtab_dft_avx2_128'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_dft_avx2[.refptr.fftwf_solvtab_dft_avx2]+0x0): undefined reference to `fftwf_solvtab_dft_avx2'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_dft_avx[.refptr.fftwf_solvtab_dft_avx]+0x0): undefined reference to `fftwf_solvtab_dft_avx'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_dft_sse2[.refptr.fftwf_solvtab_dft_sse2]+0x0): undefined reference to `fftwf_solvtab_dft_sse2'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_dft_standard[.refptr.fftwf_solvtab_dft_standard]+0x0): undefined reference to `fftwf_solvtab_dft_standard'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_avx2_128[.refptr.fftwf_solvtab_rdft_avx2_128]+0x0): undefined reference to `fftwf_solvtab_rdft_avx2_128'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_avx2[.refptr.fftwf_solvtab_rdft_avx2]+0x0): undefined reference to `fftwf_solvtab_rdft_avx2'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_avx[.refptr.fftwf_solvtab_rdft_avx]+0x0): undefined reference to `fftwf_solvtab_rdft_avx'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_sse2[.refptr.fftwf_solvtab_rdft_sse2]+0x0): undefined reference to `fftwf_solvtab_rdft_sse2'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_r2r[.refptr.fftwf_solvtab_rdft_r2r]+0x0): undefined reference to `fftwf_solvtab_rdft_r2r'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_r2cb[.refptr.fftwf_solvtab_rdft_r2cb]+0x0): undefined reference to `fftwf_solvtab_rdft_r2cb'
CMakeFiles/fftw3f.dir/objects.a(conf.c.obj):conf.c:(.rdata$.refptr.fftwf_solvtab_rdft_r2cf[.refptr.fftwf_solvtab_rdft_r2cf]+0x0): undefined reference to `fftwf_solvtab_rdft_r2cf'
collect2.exe: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/fftw3f.dir/build.make:3056: libfftw3f.dll] Error 1
make[1]: *** [CMakeFiles/Makefile2:105: CMakeFiles/fftw3f.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

UPDATE: Build works when using the autoconf configure script build method...

@nickdademo
Copy link

@StMartin81 Any ideas on what could be wrong with the linking? (as above)

@StMartin81
Copy link
Author

I'm sorry it took me so long to answer this question. I didn't have time to look into the problem and it's been a while since I was working with FFTW. The master branch is a clone of the original FFTW master branch. This branch is not supposed to be used by end users as some files have to be generated first. These auto generated files provide the functions which the linker is complaining about.

Try to use the 3.3.8 branch which is based on the source .tar.gz files provided by the authors of FFTW. This branch includes the needed generated files.

I would also strongly recommend to use Ninja as build generator, as this will greatly speed up the compilation:

  • Make sure you have the Ninja executable in your path environment
  • Open a Visual Studio command prompt
  • Compile the project with the following commands:
    cmake -G Ninja -DCMAKE_CXX_COMPILER:STRING="cl.exe" -DCMAKE_C_COMPILER:STRING="cl.exe" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=OFF -DENABLE_OPENMP=ON -DENABLE_THREADS=OFF -DWITH_COMBINED_THREADS=OFF -DENABLE_FLOAT=ON -DENABLE_LONG_DOUBLE=OFF -DENABLE_QUAD_PRECISION=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=ON -DENABLE_AVX=OFF -DENABLE_AVX2=ON -DISABLE_FORTRAN=OFF -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON -DCMAKE_INSTALL_PREFIX=.\install ..\<path to FFTW3 source folder> cmake --build . --parallel 4 --config Release --target install

This should hopefully successfully build FFTW.

@nickdademo
Copy link

@StMartin81 Thank you very much! Building from the 3.3.8 branch works. Out of curiosity, how are the auto-generated files created? Are there instructions anywhere?

@StMartin81
Copy link
Author

I don't know how to generate the files. You would have to ask the authors of FFTW3 for that. Some hints can be found here: http://www.fftw.org/fftw3_doc/Generating-your-own-code.html#Generating-your-own-code

@nickdademo
Copy link

@StMartin81 Is there a plan to integrate this PR before the next FFTW3 release?

@StMartin81
Copy link
Author

I don't think so. At least I haven't heard anything back from the authors of FFTW.

@stevengj
Copy link
Contributor

stevengj commented Sep 7, 2019

What's wrong with using __declspec to export? Is it just a matter of defining DLL_EXPORT when compiling FFTW?

(We have used mingw a lot to compile FFTW for Windows, but it was with the autoconf configure scripts, which use GNU libtool, which #defines the DLL_EXPORT symbol when compiling a shared library with MinGW.)

Martin Stolpe added 5 commits October 2, 2019 12:31
This reverts commit 3a94455.

Including FindThreads will set Threads_FOUND to true if the thread library was found regardless if ENABLE_THREADS was enabled or not.
…EADS=OFF

If both options are enabled link against fftw3_threads/fftw3
@StMartin81
Copy link
Author

StMartin81 commented Oct 2, 2019

The __declspec works fine but the problem is that some symbols would need to be exported conditionally depending on the compile options. For example if I compile FFTW3 with threads:

$ cmake -G Ninja -DENABLE_THREADS=ON -DBUILD_TESTS=OFF
$ cmake --build .

The linker will output error messages like the following:

ld.exe: CMakeFiles/fftw3_threads.dir/threads/conf.c.obj:conf.c:(.text+0xb): undefined reference to `fftw_solvtab_exec'

This is because fftw_solvtab_exec is defined in libfftw3 without __declspec and libfftw3_threads uses this function which is not exported so the linker is not able to link to it.

@stevengj
Copy link
Contributor

problem is that some symbols would need to be exported conditionally depending on the compile options.

Can't the CMake script add -DDLL_EXPORT if needed?

@StMartin81
Copy link
Author

I've added the following define in my CMakeLists.txt:
add_compile_definitions(DLL_EXPORT)
When I compile FFTW3 with the following settings enabled:

  • BUILD_SHARED_LIBS
  • BUILD_TESTS
  • ENABLE_OPENMP

Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol fftw_imax referenced in function fftw_plan_with_nthreads C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\fftw-3.3.8 C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\api.c.obj 1 Error LNK2001 unresolved external symbol fftw_mksolver_ct_hook C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\fftw-3.3.8 C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\api.c.obj 1 Error LNK2001 unresolved external symbol fftw_mksolver_hc2hc_hook C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\fftw-3.3.8 C:\Users\Martin\Downloads\fftw-3.3.8\out\build\x64-Debug\api.c.obj 1
It looks like that depending if ENABLE_OPENMP or ENABLE_THREADS are enabled additional symbols would need to be exported.

@nickdademo
Copy link

@StMartin81 Seems like some of the recent changes have broken the build for me. I'm getting errors that fftw3.h cannot be found. I assume the build is fine for you? What options are you using?

@StMartin81
Copy link
Author

StMartin81 commented Jun 18, 2020 via email

@jcelerier
Copy link

Hello,
regarding the "Only export symbols when building FFTW as shared library", this would break some workflows - for instance I'm building a static fftw but still need its symbols exported (because I'm dlopen'ing things that need the fftw symbols which are provided by my main executable)

@StMartin81
Copy link
Author

I have deleted my branch as I don't have the time to work on it. I guess it would need a lot of work to refactor the build system so that it's not intermingled (I would imagine a script which auto generates the needed files and a CMake script file for the actual build process).

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.

4 participants