cmake对编译器版本和库依赖的问题

cmake对编译器版本和库依赖的问题

一、介绍

最近在编译Wasm的几个相关工具时,其使用的是cmake工具,一般来说,开源的软件的编译文档会写的相当清楚,而且开源软件为了让客户体验方便,一般编译的步骤和依赖的相关工具和库,都会尽量整合到一起,防止因为无谓的原因导致编译问题影响软件的整体下载应用。
在编译相关的工具过程中,确实发现很多都基本可以做到两三到命令即可完成编译,也不需要下载过多的依赖。但是在编译的过程中,也遇到了一些问题,下面进行了分析和总结,以咨后鉴。

二、编译器版本控制

在编译一些相对比较老或者很新的c++软件时,可能在电脑上安装多个版本的Gcc编译器,这样就出现一个问题,在老的版本上编译新的软件依赖时,就会出现类似于下面的错误:“unrecognized command line option ‘-std=c++14’”。这很显,就是默认的编译器的版本比较老。但是让人郁闷的是,服务器上已经安装了最新的GCC9.1版。这肯定是默认的链接并没有指向新的版本。当初为了不影响虽的用户,确实也没有修改相关的配置文件。
执行cmake .命令:

CMake Warning:
  No source or binary directory provided.  Both will be assumed to be the
  same as the current working directory, but note that this warning will
  become a fatal error in future CMake releases.

-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
......

结果发现,竟然使用的是GCC4.8.5,路径在usr/bin下。而在安装9.1版本时,就已经知道安装在了/usr/local/bin下。如果在CMakeList.txt文档中将c++14修改成c++11,编译时就会报auto的使用方法不正确。这也再次验证了是c++编译器的版本的问题。
直接修改链接配置当然最简单,暴力。但是有可能影响其它使用的相关版本的软件,那么也可以使用类似环境变量的单次配置的效果,如下:

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/project

这时候儿再使用cmake命令:

$ export CC=/usr/local/bin/gcc
$ export CXX=/usr/local/bin/g++
$ cmake .
-- The C compiler identification is GNU 9.1.0
-- The CXX compiler identification is GNU 9.1.0
-- Check for working C compiler: /usr/local/bin/gcc
-- Check for working C compiler: /usr/local/bin/gcc -- works
......

这次发现,编译器的版本已经到达了最新的版本,这时候儿再make ,就会发现上述的编译错误,不再出现。这种方法非常适合于多人在服务器端共同编程或者在电脑上维护着多个版本的软件时使用。

三、库依赖问题

在编译成功后,在运行时,有些软件还会出现类似下面的问题:

