I'm a bit puzzled by the way that CMake deals with library linking on Windows machine. Below I have a simple CMakeLists.txt
file:
cmake_minimum_required (VERSION 3.10)
project (sample)
add_library (quad SHARED quad.cpp)
add_executable (run main.cpp)
target_link_libraries (run PRIVATE quad)
On a Linux/Mac machine, CMake correctly builds the *.so/*.dylib libraries and links the executable against the *.so/*.dylib files. However on a Windows machine it builds the *.dll file and then attempts to link against a *.lib file.
Underneath the hood CMake executes the following command:
>------ Build started: Project: CMakeLists, Configuration: Debug ------
[1/4] C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\HostX64\x64\cl.exe /nologo /TP -Dquad_EXPORTS /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\quad.dir\quad.cpp.obj /FdCMakeFiles\quad.dir\ /FS -c C:\Users\UX\Workspace\sample\quad.cpp
[2/4] C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\HostX64\x64\cl.exe /nologo /TP /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoCMakeFiles\run.dir\main.cpp.obj /FdCMakeFiles\run.dir\ /FS -c C:\Users\UX\Workspace\sample\main.cpp
[3/4] cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_dll --intdir=CMakeFiles\quad.dir --manifests -- C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\Hostx64\x64\link.exe /nologo CMakeFiles\quad.dir\quad.cpp.obj /out:quad.dll /implib:quad.lib /pdb:quad.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
[4/4] cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\run.dir --manifests -- C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\Hostx64\x64\link.exe /nologo CMakeFiles\run.dir\main.cpp.obj /out:run.exe /implib:run.lib /pdb:run.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console quad.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
FAILED: run.exe
cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\run.dir --manifests -- C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\Hostx64\x64\link.exe /nologo CMakeFiles\run.dir\main.cpp.obj /out:run.exe /implib:run.lib /pdb:run.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console quad.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~1\2017\COMMUN~1\VC\Tools\MSVC\1415~1.267\bin\Hostx64\x64\link.exe /nologo CMakeFiles\run.dir\main.cpp.obj /out:run.exe /implib:run.lib /pdb:run.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console quad.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\run.dir/intermediate.manifest CMakeFiles\run.dir/manifest.res" failed (exit code 1104) with the following output:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\LINK : fatal error LNK1104: cannot open file 'quad.lib'
ninja: build stopped: subcommand failed.
Build failed.
My question is why does it fail on Windows when the CMake documentation states the following:
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
Where item
can be A library target name
? Shouldn't it have enough information from the target
's properties to identify the full path to the compiled library as well as its type (i.e. SHARED
) to be able to properly link the executable?