View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015885CMakeCMakepublic2015-12-16 05:222016-05-02 08:30
ReporterPavel Solodovnikov 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionno change required 
PlatformOSWindowsOS Version
Product VersionCMake 3.4.1 
Target VersionFixed in Version 
Summary0015885: Ninja always relinks libraries that doesn't export any symbols (on Windows)
DescriptionConsider 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".
Steps To Reproduce1) 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)
Additional InformationIt'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.
TagsNo tags attached.
Attached Fileszip file icon cmake_relink_test.zip [^] (615 bytes) 2015-12-16 05:22

 Relationships

  Notes
(0039990)
James Johnston (developer)
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 (reporter)
2015-12-17 01:40

Yes, this is an acceptable workaround, thanks for quick response.
(0040988)
Robert Maynard (manager)
2016-05-02 08:30

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2015-12-16 05:22 Pavel Solodovnikov New Issue
2015-12-16 05:22 Pavel Solodovnikov File Added: cmake_relink_test.zip
2015-12-16 09:42 James Johnston Note Added: 0039990
2015-12-17 01:40 Pavel Solodovnikov Note Added: 0039992
2015-12-17 08:50 Brad King Status new => resolved
2015-12-17 08:50 Brad King Resolution open => no change required
2016-05-02 08:30 Robert Maynard Note Added: 0040988
2016-05-02 08:30 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team