[CMake] Unnecessary ordering breaks existing CMakeLists.txt

Brad King brad.king at kitware.com
Wed Aug 16 10:30:05 EDT 2006


Dataflow wrote:
> This was working with 2.0 and feels natural, but no longer works with 2.4.
> It boils down to the ordering of LINK_DIRECTORIES.
> -------------
> add_executable(app
>     src1.cpp src2.cpp ...
>     )
> link_directories(dir1;dir2;dir3)
> target_link_libraries(app lib1 lib2 lib3)
> --------------
>  
> This now requires that the 'add_executable' should come between
> 'link_dirs' and 'target_link..'. This is unnecessarily restrictive. Any
> particular reason why CMake has been changed to impose this ?

This change was made as part of allowing subdirectories to be processed
before parent directories:

add_executable(exe1 ...)
add_subdirectory(sub1) # sub1 has "add_executable(sub1exe ...)"
link_directories(dir1)
add_executable(exe2 ...)
add_subdirectory(sub2) # sub1 has "add_executable(sub2exe ...)"

In this example exe1 and sub1exe should get no link directories, and
exe2 and sub2exe should both get link directory dir1.  Without the
ordering then exe1 would get link directory dir1 while sub1exe would not.

The decision to establish the ordering requirement was made because link
directories were one of the last order-independent things left from very
early versions of CMake where everything was order-independent.  We
wanted to get rid of this legacy before too many more users started
using CMake.

For most changes that break compatibility we support the old behavior if
CMAKE_BACKWARDS_COMPATIBILITY is set low enough.  Try setting that
variable to 2.0.  It may not work in this one case because it is tricky
to support both behaviors but it is worth a try.

> PS:
> I have reduced this from the general case of
> -----------
> add_executable(app ...)
>  
> find_package(...)
> target_link_libraries(app lib1)
>  
> find_package(...)
> target_link_libraries(app lib2)
> etc
> -----------
> Now the add_executable must come after all the 'find_packages'.
> Changing all the old CMakeLists is annoying. Even lowly make does not
> force this type of ordering.
> Would like to keep package finding & its use at a single place.
> Please clarify... 

You can.  We generally do not use link directories to get
target_link_libraries to work.  Instead the packages should compute full
paths to lib1 and lib2:

find_package(foo)
target_link_libraries(app ${foo_libraries})

where foo_libraries contains something like
"/path/to/libfoo1.so;/path/to/libfoo2.so".

This has the advantage that library dependency chaining (such as if
"app" were a library and something else linked to it) automatically
pulls through the library locations instead of requiring manual
propagation of the link directories.

-Brad


More information about the CMake mailing list