[CMake] add_subdirectory inheritance (patch)

irukandji irukandji at voidptr.eu
Thu Apr 19 05:04:14 EDT 2012


Ok, guys, catch... source base is 2.8.7.

add_subdirectory(source_dir [binary_dir]
                    [EXCLUDE_FROM_ALL] [NOINHERIT])


/.../

If the NOINHERIT argument is provided, the subdirectory build 
configuration
will not inherit any preprocessor, compiler or linker specific 
parameters.

Regards,
irukandji



On 2012-04-18 21:07, irukandji wrote:
> 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
>
> --
>
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch_NOINHERTI_flag.txt
Type: text/x-diff
Size: 3987 bytes
Desc: not available
URL: <http://www.cmake.org/pipermail/cmake/attachments/20120419/dfc01573/attachment.diff>


More information about the CMake mailing list