[CMake] add_subdirectory inheritance

irukandji irukandji at voidptr.eu
Tue Apr 17 18:02:03 EDT 2012


Hi,

Maybe i can try to reexplain, from head, ignore syntactic errors and 
oversimplifying...
**********************************
/sources/cmakelist.txt

/sources/binaries/helloworld
..................cmakelists.txt

/sources/binaries/hellocmake
..................cmakelists.txt

/sources/libraries/stdio
..................cmakelists.txt
..................description.txt

/sources/libraries/gfx
..................cmakelists.txt
..................description.txt
**********************************
>> helloworld: <<
project(helloworld)
include("${libs}/stdio/description.txt")
include("${libs}/network/description.txt")
file(glob da_files "*.*")
add_executable( helloworld da_files )
helper_add_stdio()
**********************************
>> stdio description <<
function (helper_add_stdio)
include_directory( "${sources}/libraries/stdio" )
target_add_library( ${CMAKE_PROJECT_NAME} 
"${BINDIR}/whatever/stdio.lib" )
add_definition( -DUSING_STDIO )
...
execute(grab_me_a_beer_and_add_some_more_flags)
...
if(not exists "${BINDIR}/whatever/stdio.lib")
add_subdirectory( "/sources/libraries/stdio")
endif()
endfunction()
**********************************
>> hellocmake <<
project(hellocmake)
include("${libs}/gfx/description.txt")
include("${libs}/network/description.txt")
file(glob da_files "*.*")
add_executable( hellocmake da_files )
helper_add_gfx()
helper_add_stdio()
**********************************
>> gfx description <<
function (helper_add_gfx)
include_directory( "${sources}/libraries/gfx" )
target_add_library( ${CMAKE_PROJECT_NAME} "${BINDIR}/whatever/gfx.lib" 
)
add_definition( -DUSING_GFX )
...
if(not exists "${BINDIR}/whatever/gfx.lib")
add_subdirectory( "${sources}/libraries/gfx" 
"${BINDIR}/whatever/gfx.lib" )
endif()
endfunction()
**********************************
>> sources/cmakelist.txt <<
add_subdirectory( "/sources/binaries/helloworld" )
add_subdirectory( "/sources/binaries/hellocmake" )
**********************************

* If i run cmake on helloworld, lets say for windows, i get solution 
and vcprojs
of helloworld with dependancy to generated vcproj for stdio. Stand 
alone.

* If i run cmake on hellocmake, lets say for windows, i get solution 
and vcprojs
of hellocmake with dependancy to generated vcproj for stdio and gfx. 
Stand alone.

* If i run cmake on /sources/cmakelist.txt i get full build.

* The author(s) of helloworld doesnt need to have a clue about stdio 
library its paths
or whatever as the author(s) of stdio/description.txt has prepared 
everything for him
(in a perfect world :) ). Same goes for hellocmake.

* The full build doesnt need to understand what is behind the 
helloworld and hellocmake as
they both will take care about building the dependancies on their own.

* The coupling is minimized.

* The description.txt can serve as a hook in case of changing whatever 
settings for
the libraries (from renaming them, to changing directory tree, changing 
compiler flags etc)

This is what i would like to achieve. But if you look at >> hellocmake 
<<, the
stdio cmakelists will inherit the include path from gfx library which 
you really
dont want. It will also inherit -DUSING_GFX even if it has nothing to 
do with it.

Regards,
irukandji


