View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015757CMakeCMakepublic2015-09-23 05:282016-02-01 09:10
ReporterPavel Solodovnikov 
Assigned ToBrad King 
PriorityhighSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
Platformx86OSMicrosoft WindowsOS VersionWindows 7
Product VersionCMake 3.2 
Target VersionCMake 3.4Fixed in VersionCMake 3.4 
Summary0015757: Including a project from parent subdirectory causes CMake to produce wrong build files for Ninja generator
DescriptionSuppose 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.
Steps To Reproduce1) Extract attached archive
2) Invoke cmake inside mylib1 directory with following arguments:
cmake -G "Ninja" .
TagsNo tags attached.
Attached Fileszip file icon testing_ninja.zip [^] (1,429 bytes) 2015-09-23 05:28

 Relationships

  Notes
(0039481)
Brad King (manager)
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 (manager)
2016-02-01 09:10

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

 Issue History
Date Modified Username Field Change
2015-09-23 05:28 Pavel Solodovnikov New Issue
2015-09-23 05:28 Pavel Solodovnikov File Added: testing_ninja.zip
2015-09-25 14:55 Brad King Note Added: 0039481
2015-09-25 14:55 Brad King Assigned To => Brad King
2015-09-25 14:55 Brad King Status new => resolved
2015-09-25 14:55 Brad King Resolution open => fixed
2015-09-25 14:55 Brad King Fixed in Version => CMake 3.4
2015-09-25 14:55 Brad King Target Version => CMake 3.4
2016-02-01 09:10 Robert Maynard Note Added: 0040422
2016-02-01 09:10 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team