MantisBT - CMake
View Issue Details
0006348CMakeCMakepublic2008-02-14 15:162016-06-10 14:30
Alex Neundorf 
Kitware Robot 
normalfeaturealways
closedmoved 
 
 
0006348: custom global targets (targets which when built from the root build all targets with the same name in subdirs)
In cmake targets must have unique names.
Nevertheless in cmake 2.4 it was possible to use ADD_CUSTOM_TARGET() in multiple directories with the same target name.
I know this wasn't officially supported and I don't know what happened with the XCode and the MSVC generators, but with makefiles this was a nice feature. The target name was even propagated up to the CMAKE_BUILD_DIR and when you built that target there all the targets with the same name in all subdirectories were built.
This was really useful, e.g. if you wanted to fun doxygen in multiple directories, or a custom clean command (because you can't make the clean target depend on other targets) or in general do the same in several subdirectories.

Now this doesn't work anymore and cmake gives an error message which explains what happened. It is also possible to set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 to get it working again, but I'd prefer not to do this because otherwise I'd like to use all the current features. (actually it would be also a good thing to document which effects setting CMAKE_BACKWARDS_COMPATIBILITY exactly has).

Anyway, this was a really nice feature, can this be made working somehow again ?
I.e. allow multiple targets with the same name if they are all custom targets and make this an officially supported feature, which officially behaves like it did in 2.4

A testcase is attached, it has the target "doxy" twice. If you "make doxy" in CMAKE_BUILD_DIR doxy in both subdirectories is "built". With cvs it fails.
No tags attached.
related to 0008438closed Kitware Robot add_dependencies() for "build-in cmake targets" 
related to 0012960closed Nils Gladitz CMake should reject targets with reserved names like "test" 
related to 0012961closed Kitware Robot CMAKE_INSTALL_BEHAVIOR and allowing users to run INSTALL under Visual Studio by default 
gz multipletargets.tar.gz (372) 2008-02-14 15:16
https://public.kitware.com/Bug/file/1312/multipletargets.tar.gz
Issue History
2008-02-14 15:16Alex NeundorfNew Issue
2008-02-14 15:16Alex NeundorfFile Added: multipletargets.tar.gz
2008-02-14 15:19Bill HoffmanStatusnew => assigned
2008-02-14 15:19Bill HoffmanAssigned To => Brad King
2008-02-14 15:51Brad KingNote Added: 0010501
2008-02-14 15:52Brad KingNote Added: 0010502
2008-02-14 16:43Brad KingStatusassigned => closed
2008-02-14 16:43Brad KingNote Added: 0010503
2008-02-14 16:43Brad KingResolutionopen => fixed
2008-02-14 16:48Alex NeundorfStatusclosed => feedback
2008-02-14 16:48Alex NeundorfResolutionfixed => reopened
2008-02-14 16:48Alex NeundorfNote Added: 0010504
2008-02-14 17:14Brad KingNote Added: 0010505
2008-02-14 17:19Brad KingNote Added: 0010506
2008-02-14 17:43Alex NeundorfNote Added: 0010507
2008-02-14 17:45Alex NeundorfNote Added: 0010508
2008-02-14 17:45Alex NeundorfStatusfeedback => assigned
2008-04-03 15:02Alex NeundorfSummaryfix in cmake cvs removes nice feature => custom global targets (targets which when built from the root build all targets with the same name in subdirs)
2009-01-29 14:35Brad KingRelationship addedrelated to 0008438
2011-05-17 15:54Brad KingNote Added: 0026521
2011-05-17 15:54Brad KingAssigned ToBrad King =>
2011-05-17 15:54Brad KingStatusassigned => backlog
2012-02-13 09:49Brad KingRelationship addedrelated to 0012960
2012-02-14 10:40Brad KingRelationship addedrelated to 0012961
2016-02-19 12:13Bruce AdamsNote Added: 0040515
2016-06-10 14:27Kitware RobotNote Added: 0041408
2016-06-10 14:27Kitware RobotStatusbacklog => resolved
2016-06-10 14:27Kitware RobotResolutionreopened => moved
2016-06-10 14:27Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:30Kitware RobotStatusresolved => closed

Notes
(0010501)
Brad King   
2008-02-14 15:51   
I knew someone would be upset by this, but it is necessary. Duplicate target names in the Xcode and VS IDE generators have unpredictable behavior. We cannot continue to silently support this case.

In order to help projects that only care about the Makefile generators, I can create a global property "ALLOW_DUPLICATE_CUSTOM_TARGETS" that allows the behavior. Non-makefile generators will immediately error out when this property is set, but then Makefile-only projects can be fixed with one line:

  set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1)

FYI, with CMake 2.4 when you build the "doxy" target in a subdirectory I bet it still builds the doxy target from all directories.
(0010502)
Brad King   
2008-02-14 15:52   
BTW, you can easily create this "doxy" case without duplicate custom targets:

  # CMakeLists.txt
  add_custom_target(doxy)
  add_subdirectory(A)
  add_subdirectory(B)

  # A/CMakeLists.txt
  add_custom_target(doxy_A)
  add_dependencies(doxy doxy_A)

  # B/CMakeLists.txt
  add_custom_target(doxy_B)
  add_dependencies(doxy doxy_B)

