5

CMake has an irritating default (I presume, I see nothing magical in my CMake config, but I could be wrong since I know very little about CMake) behavior that he silently ignores when you add a target to your project even if that target does not exist, for example:

project(StackOverflow)

// another CMakeLists.txt

project (Stuff)

target_link_libraries(Stuff PUBLIC StackOverlow )

Is there a way to force CMake to check that all projects you link in target_link_libraries must exist?

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • What is the non-existent target here in your example? The syntax for `target_link_libraries()` in your example is incorrect. Specifically, the first argument *must* be an **existing** target, or you will receive an error. You haven't created a target `StackOverflow` either. – Kevin May 08 '20 at 14:45
  • @squareskittles sorry, I reduced my real CMakeLists.txt too much, thank you for bug report :) – NoSenseEtAl May 08 '20 at 15:02

2 Answers2

2

It is possible for CMake to fail if you link ALIAS targets. For example

In first CMakeLists.txt

add_library(StackOverflow STATIC lib.cpp)
add_library(StackOverflow::StackOverflow ALIAS StackOverflow)

In second CMakeLists.txt

target_link_libraries(Stuff PUBLIC StackOverflow::StackOverflow)

CMake will fail with an error if StackOverflow::StackOverflow is not defined.

https://cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#alias-targets

Community
  • 1
  • 1
lgisler
  • 21
  • 3
1

In CMake, you do not link projects to other projects. Instead, you link targets to other targets.

CMake targets are only created via a few commands (such as add_library, add_executable, and add_custom_target). The project command does not create a CMake target, it merely declares a project.

Furthermore, the target_link_libraries() command accepts the following arguments after the scoping keyword:

  • A library target name
  • A full path to a library file
  • A plain library name
  • A link flag
  • A generator expression
  • A debug, optimized, or general keyword

It does not accept project names, although if you put a project name, it will instead look for a CMake target or library file on your system with that name.

To get to the root of what I believe you're asking: If you provide link-item name to target_link_libraries() that does not match an existing target, the command will simply search for a library file of that name instead.

To check if a target exists before trying to link it, you can do:

if (TARGET StackOverflow)
    target_link_libraries(Stuff PUBLIC StackOverflow)
endif()

I suggest reading through the linked target_link_libraries() documentation if you want more details about what this command does.

Kevin
  • 16,549
  • 8
  • 60
  • 74
  • 1
    ah, this is definitely not ideal... and yes you are right, I never considered the "fallback" (or default) that target_link_libraries will look for library instead of failing. – NoSenseEtAl May 08 '20 at 15:23
  • 1
    also now I found this feature request for what I want: https://cmake.org/pipermail/cmake/2019-February/068983.html looks ignored. :) – NoSenseEtAl May 08 '20 at 15:27
  • 1
    @NoSenseEtAl The active CMake issues can be found [here](https://gitlab.kitware.com/cmake/cmake/issues), although from a quick search I didn't see anything related to this issue. CMake has made incredible efforts to maintain backward compatibility, and I think a change like this would break that. Perhaps, they could add a CMake policy to optionally produce a warning when linking non-target link items... – Kevin May 08 '20 at 15:32
  • I do not see how adding new builtin function (target_add_targets) would break bw compat, but tbh like I said CMake is mostly a black box to me. – NoSenseEtAl May 08 '20 at 15:38