[CMake] Target visibility in CMake using Xcode generator

Manuel Holtgrewe manuel.holtgrewe at fu-berlin.de
Sat Apr 9 12:32:52 EDT 2011


> There're two spots in your A/CMakeLists.txt catching my eye,  
> although I
> doubt that they are actually causing the difficulties you report on:
>
> 1) The DEPENDS clause of ADD_CUSTOM_TARGET() is meant for file-level
>   dependencies only, i.e. you shouldn't denote a target as target_aa
>   but files and particularly OUTPUTs of custom commands as target_ab
>   after that clause. Instead, you should use ADD_DEPENDENCIES() to
>   establish a dependency of target_a on target_aa.
> 2) When dealing with custom commands' OUTPUTs, it's best to specify
>   full paths since it is hardly documented how relative paths are
>   interpreted, i.e. relative to the source directory or the build
>   tree. AFAIK, it's ADD_CUSTOM_COMMAND(OUTPUT ...) only that - in
>   a documented manner - interprets a relative OUTPUT path w.r.t.
>   to CMAKE_CURRENT_BINARY_DIR.
>
> Having said that, with a Makefile generator, your projects A and B
> indeed work as one would usually expect, despite the limitation of
> the ADD_CUSTOM_TARGET() command's DEPENDS clause mentioned in the
> documentation, but perhaps, the Xcode generator or Xcode itself
> is pickier.

I changed the CMakeLists.txt files as can bee seen at the bottom of  
the email. I hope this resolves both points you described above.  
However, the problem persists.

Is this the limitation you mention: "Dependencies listed with the  
DEPENDS argument may reference files and outputs of custom commands  
created with add_custom_command() in the same directory  
(CMakeLists.txt file)."? The way I understand it, my  
"add_custom_target()" statement references only files generated in the  
same CMakeLists.txt. The documentation does not explicitely limit a  
target from another CMakeLists.txt file depending indirectly on  
generated files.

To clarify whether the problem is in Xcode or the generator, I grepped  
for target_ab in a build directory for Xcode and one for Makefiles.  
The results can also be found at the bottom of the email. As can be  
seen, target_ab does not occur in combination with target_b. I also  
grepped for "target_a" (the results are ommitted for their longness)  
and target_a does not occur in any files related to target_b either.  
So it appears that the Xcode generator does not realize that I want it  
to build target_a when building target_b in the B.xcodeproj file.

The question now is whether there is a way to tell the generator to do  
what I want. If it is not possible to do so: Would extending the  
generator to do what I want be correct or am I asking for something  
that should not be supported?

Bests,
Manuel

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(A)
add_executable(target_aa target_aa.cpp)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/target_ab  
COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/target_ab)
add_custom_target(target_a DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ 
target_ab)
add_dependencies(target_a target_aa)
add_subdirectory(B)

$ cat B/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(B)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(target_b target_b.cpp)
add_dependencies(target_b target_a)

Makefiles $ grep -Ri target_ab .
./B/CMakeFiles/target_b.dir/CXX.includecache:../target_ab
./B/CMakeFiles/target_b.dir/CXX.includecache:/Users/manuel/Development/ 
Sandbox/CMakeSandbox/A/B/../target_ab
./B/CMakeFiles/target_b.dir/CXX.includecache:B/../target_ab
./B/CMakeFiles/target_b.dir/depend.internal: B/../target_ab
./B/CMakeFiles/target_b.dir/depend.make:B/CMakeFiles/target_b.dir/ 
target_b.cpp.o: B/../target_ab
./CMakeFiles/CMakeRuleHashes.txt:eb772089b1414de60dae83cdf775c8ef  
target_ab
./CMakeFiles/target_a.dir/build.make:CMakeFiles/target_a: target_ab
./CMakeFiles/target_a.dir/build.make:target_ab:
./CMakeFiles/target_a.dir/build.make:	@$(CMAKE_COMMAND) -E  
cmake_echo_color --switch=$(COLOR) --blue --bold "Generating target_ab"
./CMakeFiles/target_a.dir/build.make:	touch target_ab
./CMakeFiles/target_a.dir/build.make:target_a: target_ab
./CMakeFiles/target_a.dir/cmake_clean.cmake:  "target_ab"

Xcode $ grep -Ri target_ab .
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeDebug:	/Users/manuel/ 
Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeDebug:/Users/manuel/ 
Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab:
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeDebug:	touch target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeMinSizeRel:	/Users/ 
manuel/Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeMinSizeRel:/Users/ 
manuel/Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab:
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeMinSizeRel:	touch  
target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelease:	/Users/ 
manuel/Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelease:/Users/manuel/ 
Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab:
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelease:	touch  
target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelWithDebInfo:	/ 
Users/manuel/Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelWithDebInfo:/Users/ 
manuel/Development/Sandbox/CMakeSandbox/A-build/Xcode/target_ab:
./CMakeScripts/target_a_cmakeRulesBuildPhase.makeRelWithDebInfo:	touch  
target_ab



More information about the CMake mailing list