This also allows users to build the doxy target in one subdirectory without running it in all directories.
(0010503)
Brad King   
2008-02-14 16:43   
I've committed changes implementing the ALLOW_DUPLICATE_CUSTOM_TARGETS feature. I also made the error even more descriptive.

/cvsroot/CMake/CMake/Source/cmAddCustomTargetCommand.cxx,v <-- cmAddCustomTargetCommand.cxx
new revision: 1.30; previous revision: 1.29
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.cxx,v <-- cmGlobalGenerator.cxx
new revision: 1.226; previous revision: 1.225
/cvsroot/CMake/CMake/Source/cmGlobalGenerator.h,v <-- cmGlobalGenerator.h
new revision: 1.107; previous revision: 1.106
/cvsroot/CMake/CMake/Source/cmGlobalUnixMakefileGenerator3.h,v <-- cmGlobalUnixMakefileGenerator3.h
new revision: 1.55; previous revision: 1.54
/cvsroot/CMake/CMake/Source/cmMakefile.cxx,v <-- cmMakefile.cxx
new revision: 1.437; previous revision: 1.436
/cvsroot/CMake/CMake/Source/cmMakefile.h,v <-- cmMakefile.h
new revision: 1.225; previous revision: 1.224
/cvsroot/CMake/CMake/Source/cmake.cxx,v <-- cmake.cxx
new revision: 1.360; previous revision: 1.359
(0010504)
Alex Neundorf   
2008-02-14 16:48   
You are fast !

I was still typing a note, so I reopen the bug for now to be able to add that note:

I tested here with 2.4.6, if I build doxy in sub1 then only doxy in sub is built.

The idea with the different names is complicated.
I used this for running doxygen, the target names was "docs". So I knew I could go in any directory and build "docs", I didn't need to check what the name in this directory is. This target was created inside a macro like
add_doc_target() or something like this.
So the logic in that macro would have to be changed so that it creates a unique name in every directory. Then I would have to figure out that name. So it would be really a by far not so nice solution.

I know it wasn't officially supported, and I think it may also have worked differently with cmake 2.0.
Couldn't this be somehow made into an official feature ?
Would it be possible for the xcode and msvc generators to collect the custom targets with the same name into one target, which executes all commands and depends on all depends of the separate targets ?

I would prefer this over an additional property/variable which modifies cmake behaviour slightly, there have been quite a few added lately.

Alex
(0010505)
Brad King   
2008-02-14 17:14   
Combining custom targets across directories will be a HUGE can of worms with yet further unpredictable behavior.

What we really need is a notion of a "local target" that runs the same rule in every directory with that directory as the working directory. The rule would not be allowed to have any input or output files...just a command line to run unconditionally. On IDE generators the target would appear only once and always run in the top level. Currently the "install", "test", and "clean" targets work like this. It would have to become a first-class feature. I'd also want to convert the install, test, and clean targets to be defined this way in the first place. They could be created at the beginning of the configure step and referencable by users.
(0010506)
Brad King   
2008-02-14 17:19   
There is no way I'm getting a whole new kind of target in before 2.6. For now projects can do things like

if("${CMAKE_GENERATORS}" MATCHES Make)
  set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1)
  set(USE_SUBDIR_TARGETS)
endif("${CMAKE_GENERATORS}" MATCHES Make)

add_custom_target(docs ...)

# A/CMakeLists.txt
if(USE_SUBDIR_TARGETS)
  add_custom_target(docs ...)
endif(USE_SUBDIR_TARGETS)
(0010507)
Alex Neundorf   
2008-02-14 17:43   
Sounds good :-)

Converting the clean, install etc. targets to "real" targets would be a good thing, this is actually another use of the multiple-targets-with-the-same-name "feature". I added targets "veryclean" in subdirs, which cleaned some special things and then called "make clean" (using the appropriate cmake variables) to do the normal cleaning and there have been several questions regarding this on the mailing list.

Alex
(0010508)
Alex Neundorf   
2008-02-14 17:45   
As discussed, having these "local" targets would be a nice thing in the long term.

Alex
(0026521)
Brad King   
2011-05-17 15:54   
Moving to backlog. I think the approach mentioned in 0006348:0010505 will work but I have no time to work on this.
(0040515)
Bruce Adams   
2016-02-19 12:13   
Asking about this on stackoverflow led me here.

http://stackoverflow.com/questions/35489093/cmake-special-targets-like-all-and-test-having-the-same-name-in-multiple-pl [^]

It is possible to implement a add_local_target() workaround macro like mine as in the question.
My suggestion is to make something like this official until there is an opportunity to implement a genuine add_local_target() at which time policy CMP0002 could perhaps be eliminated.
(0041408)
Kitware Robot   
2016-06-10 14:27   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.