MantisBT - CMake
View Issue Details
0015775CMakeCMakepublic2015-10-07 18:342016-03-07 09:12
James Johnston 
James Johnston 
normaltextalways
closedfixed 
Windows
CMake 3.4 
CMake 3.4CMake 3.4 
0015775: Document that SHARED libraries must export at least one symbol
This is very similar to the issue reported by Nils Gladitz:
0015666: Ninja may unnecessarily relink on windows
http://public.kitware.com/Bug/view.php?id=15666 [^]

However, my test case does not work on CMake 3.4.0-rc1 either. In this situation, the issue arises when the library exports no symbols.

My test case is almost identical to the one from Nils, except notice that test.cpp is now a blank file: I don't export any symbols. If the project does not export any symbols, the linker *will not emit a LIB file at all.*

It initially sounds non-sensical, but not exporting any symbols is not as uncommon as one might think; some examples:

 * It is common that a .NET C++/CLR project will not export unmanaged symbols, as it is exporting directly through the DLL (i.e. no LIB file).
 * A DLL being used for the purpose of storing Win32 resources would not export any symbols.
 * Some 3rd-party libraries (e.g. FLANN) happily seem to link an empty library...
My test case, as you can see it's basically the same as Nils in 0015666 except no symbols:

CMakeLists.txt
--------------

# Using CMake 3.4.0-rc1 here:
cmake_minimum_required(VERSION 3.4)

project(Foo CXX)

if(NOT EXISTS test.cpp)
    # Unlike Nils, I emit no symbols at all here:
    file(WRITE test.cpp "")
endif()

add_custom_target(touch
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/test.cpp
)

add_library(foo SHARED test.cpp)

Procedure:
----------

1. Configure with Ninja from a Visual C++ 2008 command prompt. (Other VC++ versions will likely exhibit the same issue).
2. ninja # builds as expected
3. ninja # continues to build
4. ninja -d explain

ninja explain: output foo.lib doesn't exist
ninja explain: foo.dll is dirty
[1/1] Linking CXX shared library foo.dll
No tags attached.
Issue History
2015-10-07 18:34James JohnstonNew Issue
2015-10-08 02:53Nils GladitzNote Added: 0039530
2015-10-08 10:44Brad KingNote Added: 0039537
2015-10-08 12:49James JohnstonNote Added: 0039542
2015-10-08 13:03Brad KingNote Added: 0039543
2015-10-08 13:20James JohnstonNote Added: 0039545
2015-10-08 13:30Brad KingAssigned To => James Johnston
2015-10-08 13:30Brad KingSeverityminor => text
2015-10-08 13:30Brad KingStatusnew => assigned
2015-10-08 13:30Brad KingSummaryNinja will unnecessarily relink on windows if a library exports no symbols => Document that SHARED libraries must export at least one symbol
2015-10-08 13:59Brad KingNote Added: 0039546
2015-10-08 13:59Brad KingNote Added: 0039547
2015-10-08 13:59Brad KingStatusassigned => resolved
2015-10-08 13:59Brad KingResolutionopen => fixed
2015-10-08 13:59Brad KingFixed in Version => CMake 3.4
2015-10-08 13:59Brad KingTarget Version => CMake 3.4
2016-03-07 09:12Robert MaynardNote Added: 0040609
2016-03-07 09:12Robert MaynardStatusresolved => closed

Notes
(0039530)
Nils Gladitz   
2015-10-08 02:53   
I am not familiar with those use cases but a library without an import library can not be linked to any other target by cmake since what cmake presents to the linker is the import library.

Maybe the MODULE library type would be more appropriate in those cases?
It does seem to work for the test case at least.
(0039537)
Brad King   
2015-10-08 10:44   
CMake currently assumes all SHARED library DLLs have an import library because they are meant to be linked by other targets. This assumption is made by all generators, not just Ninja.

This may be more of a feature request to support at least some of the cases enumerated in the description.
(0039542)
James Johnston   
2015-10-08 12:49   
My apologizes for not learning the CMake build system better. @Nils: I think you are right; MODULE works better. I found that all problematic references to LIB files in build.ninja were removed when I used MODULE.

In fact MODULE is probably the right choice for the first two use cases:
 * The .NET runtime implements its assembly reference system by loading referenced DLLs dynamically; they are not statically linked. (Even though when setting up a .NET project.)
 * A Win32 resource DLL would also be explicitly loaded via LoadLibrary.

Perhaps for now a contribution with a documentation update clarifying this restriction would be most useful?
(0039543)
Brad King   
2015-10-08 13:03   
Re 0015775:0039542: Yes, a documentation update sounds good.
(0039545)
James Johnston   
2015-10-08 13:20   
Pushed: https://cmake.org/gitweb?p=stage/cmake.git;a=commit;h=81e01f92df657516456d036fd0a99f69410fd07e [^]

Since it's just a minor doc update, I put it on the release branch.
(0039546)
Brad King   
2015-10-08 13:59   
Thanks. I revised the wording a bit:

 Help: Document that SHARED libraries must export a symbol
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6556481e [^]

There may be problems other than just Ninja rebuilds because CMake assumes this in general.
(0039547)
Brad King   
2015-10-08 13:59   
I've queued this for merge to 'release'.
(0040609)
Robert Maynard   
2016-03-07 09:12   
Closing resolved issues that have not been updated in more than 4 months.