MantisBT - CMake
View Issue Details
0015757CMakeCMakepublic2015-09-23 05:282016-02-01 09:10
Pavel Solodovnikov 
Brad King 
highmajoralways
closedfixed 
x86Microsoft WindowsWindows 7
CMake 3.2 
CMake 3.4CMake 3.4 
0015757: Including a project from parent subdirectory causes CMake to produce wrong build files for Ninja generator
Suppose we have following project structure:

testing_ninja/
--- mylib1/
------ CMakeLists.txt
------ src.cpp
--- mylib2/
------ CMakeLists.txt
------ src.cpp

CMakeLists.txt for mylib1 creates a library mylib1.dll, which exports some symbols needed by mylib2, so mylib2 depends on mylib1 ( via target_link_libraries(mylib2 mylib1) ). If mylib1 CMakelists.txt contains following line, which includes mylib2 project:

add_subdirectory("../mylib2" "../mylib2")

then if we use Ninja generator to produce build files (invoking cmake inside mylib1 directory), the generated build.ninja file contains errors.

CMake-generated build.ninja file contains mixed absolute-relative paths for mylib1.lib target which confuses ninja in such a way:

when ninja is invoked it immediately reports an error that it couldn't find mylib1.lib binary needed by mylib2 (however it should be generated at build time and ninja should not rely on its existence). Error message is as follows:

E:\testing_ninja\mylib1>ninja
ninja: error: 'E:/testing_ninja/mylib1/mylib1.lib', needed by 'E:/testing_ninja/
mylib2/mylib2.dll', missing and no known rule to make it

As I understand it happens because CMake generates a list of phony targets for each build target (expressed via relative path to target), so ninja does not need these files to exist at the beginning of build. And because CMake is mixing up relative and absolute paths in this case, ninja does not recognize phony targets anymore (they are expressed as absolute paths now) and fails. If I move mylib2 project inside mylib1 directory so the whole source tree stays inside the folder in which the root CMakeLists.txt file is placed, this behavior does not happen.

To note one important moment: this only does happen if mylib1 appears to be dynamic library, if we build static libraries instead everything is alright.

I've attached a test project to demonstrate such behavior. Tested only on Windows but I assume that it could be reproduced under the same conditions on other platforms.
1) Extract attached archive
2) Invoke cmake inside mylib1 directory with following arguments:
cmake -G "Ninja" .
No tags attached.
zip testing_ninja.zip (1,429) 2015-09-23 05:28
https://public.kitware.com/Bug/file/5533/testing_ninja.zip
Issue History
2015-09-23 05:28Pavel SolodovnikovNew Issue
2015-09-23 05:28Pavel SolodovnikovFile Added: testing_ninja.zip
2015-09-25 14:55Brad KingNote Added: 0039481
2015-09-25 14:55Brad KingAssigned To => Brad King
2015-09-25 14:55Brad KingStatusnew => resolved
2015-09-25 14:55Brad KingResolutionopen => fixed
2015-09-25 14:55Brad KingFixed in Version => CMake 3.4
2015-09-25 14:55Brad KingTarget Version => CMake 3.4
2016-02-01 09:10Robert MaynardNote Added: 0040422
2016-02-01 09:10Robert MaynardStatusresolved => closed

Notes
(0039481)
Brad King   
2015-09-25 14:55   
Thanks for the simple example. I've reproduced the issue. Here is a fix and an update to the test suite to cover the case:

 Ninja: Centralize path conversion in global generator
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6e2a4087 [^]
(0040422)
Robert Maynard   
2016-02-01 09:10   
Closing resolved issues that have not been updated in more than 4 months.