以前工作中单板构建结合shell+cmake使用,主题框架由shell处理,主要是基本所有单板公用同一套代码,根据shell来处理和区分单板类型;单板类型会根据入参改变C++中代码宏的定义,使得对应单板代码有效。
shell常用命令可以参考我发的:Linux常用命令
或者在这个网站上搜索:菜鸟教程 - 学的不仅是技术,更是梦想!
github示例代码:https://github.com/ttroy50/cmake-examples
一般在CMake编译时出错搜第一个error来处理,如果是在make过程中报错搜不到更早的error,则根据错误提示make文件中查看报错的文件及行数
makefile上配置后给LIBS
cmake转换成lib
link_directories()
target_link_options
target_link_libraries
GCC:全称为GNU Compiler(编译器) Collection(收集)
Linux touch命令
Linux touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
ls -l 可以显示档案的时间记录。
语法
touch [-acfm][-d<日期时间>][-r<参考文件或目录>] [-t<日期时间>][--help][--version][文件或目录…]
- 参数说明
- :
- a 改变档案的读取时间记录。
- m 改变档案的修改时间记录。
- c 假如目的档案不存在,不会建立新的档案。与 --no-create 的效果一样。
- f 不使用,是为了与其他 unix 系统的相容性而保留。
- r 使用参考档的时间记录,与 --file 的效果一样。
- d 设定时间与日期,可以使用各种不同的格式。
- t 设定档案的时间记录,格式与 date 指令相同。
- --no-create 不会建立新档案。
- --help 列出指令格式。
- --version 列出版本讯息。
Minimum CMake version 最小 CMake 版本
When creating a project using CMake, you can specify the minimum version of CMake that is supported.
使用 CMake 创建项目时,可以指定支持的最小版本的 CMake。
cmake_minimum_required(VERSION 3.5)
Projects 项目
A CMake build can include a project name to make referencing certain variables easier when using multiple projects.
CMake 构建可以包含项目名称,以便在使用多个项目时更容易地引用某些变量。
project (hello_cmake)
Creating an Executable 创建可执行文件
The add_executable() command specifies that an executable should be build from the specified source files, in this example main.cpp. The first argument to the add_executable() function is the name of the executable to be built, and the second argument is the list of source files to compile.
Add _ executable ()命令指定应该从指定的源文件构建可执行文件,在本例中为 main.cpp。Add _ executable ()函数的第一个参数是要生成的可执行文件的名称,第二个参数是要编译的源文件列表。
add_executable(hello_cmake main.cpp)
在根目录中运行 cmake 命令
编译当前目录
cmake .
创建文件夹后进入并编译上层目录
mkdir build
cd build
cmake ..
查看编译后框架
tree
如果提示没有安装
apt install tree
编译
make
有文件夹的编译示例
# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.5)
# Set the project name
project (hello_headers)
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/Hello.cpp
src/main.cpp
)
# Add an executable with the above sources
add_executable(hello_headers ${SOURCES})
# Set the directories that should be included in the build command for this target
# when running g++ these will be included as -I/directory/path/
target_include_directories(hello_headers
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
添加静态库(主要为add_library和target_link_libraries)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
这将用于创建一个名为 libhello _ library. a 的静态库,其中包含 add_library 调用中的源代码
使用 target _ include _ directories ()函数将目录包含在库中,作用域设置为 PUBLIC。
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
This will cause the included directory used in the following places:
这将导致在下列地方使用包含的目录:
- When compiling the library
- 在编译库时
- When compiling any additional target that links the library.
- 在编译链接库的任何其他目标时。
- PRIVATE-该目录被添加到此目标的 include 目录中
- INTERFACE-该目录被添加到包含目录中,用于链接此库的任何目标。
- PUBLIC-如上所述,它包含在这个库中,也包含在链接这个库的任何目标中。
在创建将使用库的可执行文件时,必须告诉编译器有关库的信息。这可以使用 target _ link _ libraries ()函数来完成。
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello_library
)
共享库(SHARED)
共享库是为了增强灵活性,LabVIEW能够调用并创建外部代码程序,并把这些程序集成到可执行程序中。事实上,一个共享程序库就是一个共享函数库,应用程序可以在运行时连接到该程序库,而不是在编译时连接。在Windows中,共享程序库被称为动态链接库;在Mac OS X系统中,称为framework;在Linux中称为共享目标。在LabVIEW中可以使用Call Library函数调用共享库。还可以告诉LabVIEW,将VI编译为共享库,供其他类型的代码使用。
cmake_minimum_required(VERSION 3.5)
project(hello_library)
#Generate the shared library from the library sources
add_library(hello_library SHARED
src/Hello.cpp
)
add_library(hello::library ALIAS hello_library)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
# Add an executable with the above sources
add_executable(hello_binary
src/main.cpp
)
# link the new hello_library target with the hello_binary target
target_link_libraries( hello_binary
PRIVATE
hello::library
)
在系统上安装文件和二进制文件。这是基于前面的共享库示例
以下在CMakeLists.txt中配置
将从目标 CMAKE _ examples _ inst _ bin 目标生成的二进制文件安装到目标 ${ CMAKE _ Install _ prefix }/bin
install (TARGETS cmake_examples_inst_bin
DESTINATION bin)
将从目标 CMAKE _ examples _ inst 目标生成的共享库安装到目标 ${ CMAKE _ Install _ prefix }/lib
install (TARGETS cmake_examples_inst
LIBRARY DESTINATION lib)
编译后make安装
sudo make install
安装到目的地
make install DESTDIR=/tmp/stage
查找引用第三方库文件(find_package查找后include_directories包含目录,并链接库target_link_libraries)
find_package(Boost库名称 1.46.1最小版本 REQUIRED必要的 COMPONENTS要寻找的库列表 filesystem system)
查找结果判断
if(Boost_FOUND)
message ("boost found")
include_directories(${Boost_INCLUDE_DIRS})
else()
message (FATAL_ERROR "Cannot find Boost")
endif()
引用库
# Include the boost headers
target_include_directories( third_party_include
PRIVATE ${Boost_INCLUDE_DIRS}
)
# link against the boost libraries
target_link_libraries( third_party_include
PRIVATE
${Boost_SYSTEM_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
)
更改CMake编辑器
将编译器从缺省 gcc 更改为 clang 的最基本方法
cmake .. -DCMAKE_C_COMPILER=clang-3.6 -DCMAKE_CXX_COMPILER=clang++-3.6
添加子目录
主基础目录中
cmake_minimum_required (VERSION 3.5)
project(subprojects)
# Add sub directories
add_subdirectory(sublibrary1)
add_subdirectory(subbinary)
子目录1中
project(subbinary)
# Create the executable
add_executable(${PROJECT_NAME} main.cpp)
# Link the static library from subproject1 using it's alias sub::lib1
# Link the header only library from subproject2 using it's alias sub::lib2
# This will cause the include directories for that target to be added to this project
target_link_libraries(${PROJECT_NAME}
sub::lib1
)
子目录2中
# Set the project name
project (sublibrary1)
# Add a library with the above sources
add_library(${PROJECT_NAME} src/sublib1.cpp)
# 在调用这个库target_link_libraries使用sub::lib1
add_library(sub::lib1 ALIAS ${PROJECT_NAME})
target_include_directories( ${PROJECT_NAME}
PUBLIC ${PROJECT_SOURCE_DIR}/include
)
2.1 message打印方法
message([<mode>] "message to display" ...)
message(DEBUG "message to display")
message("message to display") # 编译的时候这里就打印出来
- message:消息名字,可在CMakeLists.txt或者.cmake脚本文件中输入,且有提示,不区分大小写
- mode:打印消息的类别,有FATAL_ERROR,SEND_ERROR,WARNING,AUTHOR_WARNING,DEPRECATION,(none) or
- NOTICE
- ,STATUS,VERBOSE,DEBUG,TRACE共10种
- “message to display”:输出消息的内容,是字符串类型
- …:表示可变参数,可连接多个输出
2.2 mode说明
- FATAL_ERROR:cmake出错,停止编译和生成(信息红色)
- SEND_ERROR:cmake出错,继续编译,但是停止生成(信息红色)
- WARNING:cmake警告,继续编译(信息红色)
- AUTHOR_WARNING:开发者警告,继续编译(信息红色)
- DEPRECATION:如果使用set方法设置CMAKE_ERROR_DEPRECATED为true(不区分大小写),编译出错,否则继续编译
- (none) or
- NOTICE
- :不设置mode,默认是NOTICE模式,不影响编译和生成,用于打印消息(信息白色)
- STATUS:编译时状态信息,左边以
- --
- 开头(信息白色)
- DEBUG:针对开发人员的调试信息(信息白色)
- TRACE:日志级别的临时信息(信息白色)
判断环境变量是否定义
if(NOT DEFINED ENV{JAVA_HOME})
# 没有找到JAVA_HOME环境变量
message(FATAL_ERROR "not defined environment variable:JAVA_HOME")
endif()
if(NOT DEFINED JAVA_HOME)
# 没有找到JAVA_HOME环境变量
message(FATAL_ERROR "not defined environment variable:JAVA_HOME")
endif()