[cmake-developers] ExternalProject: using the same argument multiple times

Alexander Neundorf neundorf at kde.org
Thu Jun 16 13:39:19 EDT 2011


On Monday 13 June 2011, David Cole wrote:
> It is unexpected (and user/pilot error, if encountered) to have
> multiple INSTALL_DIR arguments to ExternalProject_Add.
> 
> Why do you have to override the function in order to achieve your goal?

I'm working on this:
https://projects.kde.org/projects/kde/superbuild

With the move to git, KDE is splitting into much smaller repositories, which 
makes it much harder to to build (since it's so many things now).

So, I'm setting up CMakeLists.txt to create builds like we had with the old 
big KDE modules, e.g. kdegraphics.

The CMakeLists.txt for this is here:
https://projects.kde.org/projects/kde/superbuild/repository/entry/kdegraphics/CMakeLists.txt?rev=master

sb_add_project() wraps externalproject_add():
https://projects.kde.org/projects/kde/superbuild/repository/entry/SuperBuild.cmake?rev=master

The wrapper does mainly these 3 things:

* it sets up the directories to nice (IMO) default locations
This works quite nice with the  EP_BASE  directory property, but I wouldn't be 
surprised if KDE developers will want to have "src" and "build" instead of 
"Source" and "Build".

* it takes care of e.g. CMAKE_PREFIX_PATH, so projects which use earlier 
projects will find them


* it has special handling for the "DEPENDS" argument:
It checks each of the given dependencies, whether such a target exists, and if 
it doesn't, it prints a warning but does not pass this dependency to 
externalproject_add(). So the developer can decide whether he wants to use a 
dependency from within the superbuild or whether the dependency should be 
found somewhere in the system.


* it offers two modes:
once the "native" mode, where the sources are actually downloaded from git, 
and additionally a source-package mode. In the "native" mode, if you do "make 
package", the created package contains just the sources of all subprojects, 
nothing is built. This is useful e.g. for packagers, who must not access the 
network for creating packages, but who also don't want to fiddle around with 
the many small repositories. So these can do "make UpdateAll", which only 
executes the download step for the subprojects, and then "make package", to 
create a package from these sources.
When unpacking this source package then somewhere, the sb_add_project() then 
detects that it is being used inside such a source package and should not 
download anything. So it has to catch the GIT_REPOSITORY etc. arguments and 
replace them for externalproject_add() with a SOURCE_DIR argument.


So, for these last two features I need to modify the arguments I got and how 
to give them to externalproject_add().

Right now I parse them, and figure out what to do with them. This results in 
relatively much code.

E.g. the overriding of the GIT_REPOSITORY argument could be done by appending 
it again, but empty, to the list of arguments for externalproject_add().
OTOH, the "append"-feature is also nice, if it was changed to "set" instead, 
append would still be nice to have.
So I could do
sb_add_project(...
               CMAKE_ARGS APPEND -DSOMETHING=foo
              ... )

etc., which will be necessary for some projects.



Or instead, maybe, externalproject_add() could provide something like a hook 
where I could hook in ?
Maybe directly after having parsed the arguments, when the target properties 
have been created, at the end of _ep_parse_arguments():

if(EXTERNALPROJECT_USER_HOOK)
  externalproject_user_hook_function(${targetname})
endif()


and in Superbuild.cmake I would have to set EXTERNALPROJECT_USER_HOOK to TRUE 
and implement a function or macro externalproject_user_hook_function().

In this function I could check the already parsed arguments (now as target 
properties), and modify them. E.g. make GIT_REPOSITORY empty again. Or remove 
some of the DEPENDS targets.



Other ideas ?
Or parse the arguments completely and manipulate them ? Possible, but it will 
become somewhat slow, and I will have to basically parse all possible 
arguments of externalproject_add(), and handle them, which is quite a lot. So 
I#d like to avoid this.

Alex



More information about the cmake-developers mailing list