[CMake] Target visibility in CMake using Xcode generator

Michael Hertling mhertling at online.de
Sat Apr 9 10:44:13 EDT 2011


On 04/09/2011 01:43 PM, Manuel Holtgrewe wrote:
> Dear all,
> 
> I have an issue with the Xcode generator and the visibility of targets  
> in the generated project files. The problem is that in the project  
> files generated in subdirectories, targets from the directories above  
> are not visible.
> 
> At the bottom of the email, you can see the project structure and code  
> files. The setup is as follows: A is the project root, B is a  
> subdirectory, each directory contains a CMakeLists.txt.
> 
> A/CMakeLists.txt creates a target target_a and a custom command that  
> creates a file target_ab by touching it. target_a depends on the file  
> target_ab and thus when target_a is built, the file is created. B/ 
> CMakeLists.txt contains a target for an executable target_b that  
> depends on target_a and includes the generated file A/target_ab.
> 
> Thus, when generate Makefiles, I can type "make target_b" and this  
> will automatically build target_a and create file target_ab. This  
> works in a clean out-of-source build directory both from directories  
> the root and subdirectory "B".
> 
> I then generate an Xcode project in an out-of-source build. I can  
> build target_b without any problems from the A.xcodeproj. This will  
> also create file target_ab. However, when I start with a clean build  
> directory, generate XCode project, open B/B.xcodeproj and try to build  
> target_b, then target_a does not appear in the target list, target_b  
> thus does not depend on it (I guess) and subsequently, the file  
> target_ab is not generated!
> 
> Is this behaviour desired/expected? Given that the Makefiles generator  
> works fine for my use case, I would expect that target_a is also  
> visible in B.xcodeproj. I would expect that either all targets should  
> be visible the generated projects in subdirectories or at least the  
> targets required to build the subdirectories.
> 
> Bests,
> Manuel
> 
> $ tree A
> A
> ├── B
> │   ├── CMakeLists.txt
> │   └── target_b.cpp
> ├── CMakeLists.txt
> └── target_aa.cpp
> 
> 1 directory, 4 files
> 
> $ cat A/target_aa.cpp
> int main(int argc, char **argv)
> {
>      return 0;
> }
> 
> $ cat A/B/target_b.cpp
> #include "../target_ab"
> 
> int main(int argc, char **argv)
> {
>      return 0;
> }
> 
> $ cat A/CMakeLists.txt
> cmake_minimum_required(VERSION 2.8)
> project(A)
> add_executable(target_aa target_aa.cpp)
> add_custom_command(OUTPUT target_ab COMMAND touch target_ab)
> add_custom_target(target_a DEPENDS target_aa target_ab)
> add_subdirectory(B)
> 
> $ cat A/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)

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.

Regards,

Michael


More information about the CMake mailing list