cpp-best-practices / gui_starter_template

A template CMake project to get you started with C++ and tooling

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues with using template for libraries

Ebony-Ayers opened this issue · comments

When I write a library using the template and an application also using the template cmake returns an error.

CMake Error at ../CMakeLists.txt:9 (add_library):
  add_library cannot create target "project_options" because another target
  with the same name already exists.  The existing target is an interface
  library created in source directory
  "/home/ebony/git/Ebony-Ayers/fwds/test".  See documentation for policy
  CMP0002 for more details.


CMake Error at ../CMakeLists.txt:21 (add_library):
  add_library cannot create target "project_warnings" because another target
  with the same name already exists.  The existing target is an interface
  library created in source directory
  "/home/ebony/git/Ebony-Ayers/fwds/test".  See documentation for policy
  CMP0002 for more details.

The main CMakeLists.txt is setup to require libraries for the settings and warnings. I cannot find a way of removing the libraries with out losing the warnings and settings.

Is there a way remedy this?

What method are you using to include the library in the application? There must be some way of keeping the namespaces of the two projects separate.

One obvious solution would be to rename the project_warnings and project_options targets in one or both projects. You would only need to modify the root level CMakeLists.txt and the CMakeLists.txt files within 'src'; those are the only places that use those names. This is admittedly not sustainable: it would require more renaming when you include your top-level project in any other project. However, it might be a better short-term solution than removing project_warnings and project_options entirely.

In case you are tempted to do something like rename project_warnings to ${PROJECT_NAME}_project_warnings, be aware that PROJECT_NAME is a global variable that will change every time you call project(), and its previous value will not be restored when you return from a subproject.

This is how I am including the library

add_subdirectory(../../ external/library)
include_directories(../src)
target_link_libraries(application PUBLIC library)

I did not want to rename everything as you point out, it is no scalable.

I know no way in cmake to create name spaces in he c++ sense. However each target has it's own scope for variables.

Would it be an option to use ExternalProject_Add (https://cmake.org/cmake/help/latest/module/ExternalProject.html)?

I'm pretty sure that add_subdirectory leaks all of the variables present in the outer project's namespace to the inner project, and I'm not aware of any way to prevent that.