[CMake] How to depend on an ExternalProject

Michael Hertling mhertling at online.de
Fri Oct 8 11:28:26 EDT 2010


On 10/08/2010 12:50 PM, Michael Wild wrote:
> 
> On 8. Oct, 2010, at 12:13 , Rolf Eike Beer wrote:
> 
>>>
>>> On 8. Oct, 2010, at 10:50 , Rolf Eike Beer wrote:
>>>
>>>> Hi,
>>>>
>>>> I have a problem with ExternalProject and how to depend on that. I'm not
>>>> absolutely sure I got the CMakeLists.txt right, so I first ask here
>>>> before
>>>> filing a bug report.
>>>>
>>>> The idea is like this: we have an project that generates a couple of
>>>> files. In a special configuration of another project we need those files
>>>> as input for a special build step. Those step will take those files,
>>>> mangle them and will generate a source file at the end. This is then
>>>> added
>>>> as usual to a library (in my example below to a executable, but that
>>>> doesn't matter). When I run the example below I get:
>>>>
>>>> [ 80%] Built target Subdir_Build
>>>> make[2]: *** No rule to make target `Subdir_Build', needed by `main.c'.
>>>> Stop.
>>
>> [...]
>>
>>> Subdir_Build is a top-level target, and the custom-command can only depend
>>> on files. You need to add a custom target that depends on main.c and then
>>> add a dependency of that custom target on Subdir_Build.
>>
>> The documentation of add_custom_command has this sentence:
>>
>> If DEPENDS specifies any target (created by an ADD_* command) a
>> target-level dependency is created to make sure the target is built
>> before any target using this custom command.
>>
>> So if I can't depend on a target this is extremely confusing. Even worse:
>> the dependency itself _works_, i.e. Subdir_Build always get's properly
>> build before the depending target. But even then depending target fails.
>>
>> Eike
> 
> Does it work with the custom target? Because that's how it works for me. But I agree that either the documentation is wrong or there is a bug...

AFAIK, the external project is incorporated as a custom target, and
custom targets are not suited as prerequisites of a custom command's
output whereas ordinary targets, i.e. executables and libraries, are:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(CUSTOMDEPENDS C)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
ADD_CUSTOM_TARGET(t ${CMAKE_COMMAND} -E echo "Building custom target t")
ADD_CUSTOM_COMMAND(
    OUTPUT timestamp1
    COMMAND ${CMAKE_COMMAND} -E touch timestamp1
    DEPENDS f
)
ADD_CUSTOM_COMMAND(
    OUTPUT timestamp2
    COMMAND ${CMAKE_COMMAND} -E touch timestamp2
    DEPENDS t
)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main1 EXCLUDE_FROM_ALL main.c timestamp1)
ADD_EXECUTABLE(main2 EXCLUDE_FROM_ALL main.c timestamp2)

On *nix, I can see main1 getting built, and it gets rebuilt along f and
timestamp1 if f.c is touched. In contrast, building main2 fails due to
the missing rule for the custom target t although t can be built on the
direct way. Of course, you can succeed with an additional custom target
in junction with explicitly declared dependencies, but IMO, too, this
shortcoming of custom targets w.r.t. custom commands should be
mentioned in the documentation - or considered as a bug.

Recently, IIRC, I've seen a similar configuration work with a custom
target declared in another CMakeLists.txt as the one containing the
depending custom command, but currently, I can't reproduce it. :(
Perhaps, the CMake developers can give us a hint in this matter.

Regards,

Michael


More information about the CMake mailing list