以前工作中单板构建结合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][文件或目录…]
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:
这将导致在下列地方使用包含的目录:
在创建将使用库的可执行文件时,必须告诉编译器有关库的信息。这可以使用 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([
] "message to display" ...) - message(DEBUG "message to display")
- message("message to display") # 编译的时候这里就打印出来
2.2 mode说明
判断环境变量是否定义
- 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()