On 04/09/2011 06:32 PM, Manuel Holtgrewe wrote: >> 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)."? [...]
Yes, in connection with "Use ADD_DEPENDENCIES to add dependencies *to* or from other targets." from ADD_CUSTOM_TARGET()'s documentation, too. > [...] The way I understand it, my > "add_custom_target()" statement references only files generated in the > same CMakeLists.txt. [...] You might set the [RUNTIME_]OUTPUT_NAME property of your target_aa, and on Windows, the target's default output is named target_aa.exe, i.e. you cannot rely on your target_aa to produce an equally named output file. Hence, if you have a "DEPENDS target_aa" clause for a custom target, CMake would need to know that "target_aa" refers to a logical target instead of an ordinary file, and this exceeds the documented limitation. However, as stated previously, it seems to work anyway - even with a RUNTIME_OUTPUT_NAME set to an arbitrary value - so perhaps a CMake developer could tell us whether that limitation is to be taken seriously or if it's overly strict. > [...] The documentation does not explicitely limit a > target from another CMakeLists.txt file depending indirectly on > generated files. Absolutely, but this indirect dependency must be conveyed by a custom target as you've correctly done in your CMakeLists.txt. > 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. [...] This is expected since target_ab - as a custom command's OUTPUT - can not be referenced from another CMakeLists.txt file, in particular not target_b's CMakeLists.txt. The crucial line for target_ab is rather: ./CMakeFiles/target_a.dir/build.make:target_a: target_ab Nevertheless, after the first build, CMake's dependency scanner for Makefiles has recognized the file-level dependency of target_b on target_ab due to the "#include" statement as can be seen in ./B/CMakeFiles/target_b.dir/depend.make: > B/CMakeFiles/target_b.dir/target_b.cpp.o: B/../target_ab I.e. target_b gets rebuilt when the file "target_ab" has changed. > [...] 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. No, the related line for the Makefiles is in ./CMakeFiles/Makefile2: > B/CMakeFiles/target_b.dir/all: CMakeFiles/target_a.dir/all The dependency chain for target_b is mainly the following: > target_b built from top-level Makefile > builds target_b in CMakeFiles/Makefile2 > depends on B/CMakeFiles/target_b.dir/rule > builds B/CMakeFiles/target_b.dir/all in CMakeFiles/Makefile2 > (1) depends on CMakeFiles/target_a.dir/all > (1.1) depends on CMakeFiles/target_aa.dir/all > builds CMakeFiles/target_aa.dir/build in > CMakeFiles/target_aa.dir/build.make > depends on target_aa > depends on CMakeFiles/target_aa.dir/target_aa.cpp.o > depends on ../target_aa.cpp > (COMPILE) > (1.2) builds CMakeFiles/target_a.dir/build in > CMakeFiles/target_a.dir/build.make > depends on target_a > depends on target_ab > (TOUCH) > (2) builds B/CMakeFiles/target_b.dir/build in > B/CMakeFiles/target_b.dir/build.make > depends on B/target_b > depends on B/CMakeFiles/target_b.dir/target_b.cpp.o > depends on ../B/target_b.cpp > (COMPILE) Starting from directory B, target_b's dependencies originate as > target_b built from B/Makefile > depends on B/CMakeFiles/target_b.dir/rule > builds B/CMakeFiles/target_b.dir/rule in CMakeFiles/Makefile2 so the remaining dependency chain is the same as the above-noted one. > 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. While this works with Makefiles, I could imagine that the Xcode generator doesn't allow to build a (sub)project from within its directory if there're references to the parent project, especially targets. Since I don't have access to an Xcode installation at the moment, I cannot investigate this issue in further detail. BTW, is there a problem/badness/disadvantage to build target_b within the parent project, i.e. from A.xcodeproj? Regards, Michael > 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 _______________________________________________ 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