Jepessen
Jepessen

Reputation: 12435

CMP0002 error when compiling different subproject with same target

I've many sub-folders

home
|
|-library1
|-library2
|
|-libraryn

Every subfolder contains a complete library that can compile by itself (every library has a different mantainer). Until now it works correctly and I compile them using a script.

Now I need to create another library, that depends on existing one. In order to do so, I've created a CMakeLists.txt under home folder, using add_subdirectory command that allows me to compile all libraries.

I've something like

cmake_minimum_required (VERSION 2.8)

add_subdirectory(library1)
add_subdirectory(library2)
...
add_subdirectory(libraryn)

When I try to execute cmake I obtain following error for various libraries:

CMake Error at libraryY/CMakeLists.txt:63 (add_custom_target):
  add_custom_target cannot create target "doc" because another target with
  the same name already exists.  The existing target is a custom target
  created in source directory
  "/path/to/libraryX".  See
  documentation for policy CMP0002 for more details.

This happens because in every library we create a doc target in order to compile the Doxygen documentation of the library itself. It works fine when libraryes are compiled one by one, but with the master CMakeLists.txt it seems that I cannot do it.

# Create doc target for doxygen documentation compilation.
find_package (Doxygen)
if (DOXYGEN_FOUND)
  set (Doxygen_Dir ${CMAKE_BINARY_DIR}/export/${Library_Version}/doc)
  # Copy images folder
  file (GLOB IMAGES_SRC "images/*")
  file (COPY ${IMAGES_SRC} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/images)
  configure_file (${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
  add_custom_target (doc
    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    COMMENT "Generating doxygen documentation" VERBATIM
  )
else (DOXYGEN_FOUND)
  message (STATUS "Doxygen must be installed in order to compile doc")
endif (DOXYGEN_FOUND)

Is there a way to compile these project at once without modify this target?

Upvotes: 6

Views: 11384

Answers (3)

saell
saell

Reputation: 11

We are using options in each library to enable 'tooling' via build targets too.

When combining multiple libraries with the same 'tooling' you need to make sure the options have a project specific naming.

Otherwise enabling an option for the repo with the same name as in the sub repo gives you the same error message.

To come around this we follow a simple naming schema: e.g.


option(LIBRARY_A_DOXYGEN "doxygen ..." OFF)
option(LIBRARY_A_COVERAGE "gcov ..." OFF)
...

That way you can enable those settings when developing the library (e.g. CMakePresets.json) but keep them disabled when the library is used with add_subdirectory.

Upvotes: 0

Dan Wagner
Dan Wagner

Reputation: 31

if (NOT (TARGET DOCUMENTATION))
    add_custom_target(DOCUMENTATION COMMENT "workaround for multi-dependencies project")
    add_dependencies(DOCUMENTATION DOCUMENTATION_${PROJECT_NAME})
endif()

I have tested this and used it in real life. It works for multiple projects.

Upvotes: 1

user2288008
user2288008

Reputation:

If you don't want to modify anything so you can build all this projects as subprojects, then you can use ExternalProject_Add to build and install dependencies.

option

Alternatively you can use option command to exclude doc target from build:

# Foo/CMakeLists.txt
option(FOO_BUILD_DOCS "Build doc target for Foo project" OFF)
# ...
if(DOXYGEN_FOUND AND FOO_BUILD_DOCS)
  add_custom_target(doc ...)
endif()

# Boo/CMakeLists.txt
option(BOO_BUILD_DOCS "Build doc target for Boo project" OFF)
# ...
if(DOXYGEN_FOUND AND BOO_BUILD_DOCS)
  add_custom_target(doc ...)
endif()

Upvotes: 4

Related Questions