IPO,Intel,Fortran: Static libraries generated with no longer link correctly.
- CMake: 3.22.3
- Ninja: 1.10.2
- Intel: 18.0.5.274
- MSVC: 2017
This is an issue I've just experienced whilst upgrading our CMake from 3.14.4 to 3.22.3, when using Ninja (unsure if this affects any other generators).
We have some projects where various static libraries are compiled (with IPO turned on), which are then linked to a shared library containing other static-libraries or C/CXX code.
It seems that in CMake 3.21.1, a change was made, and the 'lib' tool from MSVC is used, instead of Intel's 'xilib' tool when linking the static library, which then causes an issue when linking the final shared library.
I've attached a small reproducer, which contains:
- A Fortran generated static library (with 1 subroutine)
- A shared library that contains C code, which links to the above. This also contains an export '.def' file, to export the Fortran subroutine.
The CMakeLists.txt encapsulates all of this. When the build occurs, the following is produced:
[1/2] Linking Fortran static library fortran_code.lib
f_code.f.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
[2/2] Linking C shared library test_lib.dll
FAILED: test_lib.dll test_lib.lib
cmd.exe /C "cd . && C:\BuildTools\cmake-3.22.3-windows-x86_64\bin\cmake.exe -E vs_link_dll --intdir=CMakeFiles\test_lib.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\mt.exe --manifests -- C:\PROGRA~2\MICROS~2\2017\PROFES~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo CMakeFiles\test_lib.dir\c_code.c.obj /out:test_lib.dll /implib:test_lib.lib /pdb:test_lib.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL /DEF:C:\workspaces\temp\fortran-static-lib-bug\exports.def /DEF:..\exports.def fortran_code.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2017\PROFES~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo CMakeFiles\test_lib.dir\c_code.c.obj /out:test_lib.dll /implib:test_lib.lib /pdb:test_lib.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL /DEF:C:\workspaces\temp\fortran-static-lib-bug\exports.def /DEF:..\exports.def fortran_code.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\test_lib.dir/intermediate.manifest CMakeFiles\test_lib.dir/manifest.res" failed (exit code 1120) with the following output:
exports.def : error LNK2001: unresolved external symbol vmake_name_
test_lib.lib : fatal error LNK1120: 1 unresolved externals
ninja: build stopped: subcommand failed.
I've left some commented code in the CMakeLists.txt, which re-enables the use of 'xilib' via the 'CMAKE_Fortran_CREATE_STATIC_LIBRARY' variable. When this is uncommented, everything works as expected (and you can use 'dumpbin /EXPORTS' to see that all the functions are exported as expected).