[CMake] add_subdirectory inheritance

irukandji irukandji at voidptr.eu
Wed Apr 18 15:07:27 EDT 2012


I appreciate the idea but my view is that if the solution (whatever 
dev. solution)
is not elegant there is something wrong with it.

While testing the posibilities, i had it, i have implemented the 
optional dont_inherit
flag to add_subdirectory. Tomorrow (some testing first), I'll submit a 
patch, i hope it
will be accepted as it is completely unintrusive, backward compatible, 
<insert the casual
buzzwords>,...

Regards,
irukandji

On 2012-04-18 18:18, Kent Williams wrote:
> I think I understand what you're trying to do better now.  It's a bit
> off the beaten path for CMake, and has more moving parts than is
> strictly necessary.
>
> It could be set up as a nested suite of ExternalProjects, and avoid
> the definitions inheritance issue you're running into.
>
> You could also manage this by having a flag that is defined if this 
> is
> a top-level build and not defined in a standalone build, and using
> Source Properties to properly set the definitions for the files that
> need different flags.
>
> The problem is that ADD_DEFINITIONS is global for the current 
> project,
>  It is also -- for that very reason -- if not a deprecated CMake
> feature, one whose use is discouraged.  You're much better off using
> SET_SOURCE_FILE_PROPERTIES to handle this kind of configuration 
> trick,
> since the properties are tied to a particular source file.  You can
> use macros and FOREACH to avoid having to call
> SET_SOURCE_FILE_PROPERTIES on every file explicitly.
>
> You have become invested in the idea that it can only be done by
> changing CMake, but you can do it without changing CMake if you get
> creative with the tools already available to you.
>
> On Tue, Apr 17, 2012 at 5:02 PM, irukandji <irukandji at voidptr.eu> 
> wrote:
>> 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
>>
>>
>> --
>>
>> 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