在编译程序的时候要使用链接库是经常的事情,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()