target_link_libraries() requires full path for some but not all project libraries?

My project builds several libraries, then links them to generate an executable. When calling target_link_libraries() for the executable, some - but not all - of the project libraries must be specified with full path ${CMAKE_BINARY_DIR/src/dir, else the linker cannot find them. Yet other project libraries don’t require this. Why? Each project library was added to the project with add_library().

My executable’s CMakeLists.txt looks like this:

add_executable(mbgrdviz
               mbgrdviz_callbacks.c  mbgrdviz_creation.c  mbgrdviz_main.c)

target_include_directories(mbgrdviz
                           PUBLIC
                           .
                           ${GMT_INCLUDE_DIR}
                           ${CMAKE_SOURCE_DIR}/src/mbio
                           ${CMAKE_SOURCE_DIR}/src/mbaux
                           ${CMAKE_SOURCE_DIR}/src/mbview
                           ${CMAKE_SOURCE_DIR}/src/bsio
                           ${CMAKE_SOURCE_DIR}/src/surf
                           ${CMAKE_SOURCE_DIR}/src/gsf)
                           
# Why do libbsio.a, libmbsapi.a and libgsf.a require full path else
# they aren't found by linker?
target_link_libraries(mbgrdviz
                      PRIVATE libmbio.a
                      PRIVATE libmbaux.a
                      PRIVATE libmbview.a
                      PRIVATE ${CMAKE_BINARY_DIR}/src/bsio/libbsio.a
                      PRIVATE ${CMAKE_BINARY_DIR}/src/surf/libmbsapi.a
                      PRIVATE ${CMAKE_BINARY_DIR}/src/gsf/libgsf.a
                      PRIVATE gmt
                      PRIVATE Xm
                      PRIVATE Xt
                      PRIVATE X11
                      PRIVATE GL
                      PRIVATE GLU
                      PRIVATE m
                      PRIVATE netcdf
                      PRIVATE gdal
                      PRIVATE proj
                      PRIVATE pthread)

target_link_libraries() documentation says that libraries may be specified by name only (as several of them are).
Thanks!

Your own libraries should be specified by target name, not file name.

Tom O’Reilly wrote:

My project builds several libraries, then links them to generate an
executable. When calling target_link_libraries() for the executable, some -
but not all - of the project libraries must be specified with full path
${CMAKE_BINARY_DIR/src/dir, else the linker cannot find them. Yet other
project libraries don’t require this. Why? Each project library was added
to the project with add_library().

# Library names with ‘lib’ prefix are built by this project,
# others are third-party already installed on system.
# Some of my project libraries - libbsio.a, libmbsapi.a,
# libgsf.a - require full pathname else they are not found
# by linker - why is this?
target_link_libraries(mbgrdviz
                PRIVATE libmbio.a
                PRIVATE libmbaux.a
                PRIVATE libmbview.a
                PRIVATE ${CMAKE_BINARY_DIR}/src/bsio/libbsio.a
                PRIVATE ${CMAKE_BINARY_DIR}/src/surf/libmbsapi.a
                PRIVATE ${CMAKE_BINARY_DIR}/src/gsf/libgsf.a
                PRIVATE gmt
                PRIVATE Xm
                PRIVATE Xt
                PRIVATE X11
                PRIVATE GL
                PRIVATE GLU
                PRIVATE m
                PRIVATE netcdf
                PRIVATE gdal
                PRIVATE proj
                PRIVATE pthread)

That means you should pass the target name: if you do add_library(mbio),
then you do target_link_libraries(mbgrdviz PRIVATE mbio). Btw, you need to
specify PRIVATE only once.

Eike

1 Like

That fixes it - thanks!