version `GLIBCXX_3.4.26' not found

可能版本有所不同,但基本都是缺少相关的版本的运行库。可以用strings命令来看一下:

$ strings /usr/lib64/libstdc++.so.6 |grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.14
GLIBC_2.17
GLIBC_2.3.2
GLIBCXX_DEBUG_MESSAGE_LENGTH
__strtof_l@@GLIBC_2.2.5
_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4
fileno@@GLIBC_2.2.5
pthread_cond_destroy@@GLIBC_2.3.2
......

发现确实没有这个版本,那么去安装的最新版本处看一下:

$ strings /usr/local/lib64/libstdc++.so.6 |grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.14
GLIBC_2.6
GLIBC_2.4
GLIBC_2.16
GLIBC_2.17
GLIBC_2.3.2
GLIBCXX_DEBUG_MESSAGE_LENGTH
__strtof_l@@GLIBC_2.2.5
symlink@@GLIBC_2.2.5
......

在这里发现有这个最新的依赖库。使用的方法,仍然是推荐本次终端内使用的方式,配置一下环境变量:

$ echo $PATH
/home/xyz/.cargo/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/xyz/.local/bin:/home/xyz/bin
$ export LD_LIBRARY_PATH=/usr/local/lib64
$ echo $LD_LIBRARY_PATH
/usr/local/lib64
$ sudo ldconfig
[sudo] password for fanjinfeng:
ldconfig: /lib/libzstd.so.1 is not a symbolic link

有一个小的错误,可以不理会它。这样,再执行时,就没有问题了,但是如果关闭终端或者重启电脑后,仍然需要执行这些命令,当然,可以写成一个Shell脚本。看你的心情了。

四、总结

使用工具和直接使用GCC编译还是有一些不同,当然,解决这两类问题的方法还有其它的,但是分析的这两种是推荐的,既不影响大家,又可以放心使用。

### 如何在CMake中指定配置编译器CMake项目中,可以通过多种方式来设置目标平台的编译器。以下是几种常见的方法: #### 方法一:通过命令行参数传递 可以在调用 `cmake` 命令时直接通过 `-D` 参数指定所需的编译器路径或名称。例如,如果需要分别指定 C C++ 编译器,则可以执行如下命令[^1]: ```bash cmake -G "Your Generator" \ -D CMAKE_C_COMPILER=gcc-4.2 \ -D CMAKE_CXX_COMPILER=g++-4.2 \ /path/to/your/source ``` 上述命令中的选项解释如下: - `-G "Your Generator"` 表示选择特定的构建工具(如 Makefile 或 Ninja),具体可用生成器可通过运行 `cmake --help` 查看。 - `-D CMAKE_C_COMPILER=gcc-4.2` 设置用于处理 `.c` 文件的编译器为 GCC 版本 4.2。 - `-D CMAKE_CXX_COMPILER=g++-4.2` 则定义了针对 `.cpp` 文件使用的 G++。 #### 方法二:修改环境变量 另一种替代方案是调整系统的 PATH 变量或者临时覆盖默认行为,即预先设定 CC CXX 这两个标准环境变量指向期望版本的编译程序后再初始化 cmake 工程目录结构。比如,在 Unix shell 中可这样操作[^2]: ```bash export CC=/usr/bin/gcc-7 export CXX=/usr/bin/g++-7 cmake .. ``` 这里设置了新的 GNU Compiler Collection (GCC) 的第七版作为当前会话期间唯一认可的选择之一;之后再继续常规流程即可完成整个项目的准备阶段工作而无需额外干预其他部分细节内容。 #### 方法三:利用 toolchain file 配置文件实现自动化管理 对于跨平台开发场景下更为复杂的依赖关系控制需求来说,创建专属于某个特殊硬件架构下的交叉编译链路可能更加合适一些。此时就可以考虑编写自定义 Toolchains Script 来集中存储这些定制化属性值并简化后续重复劳动过程。下面给出一个简单的例子展示如何声明 ARM Cortex-M 系列微控制器所对应的 Keil MDK-Arm 软件包内的 arm-none-eabi-gcc 工具集位置信息[^3]: ```cmake set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR ARM) # Set compilers to use. set(CMAKE_C_COMPILER "/Applications/Keil_v5/ARMCompiler6/bin/armclang.exe") set(CMAKE_CXX_COMPILER "/Applications/Keil_v5/ARMCompiler6/bin/armclang++.exe") # Where is the target environment located? set(CMAKE_FIND_ROOT_PATH "") # Adjust default behavior of FIND_XXX() commands: set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ``` 最后一步就是把上面保存成名为 something.toolchain.cmake 的纯文本文档形式存放到易于访问的地方以后每次只需要加上额外的一个开关就可以了: ```bash cmake -DCMAKE_TOOLCHAIN_FILE=<path-to-toolchain>/something.toolchain.cmake ../source/ ``` 以上三种途径均能有效达成更改底层引擎的目的,开发者可以根据实际应用场景灵活选用最适合自己的那一种策略组合起来运用到日常工作中去提升效率减少错误发生几率的同时也方便团队成员之间相互协作交流经验教训共同进步成长壮大队伍实力水平!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值