当前位置: 首页> 教育> 锐评 > 北京南站属于哪个街道_知乎有趣的网站_百度一下就知道首页_企业网络营销系统分析报告

北京南站属于哪个街道_知乎有趣的网站_百度一下就知道首页_企业网络营销系统分析报告

时间:2025/7/13 15:10:08来源:https://blog.csdn.net/m0_37565736/article/details/141268681 浏览次数:0次
北京南站属于哪个街道_知乎有趣的网站_百度一下就知道首页_企业网络营销系统分析报告

文章目录


老规矩,先放官方文档

如何构建从互联网下载的源代码包:User Interaction Guide

想使用第三方库的开发者:Using Dependencies Guide

使用cmake创建编译系统:CMake Tutorial

交叉编译章节:cmake cross-compiling

以下是一些零散判断的整理,等以后有空了再慢慢优化

cmake使用举例

一个典型的编译命令:

cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local \
-DOPENSSL_INCLUDE_DIR=/usr/local/openssl/include/ \
-DOPENSSL_SSL_LIBRARY=/usr/local/openssl/lib64/libssl.so \
-DOPENSSL_CRYPTO_LIBRARY=/usr/local/openssl/lib64/libcrypto.so \
-DLIBSSH_INCLUDE_DIRS=/usr/local/libssh/include/ \
-DLIBSSH_LIBRARIES=/usr/local/libssh/lib/libssh.so ..

对应文件:

drwxrwxr-x 12 wsl wsl     4096 Aug 16 20:13 libnetconf2-3.3.3
drwxrwxr-x 10 wsl wsl     4096 Aug 16 20:39 libssh-0.11.0
drwxrwxr-x 12 wsl wsl     4096 Aug 16 20:10 libyang-3.1.0
drwxrwxr-x 20 wsl wsl     4096 Aug 16 20:24 openssl-openssl-3.0.9
drwxrwxr-x 11 wsl wsl     4096 Aug 16 20:10 pcre2-pcre2-10.44

cmake示例模板

