-1

In CMake, what is the difference between:

add_dependencies(tgt1 tgt2)

and

target_link_libraries(tgt1 tgt2)

when tgt2 being a library target?

Note: I don't mean difference in implementation, I mean difference in semantics.

starball
  • 20,030
  • 7
  • 43
  • 238
einpoklum
  • 118,144
  • 57
  • 340
  • 684

2 Answers2

1

add_dependencies just makes the second target's build get brought up to date before the first target if both targets need to be brought up to date. It's a build order control mechanism.

target_link_libraries makes the second target a link dependency of the first target- they will be linked by the generated buildsystem- and makes it so that if the depended-upon target needs to be rebuilt, the first target will also be rebuilt if need by. When using PRIVATE or PUBLIC visibility, it's to express and instruct that things that are in the interface of the second target will be made available to the first target. When using INTERFACE or PUBLIC visibility, it's to express and instruct that things that are in the interface of the second target will be made available to targets that express link dependencies on the first target ("transitive" link dependencies).

starball
  • 20,030
  • 7
  • 43
  • 238
  • *"`add_dependencies` just makes the second target build before the first target if both targets need to be rebuilt. It does not make the second target need to be rebuilt if it needs to be rebuilt."* That needs rephrasing: "to be built" here means "brought up to date"; if `tgt2` is already up to date, no rebuilding happens. Furthermore it's not stated clearly that `tgt2` will always be made up to date, if `tgt1` is built. Also if a target needs to be built, it needs to be built; the second sentence claims something else... – fabian Jul 24 '23 at 18:21
1

add_dependencies(A B) makes sure the generated project will make sure B is up to date before building A. It's the equivalent to adding the following rule to a makefile

A: B

target_link_libraries(A B) has the same effect plus:

  • Appropriate linker flags are added to include the binary generated for B among the files linked when generating the binary for A
  • Several INTERFACE properties of B take effect on A. Many of those correspond to cmake commands you can pass INTERFACE/PUBLIC to, e.g.
    • target_compile_definitions
    • target_compile_features
    • target_compile_options
    • target_include_directories
    • target_link_directories
    • target_link_libraries
    • target_link_options
    • target_precompile_headers
    • target_sources
  • If A is a library and you're adding PUBLIC/INTERFACE as visibility, targets linking A get access to INTERFACE properties in a similar manner
  • Some additional linker options may be modified specified e.g. for setting the rpath
  • The behaviour of install(EXPORT) and install(TARGETS) may change slightly. (Export dependency information, rpath update.)
  • The LINK_LIBRARIES target property for A is changed
  • ...
fabian
  • 80,457
  • 12
  • 86
  • 114