On 2012-04-17 22:56, irukandji wrote:
>> I don't know how you'd ever maintain a sane overall project if it
>> depends on each subdirectory having conflicting compiler flags.
>
> Well here is the fun, there is not something like "you", we are 
> taling about
> over 100 developers and if everyone is handling his own garden, this 
> is not
> a problem. I cant tell you the details (the lawyers stuff) but 
> believe me it
> is as sane as it can be in regards of doing insane things :)
>
> I'll check your suggestions tomorrow, thank you.
>
> Regards,
> irukandji
>
> On 2012-04-17 20:54, Kent Williams wrote:
>> I think then that you shouldn't use add_subdirectory.
>>
>> I'd suggest using the ExternalProject module in this case, because 
>> it
>> uncouples the subdirectory's project from the parent project.  In 
>> that
>> case, each subdirectory can be its own project and maintain private
>> configurations.
>>
>> You can manage dependencies between ExternalProjects with the 
>> DEPENDS
>> keyword.
>>
>> I think that what you're describing doesn't really make any sense to
>> me.  I don't know how you'd ever maintain a sane overall project if 
>> it
>> depends on each subdirectory having conflicting compiler flags.
>>
>> Another way you can manage this sort of thing is to use Source file
>> properties -- see SET_SOURCE_FILE_PROPERTIES in the CMake
>> documentation and the "Properties on Source Files" section as well.
>>
>>
>> On Tue, Apr 17, 2012 at 1:27 PM, irukandji <irukandji at voidptr.eu> 
>> wrote:
>>> Oh, hi :)
>>>
>>> Well, the add_subdirectory takes all the preprocessor defines and
>>> include/library
>>> paths defined before calling it into the added "subdirectory"
>>> cmakelists.txt.
>>>
>>> If cmakelists.txt A defines -DWhatever and calls 
>>> add_subdirectory(/B) where
>>> the
>>> cmakelists.txt for building library B resides then the library B is 
>>> going to
>>> be
>>> built with -DWhatever. This is probably great behaviour for some 
>>> cases but
>>> can
>>> also be undesired:
>>> in my case, each library has its own description file, residing in 
>>> same
>>> directory
>>> as its cmakelists.txt, with only one function, which is included 
>>> and called
>>> with few
>>> parameters to specify runtime etc. by each binary which has a 
>>> dependancy to
>>> library.
>>> The description file function sets the -I to itself for caller, the 
>>> -l to
>>> its output
>>> and, if the output file is not found, also calls add_subdirectory 
>>> on its own
>>> directory.
>>>
>>> This is a perfect situation for developers as we can just do out of 
>>> source
>>> configuration
>>> for whatever directory (where project resides) and only the 
>>> dependancy tree
>>> for that
>>> particular binary is built.
>>>
>>> It also brings additional benefit that the team which takes care 
>>> about
>>> specific
>>> library also takes care for description file and needed defines 
>>> which splits
>>> the
>>> ownership of projects and also presents a single point of inclusion 
>>> for that
>>> particular
>>> library, meaning only one file has to be changed for library
>>> specializations.
>>>
>>> For the nightly builds, only executables are added to the build 
>>> while
>>> everything
>>> else is built only if actually used.
>>>
>>> It works great, but the add_subdirectory is propagating the 
>>> settings from
>>> executable
>>> to dependant libraries and messes the build.
>>>
>>> The question actually is: can i workaround this behaviour and if 
>>> not, can
>>> you please
>>> include the parameter to add_subdirectory function to NOT propagate 
>>> the
>>> settings.
>>>
>>> Regards,
>>> Irukandji
>>>
>>>
>>> On 2012-04-17 17:58, Kent Williams wrote:
>>>>
>>>> Frankly, I don't entirely understand what the problem is, or what 
>>>> your
>>>> proposed solution is.
>>>>
>>>> What is it that you don't want the subdirectory context to 
>>>> inherit?
>>>>
>>>> On Tue, Apr 17, 2012 at 10:30 AM, irukandji <irukandji at voidptr.eu> 
>>>> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> (as no one answered to my previous email, let me add this: 
>>>>> multiplatform
>>>>> project with few million lines
>>>>> of code, sheer size of the project is not allowing to turn around 
>>>>> whole
>>>>> directory tree as price / performance
>>>>> is a very relevant factor and even rewriting makefiles/vcprojs to 
>>>>> cmake
>>>>> will
>>>>> take months)
>>>>>
>>>>> The add_subdirectory inheritance striked which is practically a 
>>>>> show
>>>>> stopper, it was already discussed here
>>>>> http://www.mail-archive.com/cmake@cmake.org/msg34291.html What 
>>>>> was
>>>>> proposed
>>>>> (DONT_INHERIT) was a great idea
>>>>> and improvement to versability of CMake and also harmless for 
>>>>> backward
>>>>> compatibility so i dont really
>>>>> understand why forcing subproject to inherit all the settings.
>>>>>
>>>>> Yes, what is added with add_subdirectory is not a child but a 
>>>>> sibling or
>>>>> even some other part of the tree
>>>>> but the point is that it doesnt stop the cmake from building it 
>>>>> correctly
>>>>> but this inheritance is a problem
>>>>> as it adds include directories to wrong versions of headers in 
>>>>> public
>>>>> libs
>>>>> (due to bugs in different versions,
>>>>> affecting different platforms,... the unification is impossible), 
>>>>> the
>>>>> flags
>>>>> are used on wrong places etc.
>>>>>
>>>>> Is there a way to workaround it?
>>>>>
>>>>> Thank you.
>>>>>
>>>>> --
>>>>>
>>>>> Powered by www.kitware.com
>>>>>
>>>>> Visit other Kitware open-source projects at
>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>
>>>>> Please keep messages on-topic and check the CMake FAQ at:
>>>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>>>
>>>>> Follow this link to subscribe/unsubscribe:
>>>>> http://www.cmake.org/mailman/listinfo/cmake
>>>
>>>
>>> --
>>>
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Please keep messages on-topic and check the CMake FAQ at:
>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.cmake.org/mailman/listinfo/cmake
>
> --
>
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake



More information about the CMake mailing list