# cmake 的版本要求,不用修改
cmake_minimum_required(VERSION 3.0.0)# 修改 vsf_config 为自己的工程名
project(vsf_config VERSION 0.1.0)#支持自定义变量,比如指定平台
set(PLAT "ssc325")#指定编译器
set(CMAKE_C_COMPILER "arm-linux-gcc")# 源码路径,两种方式,均支持变量来控制子目录
#1、递归包含某目录及子目录的所有源码文件
file(GLOB_RECURSE PLAT_SRCS src/${PLAT}/*.c)
#2、不递归,只包含某文件夹下的文件
aux_source_directory(src/common COM_SRCS)# 添加头文件目录,支持用变量来区分平台
# Tips: 快速罗列 include 下子目录的方法
# find include/ -path "*.svn*" -prune -o -type d -print
include_directories(includeinclude/${PLAT}include/commoninclude/common/osainclude/ivfinclude/palinclude/vsf/config/include/vsf/include/vsf/drvinclude/sensor/src/config/${PLAT}/incinclude/pdi
)#添加宏定义
add_definitions(-DSVN_NUM=-1)
add_definitions(-DOSA_MODULE_NAME="${PROJECT_NAME}")#从源码生成静态库
add_library(${PROJECT_NAME} ${COM_SRCS} ${PLAT_SRCS})#生成 compile_commands.json ,不用修改
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

编译时库查找

基础知识

find_package有三种来查找依赖的包:模块模式,配置模式,内容获取重定向模式。模块模式中,会搜寻Find.cmake文件用来查找库。配置模式中,会查找-config.cmake 或 Config.cmake文件,这些文件一般是依赖包自身提供的,比如usr/lib/cmake/libssh/libssh-config-version.cmake

模块模式

使用find_package来查找库,以libyang依赖的libpcre2为例:

# find PCRE2 library
unset(PCRE2_LIBRARY CACHE)
find_package(PCRE2 10.21 REQUIRED)
include_directories(${PCRE2_INCLUDE_DIRS})
target_link_libraries(yang ${PCRE2_LIBRARIES})

CMake将尝试去寻找Find.cmake文件,在libyang的例子中FindPCRE2.cmake是开源包本身提供的。其中又进一步的使用find_path和find_library来查找头文件路径和库路径,并赋值到了相关变量中。怀疑这种方式是非交叉编译时使用的。

在交叉编译时,可能不使用开源包提供的Find.cmake文件,因此使用的是cmake自己的:/usr/local/share/cmake-3.30/Modules/FindOpenSSL.cmake
在结合了工具链文件进行交叉编译时,实际使用时会出现构建时,编译正常,链接报错:warning: libcrypto.so.3, needed by …/lib/libssh.so.4.10.0, not found (try using -rpath or -rpath-link)。将上层的CFLAGS与LDFLAGS引入解决了此问题。

CFLAGS=-I/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/include
-I/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/include/libxml2
-I/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/include
LDLAGS=-L/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/lib
-L/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/lib64
-L/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/lib
-L/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/lib64
-Wl,-rpath-link=/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/lib
-Wl,-rpath-link=/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/lib64
-Wl,-rpath-link=/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/lib
-Wl,-rpath-link=/home/344272/svn/GNOS/Trunk/src_2406/output/linux-arm64/usr/lib64
-L/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib
-L/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib64
-L/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib
-L/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64
-Wl,-rpath-link=/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib
-Wl,-rpath-link=/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib64
-Wl,-rpath-link=/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib
-Wl,-rpath-link=/usr/local/xtools/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64

最终的mk文件如下:

3RD_LIBNETCONF2_VERSION := 3.3.3
3RD_LIBNETCONF2 := $(TARGET_BUILD_3RD)/libnetconf23RD_LIBNETCONF2_OPTS := -DCMAKE_INSTALL_PREFIX=$(3RD_INSTALL_PREFIX)
3RD_LIBNETCONF2_OPTS += -DCMAKE_BUILD_TYPE="Release"
3RD_LIBNETCONF2_OPTS += -DCMAKE_TOOLCHAIN_FILE=$(MK_ROOT)/aarch64-none-linux-gnu.toolchain.cmake3RD_UNINSTALL_SEPCIAL_TARGETS += 3rd-libnetconf23rd-libnetconf2:@$(call display_start,Build libnetconf2)$(Q)$(call decompress,$(@:3rd-%=%),$(3RD_LIBNETCONF2_VERSION),$(TARGZ))$(MKD) $(3RD_LIBNETCONF2)/$(CMAKEBUILDDIR)cd $(3RD_LIBNETCONF2)/$(CMAKEBUILDDIR) && CFLAGS="$(3RD_CFLAGS)" LDFLAGS="$(3RD_LDFLAGS)" cmake ../ $(3RD_LIBNETCONF2_OPTS)cd $(3RD_LIBNETCONF2)/$(CMAKEBUILDDIR) && make@$(call display_end,Build libnetconf2)uninstall-3rd-libnetconf2:@$(call display_start,Uninstall $(@:uninstall-3rd-%=%))-$(RM) $(3RD_INSTALL_PREFIX)/lib/libnetconf2.so*-$(RM) $(3RD_INSTALL_PREFIX)/lib/pkgconfig/libnetconf2c.pc-$(RM) $(3RD_INSTALL_PREFIX)/include/libnetconf2@$(call display_end,Uninstall $(@:uninstall-3rd-%=%))

导入目标

配置文件和Find模块文件都可以定义导入目标。这些目标通常具有形式为SomePrefix::ThingName的名称。如果有这些目标可用,工程应该优先使用它们,而不是可能提供的任何CMake变量。这些目标通常携带使用要求和应用诸如头文件查询路径、编译程序定义等的内容,自动应用到链接到它们的其他目标上(例如使用target_link_libraries())。这比尝试手动使用变量应用相同的内容更加稳健和方便。请查看包或Find模块的的文档,了解它定义了哪些导入目标(如果有的话)。

导入目标还应封装任何特定于配置的路径。这包括二进制文件(库、可执行文件)的位置、编译程序标志和任何其他配置相关的数量。与配置文件相比,Find模块在提供这些细节方面可能不太可靠。
一个比较复杂的查找并使用三方库的例子如下:

cmake_minimum_required(VERSION 3.10)
project(MyExeProject VERSION 1.0.0)# Make project-provided Find modules available
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")find_package(SomePackage REQUIRED)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE SomePrefix::LibName)

请注意,上述调用find_package()的处理可以通过配置文件或Find机制来解决。它仅使用Basic签名支持的基本参数。例如,在${CMAKE_CURRENT_SOURCE_DIR}/cmake目录中的FindSomePackage.cmake文件可以使find_package()命令在机制模式下成功。如果没有这样的机制文件存在,则系统将搜索配置文件。

交叉编译配置

基础知识

如果使用cmake命令行参数–toolchain path/to/file或-DCMAKE_TOOLCHAIN_FILE=path/to/file调用cmake,文件将会被提前加载以收集编译器的值。当CMake进行交叉编译时,CMAKE_CROSSCOMPILING变量被设置为true。

请注意,在工具链文件中使用CMAKE_SOURCE_DIR或CMAKE_BINARY_DIR变量通常是不可取的。工具链文件在不同的上下文中使用这些变量时,这些变量的值会有所不同(例如,作为try_compile()调用的一部分)。在大多数情况下,在工具链文件中需要评估路径时,更合适的变量是CMAKE_CURRENT_LIST_DIR,因为它始终具有明确且可预测的值。

模板

一个典型的linux交叉编译工具链如下:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)#CMAKE_FIND_ROOT_PATH不能使用相对路径
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

解释:
CMAKE_SYSTEM_NAME
是要构建的目标平台的CMake标识符。

CMAKE_SYSTEM_PROCESSOR
是要构建的目标架构的CMake标识符。

CMAKE_SYSROOT
是可选的,如果有sysroot可用,则可以指定。

CMAKE_STAGING_PREFIX
也是可选的。它可以用于指定要安装到的路径。即使在交叉编译时,CMAKE_INSTALL_PREFIX始终是运行时安装位置。

CMAKE__COMPILER
变量可以设置为完整路径,或者设置为要在标准位置查询的编译器名称(即在PATH路径下的编译器名字,不用写路径了)。对于不支持在没有自定义标志或脚本的情况下链接二进制文件的工具链,可以将CMAKE_TRY_COMPILE_TARGET_TYPE变量设置为STATIC_LIBRARY,告诉CMake在其检查过程中不要尝试链接可执行文件。

CMake find_* 命令将在 sysroot 和 CMAKE_FIND_ROOT_PATH 条目中默认情况下查找,同时也会在被访问系统的根前缀中查找。虽然这可以在每种情况下进行控制,但在交叉编译时,可以排除在被访问系统或目标系统中查找特定的构件。通常,应该在目标系统前缀中找到头文件包含路径、库和软件包,而必须作为构建的一部分运行的可执行文件只应该在被访问系统上找到,而不是在目标系统上找到。这就是 CMAKE_FIND_ROOT_PATH_MODE_* 变量的目的。

实际使用

此cmake工具链文件可放在CMakeLists.txt同级目录下,交叉编译时,只需在非交叉编译命令中添加参数即可,比如原来是cmake …,交叉编译时命令为cmake -DCMAKE_TOOLCHAIN_FILE=…/toolchain.cmake … 。交叉编译进程和交叉编译三方库都是这个流程

使用实例

链接库

$ cat CMakeLists.txt 
cmake_minimum_required(VERSION 3.10)
project(Test)
set(GNOS_SRC "/Trunk/src_2406/")
link_directories(${GNOS_SRC}/output/linux-arm64/usr/lib ${GNOS_SRC}/output/linux-arm64/usr/lib64)
add_executable(test main.c)
include_directories(${GNOS_SRC}/output/linux-arm64/usr/include)
target_link_libraries(test netconf2 yang pcre2-8 curl ssh ssl crypto zstd pam audit cap-ng pthread  z)

解决符号冲突

一个同时链接静态动态库的例子,使用了两个不同版本的同名函数

#CMakeLists.txt 
cmake_minimum_required(VERSION 3.10)# 设置项目名称
project(MyProject)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") # 创建静态库
add_library(a2 STATIC liba2.c)# 创建静态库
add_library(a STATIC liba.c)
target_link_libraries(a PRIVATE a2)# 创建动态库
add_library(so2 SHARED libso2.c)# 创建动态库
add_library(so SHARED libso.c)
#-Wl,--exclude-libs,ALL会排除静态库所有符号
target_link_libraries(so PUBLIC -Wl,--exclude-libs,ALL so2)# 创建可执行文件
add_executable(my_executable main.c)# 链接库到可执行文件
target_link_libraries(my_executable PRIVATE a so)
# 添加安装规则
install(TARGETS my_executable DESTINATION .)
install(TARGETS a DESTINATION .)
install(TARGETS a2 DESTINATION .)
install(TARGETS so DESTINATION .)
install(TARGETS so2 DESTINATION .)# 指定安装目录
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/out")

对应文件:

$ find . -maxdepth 1 -name "*.c"  -exec sh -c 'for file; do echo "==> $file <=="; cat "$file"; done' sh {} +
==> ./libso.c <==
extern int testc();
int testso()
{return testc();
}
==> ./liba2.c <==
int testc()
{return 1;
}
==> ./main.c <==
extern int testa();
extern int testso();
#include<stdio.h>int main()
{int ret = 0;ret = testa();printf("test : %d\n",ret);ret = testso();printf("test2 : %d\n",ret);return 0;
}
==> ./liba.c <==
extern int testc();
int testa()
{return testc();
}
==> ./libso2.c <==
int testc()
{return 2;
}

参考资料

一个交叉编译项目的模板:一个基于cmake跨平台交叉编译项目模板

一个交叉编译的例子:CMake应用:交叉编译

一个链接动态库交叉编译进程的例子:嵌入式linux: 使用Cmake交叉编译tslib库

额外的配置参数解释:CMake交叉编译配置 - Ricky.K - 博客园 (cnblogs.com)

关于系统变量与cmake变量,里面还包含了一个使用动态库的例子:CMake默认环境变量及选择编译器和设置编译器选项_cmake指定编译器-CSDN博客

CMAKE_SYSROOT和CMAKE_FIND_ROOT_PATH的区别:CMAKE_SYSROOT和CMAKE_FIND_ROOT_PATH的区别

cmake中add_library、target_link_libraries、include_directories的使用:cmake中add_library、target_link_libraries、include_directories的使用

CMake是不是阻碍了C++的发展?

全网最细的CMake教程!
CMake 良心教程,教你从入门到入魂
理解cmake 中 PRIVATE、PUBLIC、INTERFACE 的含义和用法

关键字:北京南站属于哪个街道_知乎有趣的网站_百度一下就知道首页_企业网络营销系统分析报告

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: