MantisBT - CMake
View Issue Details
0015885CMakeCMakepublic2015-12-16 05:222016-05-02 08:30
Pavel Solodovnikov 
 
normalminoralways
closedno change required 
Windows
CMake 3.4.1 
 
0015885: Ninja always relinks libraries that doesn't export any symbols (on Windows)
Consider the following test case:

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(foo CXX)
add_library(foo SHARED test.cpp)

test.cpp:

void foo()
{}


With such setup when I run cmake (cmake -G Ninja) and execute several consecutive builds, each time ninja relinks "foo" library.

If test.cpp instead contains exported symbol, for example:

__declspec( dllexport ) void foo(){}

ninja works as expected, reporting for the second build "ninja: no work to do".


The cause of the problem is that cmake generates link rule for "foo.dll" in such a way that it depends on "foo.lib" file existence:

build foo.dll foo.lib: CXX_SHARED_LIBRARY_LINKER__foo CMakeFiles\foo.dir\test.cpp.obj

If a library has no exported symbols, MSVC doesn't produce a ".lib" file for it during a build. Because of that ninja assumes it needs to relink again to produce import library for "foo.dll".
1) extract attached archive with test files (CMakeLists.txt and test.cpp).
2) run "cmake -G Ninja"
3) ninja (builds and links library)
4) ninja (should report "no work to do" but relinks the library again)
It's a windows-specific case (more specifically Windows + MSVC, I assume, at least not tested with MinGW toolchain), does not occur on linux since there is no such thing as "import library" for shared libraries.
No tags attached.
zip cmake_relink_test.zip (615) 2015-12-16 05:22
https://public.kitware.com/Bug/file/5592/*
Issue History
2015-12-16 05:22Pavel SolodovnikovNew Issue
2015-12-16 05:22Pavel SolodovnikovFile Added: cmake_relink_test.zip
2015-12-16 09:42James JohnstonNote Added: 0039990
2015-12-17 01:40Pavel SolodovnikovNote Added: 0039992
2015-12-17 08:50Brad KingStatusnew => resolved
2015-12-17 08:50Brad KingResolutionopen => no change required
2016-05-02 08:30Robert MaynardNote Added: 0040988
2016-05-02 08:30Robert MaynardStatusresolved => closed

Notes
(0039990)
James Johnston   
2015-12-16 09:42   
I ran into the same issue and found that this is basically by design. What you need to do is make a MODULE library instead of a SHARED library. Then CMake will not expect a LIB file. From the documentation patch I submitted:

"If a library does not export any symbols, it must not be declared as a SHARED library. For example, a Windows resource DLL or a managed C++/CLI DLL that exports no unmanaged symbols would need to be a MODULE library. This is because CMake expects a SHARED library to always have an associated import library on Windows."

Does this work for you?
(0039992)
Pavel Solodovnikov   
2015-12-17 01:40   
Yes, this is an acceptable workaround, thanks for quick response.
(0040988)
Robert Maynard   
2016-05-02 08:30   
Closing resolved issues that have not been updated in more than 4 months.