cmake之使用链接库

在编译程序的时候要使用链接库是经常的事情,g++-L指定将路径添加到链接库搜索路径,-l指定程序链接的时候要链接的库。那么cmake中如何指定呢?

解决方案

在cmake中,我们可以通过link_directories()将路径添加到库搜索路径,使用link_libraries()指定使用的库。但是官方文档上并不推荐使用这个…

后来我发现了通过find_library()target_link_libraries()解决问题(注意,target_link_libraries()需要在add_executable()之后)。

find_library

find_library()用来查找一个库文件,具体使用信息可查阅官方文档

find_library (<VAR> NAMES name PATHS paths... NO_DEFAULT_PATH)
find_library (<VAR> NAMES name)

使用leveldb时的示例:
由于我将leveldb make install了,但是我又需要使用编译时使用的版本,所以指定了搜索路径,并设定不在默认路径中搜索leveldb库。

find_library(LEVELDB leveldb PATHS ~/workspaces/c++/leveldb/build/ NO_DEFAULT_PATH)

target_link_libraries

target_link_libraries()用来指定链接给定目标时要使用的库或标志。

target_link_libraries(<target> [item1 [item2 [...]]]
                      [[debug|optimized|general] <item>] ...)

<target>名字必须先通过add_executable()add_library()之类的命令在当前目录中创建。命令的其余参数用于指定库名称或标志。允许重复调用相同的<target>来追加调用顺序到项目。

示例

下面的示例为leveldb的示例,需要注意的是,由于头文件在默认路径中。所以没有进行include_directories()设置,如果头文件没有在默认路径中,注意修改添加。

cmake_minimum_required(VERSION 2.8)

project(testLevelBD)
find_library(LEVELDB leveldb PATHS ~/workspaces/c++/leveldb/build/ NO_DEFAULT_PATH)
if(LEVELDB)
    message(status " --- ${LEVELDB}")
endif(LEVELDB)
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries(${PROJECT_NAME} ${LEVELDB} pthread)

下面实例为boost.asio的例子的cmake配置:

cmake_minimum_required(VERSION 3.0)
project(asio_multicast_receiver)

set(project_base_dir "${PROJECT_SOURCE_DIR}")
set(cxx_headers_dir  "${project_base_dir}/include")
set(cxx_sources_dir  "${project_base_dir}/src")

set(cxx_headers )
set(cxx_sources )

ma_config_public_compile_options(cxx_public_compile_options)
ma_config_public_compile_definitions(cxx_public_compile_definitions)
set(cxx_public_libraries )

ma_config_private_compile_options(cxx_private_compile_options)
ma_config_private_compile_definitions(cxx_private_compile_definitions)
set(cxx_private_libraries )

list(APPEND cxx_sources
    "${cxx_sources_dir}/receiver.cpp")

list(APPEND cxx_private_libraries
    ma_boost_header_only
    ma_boost_asio
    ma_coverage)

add_executable(${PROJECT_NAME}
    ${cxx_headers}
    ${cxx_sources})
target_compile_options(${PROJECT_NAME}
    PUBLIC
    ${cxx_public_compile_options}
    PRIVATE
    ${cxx_private_compile_options})
target_compile_definitions(${PROJECT_NAME}
    PUBLIC
    ${cxx_public_compile_definitions}
    PRIVATE
    ${cxx_private_compile_definitions})
target_include_directories(${PROJECT_NAME}
    PUBLIC
    ${cxx_headers_dir})
target_link_libraries(${PROJECT_NAME}
    PUBLIC
    ${cxx_public_libraries}
    PRIVATE
    ${cxx_private_libraries})

if(NOT ma_no_cmake_dir_source_group)
    # Group files according to file path
    ma_dir_source_group("Header Files" "${cxx_headers_dir}" "${cxx_headers}")
    ma_dir_source_group("Source Files" "${cxx_sources_dir}" "${cxx_sources}")
endif()