- 项目目录结构
下面目录结构是一个经过实践的项目模板结构,麻雀虽小,五脏俱全。小伙伴们可以按此模板搭建自己的项目。├── build.sh
├── cmake
│ ├── config.cmake.in
│ ├── create-config.cmake
│ ├── hisi.toolchain.cmake
│ ├── rockchip.toolchain.cmake
│ ├── sigmastar.toolchain.cmake
├── CMakeLists.txt
├── include
│ ├── mymath.hpp
├── src
│ ├── CMakeLists.txt
│ ├── mymath.cpp
├── test
│ └── CMakeLists.txt
├── user.env
- 如何交叉编译
直接进入项目目录,运行目录下面的build.sh脚本,如下:
- 如何配置不同平台的交叉编译环境
只需要更改项目目录下的user.env文件,就可以实现不同平台的交叉编译。
- 海思平台dv300 user.env配置如下:
USER_TOOLCHAIN_FILE="/xxx/dv300.toolchain.cmake" # 平台交叉编译工具链
USER_PLATFORM_TYPE="hisi" # 平台类型
USER_PLATFORM_CHIP_TYPE="dv300" # 平台芯片类型
- 瑞芯微平台rv1109/rv1126 user.env配置如下:
USER_TOOLCHAIN_FILE="/xxx/rv1109.toolchain.cmake" # 平台交叉编译工具链
USER_PLATFORM_TYPE="rockchip" # 平台类型
USER_PLATFORM_CHIP_TYPE="rv1109" # 平台芯片类型
- 星辰平台ssd222d user.env配置如下:
USER_TOOLCHAIN_FILE="/xxx/ssd222d.toolchain.cmake" # 平台交叉编译工具链
USER_PLATFORM_TYPE="sigmatar" # 平台类型
USER_PLATFORM_CHIP_TYPE="ssd222d" # 平台芯片类型
- 公共配置
USER_BUILD_TYPE="Release" # 调试模式:Debug, 发布模式:Release
USER_CMAKE_GENERATOR="Ninja" # 编译加速
USER_BUILD_SHARED_LIBS=ON # 是否编译共享库 ON or OFF
- 项目顶层CMakeLists.txt
## 要求最小cmake版本
cmake_minimum_required(VERSION 3.10)
## 看系统是否安装ccache
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
message(STATUS "Set up ccache ...")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
else()
message(WARNING "ccache has not been found")
endif()
## 定义项目名称
project(
mymath
VERSION 0.1.0
DESCRIPTION "mymath libraries")
## 输出编译配置相关信息
message(STATUS "============================================================================")
message(STATUS "set CMAKE_MAKE_PROGRAM to: ${CMAKE_MAKE_PROGRAM}")
message(STATUS "set CMAKE_CURRENT_BINARY_DIR to: ${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "set CMAKE_CURRENT_SOURCE_DIR to: ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "set CMAKE_INSTALL_PREFIX to: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "set CMAKE_TOOLCHAIN_FILE to: ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "set PLATFORM_TYPE to: ${PLATFORM_TYPE}")
message(STATUS "set PLATFORM_CHIP_TYPE to: ${PLATFORM_CHIP_TYPE}")
message(STATUS "set CMAKE_BUILD_TYPE to: ${CMAKE_BUILD_TYPE}")
message(STATUS "set BUILD_SHARED_LIBS to: ${BUILD_SHARED_LIBS}")
message(STATUS "set THIRD_PARTY_PREFIX to: ${THIRD_PARTY_PREFIX}")
message(STATUS "============================================================================")
## 编译库实现代码
add_subdirectory(src)
## 编译测试代码
add_subdirectory(test)
## 创建库配置文件
include(cmake/create-config.cmake)
## 安装库头文件,若要增加库暴露的头文件,需要将暴露的头文件放入include目录
install(
DIRECTORY include
DESTINATION .
FILES_MATCHING
PATTERN "*.h" PATTERN "*.hpp")
- 编译脚本build.sh
#!/bin/bash
set -e
source_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
#读取用户编译配置
user_env_file="$source_dir/user.env"
if [ ! -f "$user_env_file" ]; then
echo -e "[Warning]: $user_env_file not exists, please copy $user_env_file.sample to $user_env_file and modify it"
else
. $user_env_file
fi
#编译目录
build_root_dir="$source_dir/build"
#安装目录
install_dir="$source_dir/install"
#编译类型
build_type=${USER_BUILD_TYPE:-"Release"}
#编译共享库
build_shared_libs=${USER_BUILD_SHARED_LIBS:-"OFF"}
#编译加速
cmake_generator=${USER_CMAKE_GENERATOR:-"Unix Makefiles"}
#工具链文件
toolchain_file=${USER_TOOLCHAIN_FILE:-"rv1109.toolchain.cmake"}
#平台类型
platform_type=${USER_PLATFORM_TYPE:-"rockchip"}
#芯片类型
platform_chip_type=${USER_PLATFORM_CHIP_TYPE:-"rv1109"}
#支持命令传参
for i in "$@"; do
case $i in
--toolchain_file=*)
toolchain_file="${i#*=}"
shift # past argument=value
;;
--clean)
clean_build="yes"
shift # past argument with no value
;;
--ninja)
cmake_generator="Ninja"
shift # past argument with no value
;;
*)
# unknown option
;;
esac
done
# 编译临时目录
build_dir=$build_root_dir/$platform_type/$chip_type/$build_type
mkdir -p "$build_dir" || true
mkdir -p "$install_dir/include" || true
mkdir -p "$install_dir/lib" || true
## 清除编译
if [[ $clean_build == "yes" ]]; then
echo "clean ..."
rm $build_root_dir -rf
rm $install_dir -rf
else
pushd "$build_dir"
cmake "$source_dir" -G "$cmake_generator" \
-DCMAKE_INSTALL_PREFIX="$install_dir" \
-DCMAKE_TOOLCHAIN_FILE="$toolchain_file" \
-DPLATFORM_TYPE="$platform_type" \
-DPLATFORM_CHIP_TYPE="$platform_chip_type" \
-DCMAKE_BUILD_TYPE="$build_type" \
-DBUILD_SHARED_LIBS="$build_shared_libs"
# 编译
cmake --build . --parallel
# 安装
cmake --build . --target install
popd
fi
- 交叉工具链cmake文件介绍
以下是一个通用的交叉工具链文件模板,用户一般只需要更改交叉工具链前缀、更改芯片平台架构、及更改c++相关编译配置。分别对应CROSS_PREFIX 、CROSS_COMPILATION_ARCHITECTURE 和CMAKE_CXX_FLAGS。下面是hisi dv300平台的cmake工具链文件。# set cross-compiled system type, it's better not use the type which cmake
# cannot recognized.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# when hislicon SDK was installed, toolchain was installed in the path as below:
# 更改工具链前缀,这里以hisi dv300 编译工具链为例子
set(CROSS_PREFIX arm-himix200-linux-)
set(CROSS_HOST arm-himix200-linux)
set(CMAKE_C_COMPILER ${CROSS_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${CROSS_PREFIX}g++)
# set searching rules for cross-compiler
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
## 根据不同平台的芯片架构来更改,比如arm的v7,v8架构等
set(CROSS_COMPILATION_ARCHITECTURE armv7-a)
# 更改c++相关配置
set(CMAKE_CXX_FLAGS
"-fpermissive -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -fopenmp ${CMAKE_CXX_FLAGS}"
)
# -fpermissive -Wno-unused-variable -Wno-unused-parameter -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4
# other settings
set(CMAKE_CXX_FLAGS "-DCV__EXCEPTION_PTR=0 ${CMAKE_CXX_FLAGS}")
- config.cmake.in和create-config.cmake内容介绍
可以参考CMake调用第三方库的两种方法,这里面有相关信息介绍。
#当前目录下的所有源文件存入_SRC_FILES变量
aux_source_directory(. _SRC_FILES)
#生成目标为mymath库,因为顶层项目名称为mymath
add_library(${PROJECT_NAME} ${_SRC_FILES})
#target_link_libraries(${PROJECT_NAME} PUBLIC spdlog)
# VERSION指代动态库版本,SOVERSION指代API版本
set_target_properties(
${PROJECT_NAME}
PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
target_include_directories(
${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
#安装目标
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)