36

Is there any use case in which

target_link_libraries(my-lib x y z)

add_dependencies(my-lib x) # this is not just a waste of bytes?

If so, can someone explain what it would be?

Andrew Lazarus
  • 18,205
  • 3
  • 35
  • 53

3 Answers3

35

In current CMake releases:

After some error checking add_dependencies results in a call to Target->AddUtility(). x is added to the list of utilities for my-lib.

target_link_libraries does not result in a call to AddUtility, but it does add the arguments to the LINK_LIBRARIES target property.

Later, both the content of the LINK_LIBRARIES target property and the list of utilities are used to compute the dependencies of the target in cmComputeTargetDepends.

The list of utilities in a target can not be queried at configure time, and is only used at generate time, so the use of add_dependencies with arguments which are libraries already added with target_link_libraries is redundant.

ololuki
  • 377
  • 1
  • 7
  • 14
steveire
  • 10,694
  • 1
  • 37
  • 48
  • 1
    Could you please double-check all the links because all of them more or less redirects to the main GitLab page of CMake? Thanks a lot in advance! – Milan Mar 01 '21 at 16:28
5

I don't know what you're particularly interested in...

From a conceptual point of view -- I think you're right. It is a waste of bytes.

From a CMake documentation point of view -- You should prefer make so to guarantee the correct build order.

According to the documentation target_link_libraries, add_dependencies concepts was ideologically split. Such an idea of split dependencies, and linker options is also persisted in the Makefile format in the GNU make tool.

target_link_libraries

..Specify libraries or flags to use when linking a given target..

add_dependencies

...Make a top-level <target> depend on other top-level targets to ensure that they build before <target> does...

In modern CMake from 3.* you can omit add_dependencies if you will perform linking with an aliased target:

add_library(fooLib 1.cpp 2.cpp)
add_library(my::fooLib ALIAS fooLib)
...
target_link_libraries(fooBin my::fooLib)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Konstantin Burlachenko
  • 5,233
  • 2
  • 41
  • 40
  • 1
    You don't even need ALIAS - using library name is enough. "If a library name matches that of another target in the project a dependency will automatically be added in the build system to make sure the library being linked is up-to-date before the target links."[docs](https://cmake.org/cmake/help/v3.0/command/target_link_libraries.html) This should be enough: `add_library(fooLib 1.cpp 2.cpp)` `target_link_libraries(fooBin fooLib)` – ololuki Apr 10 '22 at 15:41
  • @ololuki Wouldn't you like to correct the answer? – John Nov 04 '22 at 02:31
  • Regardless of if it's needed, you should use ALIAS targets anyways. – Ryan Friedman Jun 24 '23 at 06:06
-2

It's used in cases where top-level targets depend on each other. That is, if x is a something that you add to your project (at top-level) with

add_library( x x.c y.c z.c )

you shall tell CMake about it. And you do that with add_dependencies.

sebkraemer
  • 435
  • 3
  • 12
  • I didn't downvote, but the point of my question is whether **add_dependencies** is _redundant_ after **target_link_libraries**. – Andrew Lazarus Dec 04 '14 at 08:53
  • OK, I obviously got this a bit wrong. Anyway, I wouldn't have been able to comment in such depth as @seveire did, so thanks for that. – sebkraemer Jan 19 '15 at 12:38