概述
cmake 基本命令:
cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR)
project("ProjName")
// 不推荐使用add_definitions来设置编译选项,因为其作用如同cmake -D
add_definitions(
-std=c++11 # Or -std=c++0x
-Wall
-Wfatal-errors
-DXXX #等于gcc -DXXX
# Other flags
)
// 一般通过下条语句设置编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wfatal-errors -fPIC")
//变量:CMAKE_PREFIX_PATH: Path used for searching by FIND_XXX(), with appropriate suffixes added. e.g: find_package
set(CMAKE_PREFIX_PATH /path/path/path)
//引用环境变量
export FOO=/use/lib # 在bash中
$ENV{FOO} # 在CMakeLists.txt中
//头文件路径
include_directories(
include
relative/path
/absolute/path/
)
//链接库目录
link_directories(directory1 directory2 ...)
//链接函数库
target_link_libraries(a.out mylib ompl) //可以是cmake中的target,也可以是某个目录中的库文件,如 libompl.so,等同于 gcc -lompl
//源文件路径,在子目录中
add_subdirectory (
someDirectory
src/otherDirecotry
)
//寻找某个目录中的所有源文件,格式:aux_source_directory(<dir> <variable>)
aux_source_directory(src _srcFiles)
//生成库文件
add_library(mylib [SHARED|STATIC]
mylib.cpp
other.cpp
)
//生成可执行程序
add_executable(a.out
main.cpp
src/func.cpp
)
//设置变量
set(someVariable "some string")
//打印消息
message(STATUS "some status ${someVariable}")
//list操作
list(REMOVE_ITEM _srcFiles "src/f4.cpp") //从变量中去掉某一项
list(APPEND <list> <element> [<element> ...]) //添加某一项到变量中
//检查编译器是否支持某一个编译选项
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
常用 find_package 找 boost 库和头文件:
# Put this in your CMakeLists.txt file (change any options from OFF to ON if you want):
set(Boost_USE_STATIC_LIBS OFF) # 不写这几个就是默认设置
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.59.0 COMPONENTS *boost libraries here* REQUIRED) // 如果只是头文件库,则不需要写 COMPONENTS, 直接 find_package(Boost 1.59.0 xxx REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(progname file1.cxx file2.cxx)
target_link_libraries(progname ${Boost_LIBRARIES})
endif()
# Obviously you need to put the libraries you want where I put *boost libraries here*.
# For example, if you're using the filesystem and regex library you'd write:
find_package(Boost 1.59.0 COMPONENTS filesystem regex REQUIRED) # 一般包含头文件是 <boost/xxx/*>, 则 COMPONENTS 后面就写 xxx
cmake marco & function
set(var "ABC")
macro(Moo arg) # 定义macro
message("arg = ${arg}")
set(arg "abc")
message("# After change the value of arg.")
message("arg = ${arg}")
endmacro()
message("=== Call macro ===")
Moo(${var}) # 调用macro
function(Foo arg) # 定义函数
message("arg = ${arg}")
set(arg "abc")
message("# After change the value of arg.")
message("arg = ${arg}")
endfunction()
message("=== Call function ===")
Foo(${var}) # 调用函数
and the output is
=== Call macro ===
arg = ABC
# After change the value of arg.
arg = ABC
=== Call function ===
arg = ABC
# After change the value of arg.
arg = abc
#注意,marco的调用相当于c/c++的预编译器,只会进行字符串替换(这就是为啥 arg 没有被改变);而函数则可以进行变量操作
//常用变量
CMAKE_SOURCE_DIR ( 相当于工程根目录 )
this is the directory, from which cmake was started, i.e. the top level source directory
CMAKE_CURRENT_SOURCE_DIR
this is the directory where the currently processed CMakeLists.txt is located in
PROJECT_SOURCE_DIR ( =CMAKE_SOURCE_DIR 相当于工程根目录 )
contains the full path to the root of your project source directory, i.e. to the nearest directory where CMakeLists.txt contains the PROJECT() command
CMAKE_PREFIX_PATH (用于找 Findxxx.cmake文件,找 库 和 头文件)
Path used for searching by FIND_XXX(), with appropriate suffixes added.
CMAKE_INSTALL_PREFIX ( 安装目录 )
Install directory used by install.
If “make install” is invoked or INSTALL is built, this directory is prepended onto all install directories. This variable defaults to /usr/local on UNIX and c:/Program Files on Windows.
例如:cmake .. -DCMAKE_INSTALL_PREFIX=/my/paht/to/install
cmake 配置交叉编译环境:
// cmake的交叉编译环境设置,创建文件toolchain.cmake,添加以下内容:
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compiler
SET(CMAKE_C_COMPILER /opt/arm/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /opt/arm/arm-linux-gnueabihf-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /opt/arm/install)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
// If this file is named toolchain.cmake and is located in your home directory
// and you are building in the subdirectory build then you can do:
~/src$ cd build
~/src/build$ cmake -DCMAKE_TOOLCHAIN_FILE=~/toolchain.cmake ..
注意: 在交叉编译的时候,如果某些 FindXXX.cmake 模块中有类似 pkg_search_module
或者 pkg_check_modules
等命令,则会有点问题:
FindXXX.cmake modules, which rely on executing a binary tool like pkg-config may have problems, since the pkg-config of the target platform cannot be executed on the host. Tools like pkg-config should be used only optional in FindXXX.cmake files.
可以找到相应的模块的 FindXXX.cmake 替换其 pkg-config
如果不想让 pkg-config 被执行,可以试着:
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) // 即不让cmake的 find_program 去host环境中找可执行文件,所以 pkg_search_module 这种命令应该会失败。
如果 cmake cache了一些变量,需要重新运行cmake,只需要删除 CMakeCache.txt 文件即可
关于如何编写自己的 Findxxx.cmake 文件:
尊重原作,以下部分复制了该作者的部分文件内容,see link
set(MYSIMPLEPACKAGE_ROOT_DIR
"${MYSIMPLEPACKAGE_ROOT_DIR}"
CACHE
PATH
"Directory to search")
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
set(_LIBSUFFIXES /lib64 /lib)
else()
set(_LIBSUFFIXES /lib)
endif()
find_library(MYSIMPLEPACKAGE_LIBRARY
NAMES
mysimplepackage
PATHS
"${MYSIMPLEPACKAGE_ROOT_DIR}"
PATH_SUFFIXES
"${_LIBSUFFIXES}")
# Might want to look close to the library first for the includes.
get_filename_component(_libdir "${MYSIMPLEPACKAGE_LIBRARY}" PATH)
find_path(MYSIMPLEPACKAGE_INCLUDE_DIR
NAMES
mysimplepackage.h
HINTS
"${_libdir}" # the library I based this on was sometimes bundled right next to its include
"${_libdir}/.."
PATHS
"${MYSIMPLEPACKAGE_ROOT_DIR}"
PATH_SUFFIXES
include/)
# There's a DLL to distribute on Windows - find where it is.
set(_deps_check)
if(WIN32)
find_file(MYSIMPLEPACKAGE_RUNTIME_LIBRARY
NAMES
mysimplepackage.dll
HINTS
"${_libdir}")
set(MYSIMPLEPACKAGE_RUNTIME_LIBRARIES
"${MYSIMPLEPACKAGE_RUNTIME_LIBRARY}")
get_filename_component(MYSIMPLEPACKAGE_RUNTIME_LIBRARY_DIRS
"${MYSIMPLEPACKAGE_RUNTIME_LIBRARY}"
PATH)
list(APPEND _deps_check MYSIMPLEPACKAGE_RUNTIME_LIBRARY)
else()
get_filename_component(MYSIMPLEPACKAGE_RUNTIME_LIBRARY_DIRS
"${MYSIMPLEPACKAGE_LIBRARY}"
PATH)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MySimplePackage
DEFAULT_MSG
MYSIMPLEPACKAGE_LIBRARY
MYSIMPLEPACKAGE_INCLUDE_DIR
${_deps_check})
if(MYSIMPLEPACKAGE_FOUND)
set(MYSIMPLEPACKAGE_LIBRARIES "${MYSIMPLEPACKAGE_LIBRARY}")
set(MYSIMPLEPACKAGE_INCLUDE_DIRS "${MYSIMPLEPACKAGE_INCLUDE_DIR}")
mark_as_advanced(MYSIMPLEPACKAGE_ROOT_DIR)
endif()
mark_as_advanced(MYSIMPLEPACKAGE_INCLUDE_DIR
MYSIMPLEPACKAGE_LIBRARY
MYSIMPLEPACKAGE_RUNTIME_LIBRARY)
哈,家里的小工厂,占个位: http://www.herofireworks.com/
最后
以上就是重要小白菜为你收集整理的cmake 基本命令 & 交叉编译配置 & 模块的编写的全部内容,希望文章能够帮你解决cmake 基本命令 & 交叉编译配置 & 模块的编写所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复