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

本文深入探讨了使用CMake进行编译时遇到的编译器版本和库依赖问题,包括如何通过环境变量配置指定正确的GCC版本,以及解决运行时因库版本不匹配导致的错误。

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编译还是有一些不同,当然,解决这两类问题的方法还有其它的,但是分析的这两种是推荐的,既不影响大家,又可以放心使用。

<think>首先,用户的问题是:“我想查找使用CMake指定编译器将Google Test编译为静态的方法。请问使用CMake指定编译器编译Google Test为静态的方法?” 我需要基于提供的引用之前的系统指令来回答。系统指令包括: - 所有行内数学表达式用 $...$ 格式。 - 独立公式用 $$...$$ 格式。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如 [^1]。 提供的引用是: - 引用[1]: 关于CMake检查系统信息编译器的方法。 - 引用[2]: Windows下CMake指定编译链的方式,包括使用 -DCMAKE_TOOLCHAIN_FILE -G 选项。 - 引用[3]: CMake设置启用Intel编译器编译C++代码的方法。 用户的需求是使用CMake指定编译器来编译Google Test为静态。Google Test通常指的是Google的单元测试框架googletest。 关键点: - 编译为静态:通常涉及设置构建选项来静态链接。 - 使用CMake指定编译器CMake中指定编译器可以在配置阶段通过命令行参数或CMakeLists.txt设置。 从引用中提取相关信息: - 引用[2]提到使用 -G 选项指定生成器的类型(如"MinGW Makefiles") -DCMAKE_TOOLCHAIN_FILE 来指定工具链文件。 - 引用[3]展示了在CMakeLists.txt中使用 set(CMAKE_GENERATOR_TOOLSET ...) 来设置编译器工具集。 Google Test通常是一个CMake项目,所以我们需要在CMake配置中指定编译器。 标准方法: 1. **指定编译器命令行**:在运行cmake命令时,可以使用环境变量(如CCCXX)或命令行选项指定编译器。例如,在Linux上,可以使用 `cmake -DCMAKE_C_COMPILER=/path/to/cc -DCMAKE_CXX_COMPILER=/path/to/c++ ..`。 2. **使用工具链文件**:对于跨平台或在特定环境设置编译器,使用工具链文件。这在引用[2]中提到。 3. **编译为静态**:对于googletest,默认可能编译为静态或动态。在CMake中,通常可以通过选项控制。googletest的CMakeLists.txt提供了 BUILD_SHARED_LIBS 选项来设置类型。 具体到googletest: - 下载googletest源代码。 - 在CMake配置中设置编译器并指定 BUILD_SHARED_LIBS=OFF 来编译为静态。 - 使用命令行或工具链文件指定编译器。 步骤概述: 1. 创建一个构建目录。 2. 运行cmake命令,指定编译器路径选项。 - 例如:`cmake -DCMAKE_CXX_COMPILER=/path/to/c++ -DBUILD_SHARED_LIBS=OFF /path/to/googletest` 3. 构建:`cmake --build .` 在Windows上,引用[2]提到可能需要使用 -G 选项指定生成器类型。 googletest的官方文档可能推荐使用add_subdirectory或ExternalProject模块,但这里是关于编译本身。 集成到用户项目时,用户可能想静态链接googletest。 现在,回答需要用中文。 结构清晰:一步步解决问题。 生成相关问题:在末尾添加相关问题列表。 添加引用标识:如果在回答中引用了段落,添加 [^1], [^2] 等。这里的引用是用户提供的引用[1], [2], [3],我需要自然地引用它们。 例如,在讨论指定编译器时,引用参考中的信息。 回答结构: 1. 介绍:简要说明用户需求。 2. 步骤:详细描述如何使用CMake指定编译器编译googletest为静态。 - 前提:下载googletest源代码。 - 方法1: 通过命令行指定编译器。 - 方法2: 使用工具链文件。 - 确保编译为静态:设置 BUILD_SHARED_LIBS=OFF。 - 引用相关部分。 3. 示例命令:给出命令行示例。 4. 结束:确认方法。 5. 相关问题:生成几个相关问题。 确保语言自然。 相关问题例子: 1. 如何验证编译器是否设置成功? 2. CMake中如何处理不同平台的兼容性? 3. 如何在没有根权限的情况下指定编译器? 4. Google Test静态的优缺点是什么? 5. CMake的其他选项如何影响构建? 现在,结合引用: - 当提到使用命令行指定编译器时,引用引用[2]关于 -G -DCMAKE_TOOLCHAIN_FILE。 - 当提到设置工具集时,引用引用[3]。 - 引用[1]是关于系统信息的,可能不直接相关,但可以说如果需要检查编译器信息,可以用那个命令。 最终回答。 </think>以下是针对您查询的详细解答:使用CMake指定编译器将Google Test编译为静态的方法。Google Test(也称为googletest)是一个流行的C++单元测试框架。编译为静态(例如 `.a` 文件在Linux或 `.lib` 在Windows)可以简化依赖管理,并确保测试代码在链接时无需外部文件。我将一步步解释实现方法,基于CMake的通用最佳实践您提供的引用信息(特别参考了引用[2]引用[3]关于指定编译器的方式)。整个过程包括下载源代码、配置CMake选项、指定编译器路径,以及设置类型。 ### 步骤1: 准备环境 在开始前,确保您已完成以下准备工作: - **下载Google Test源代码**:从官方仓克隆或下载源码(推荐使用Git): ```bash git clone https://github.com/google/googletest.git cd googletest ``` - **创建构建目录**:在源码目录外创建单独的构建目录,以避免污染源码: ```bash mkdir build && cd build ``` - **确保CMake版本兼容**:Google Test要求CMake 3.14或更高版本。您可以检查版本: ```bash cmake --version ``` ### 步骤2: 使用CMake指定编译器并编译为静态CMake中指定编译器有两种主要方式:**命令行参数直接指定**或**工具链文件(toolchain file)**。编译为静态需设置 `BUILD_SHARED_LIBS=OFF` 选项。以下分方法说明,每种方法都适用于Windows、Linux或macOS平台。 #### 方法1: 通过命令行参数直接指定编译器(推荐简单场景) 此方法在运行 `cmake` 命令时使用 `-D` 选项定义编译器路径类型。这是最直接的方式,尤其适合快速测试。 - **Linux/macOS 示例**: - 指定GCC或Clang编译器: ```bash cmake -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DBUILD_SHARED_LIBS=OFF ../googletest ``` 这里,`/usr/bin/gcc` `/usr/bin/g++` 是编译器路径(替换为您的编译器路径)。`-DBUILD_SHARED_LIBS=OFF` 强制生成静态。 - 构建: ```bash cmake --build . # 编译所有目标 ``` 编译完成后,静态文件(如 `libgtest.a` )会输出到构建目录。 - **Windows 示例**: - 指定MinGW或MSVC编译器(例如,使用MinGW编译器): ```powershell cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DBUILD_SHARED_LIBS=OFF ../googletest ``` 在Windows上,必须使用 `-G` 选项指定生成器类型(如 "MinGW Makefiles"),以避免与MSVC冲突(这与引用[2]中描述的 `-G` 选项一致)[^2]。 - 构建: ```powershell cmake --build . --config Release # Release模式优化性能 ``` 输出静态文件(如 `gtest.lib` )。 #### 方法2: 使用工具链文件指定编译器(推荐复杂或跨平台场景) 对于需要多次复用或特定环境设置(如自定义工具链),创建工具链文件更灵活。这与引用[2]中提到的 `-DCMAKE_TOOLCHAIN_FILE` 方法一致[^2]。 - **创建工具链文件**:新建一个文件(如 `my_toolchain.cmake`),内容指定编译器路径选项: ```cmake # my_toolchain.cmake set(CMAKE_C_COMPILER "/path/to/your/c_compiler") # e.g., /usr/bin/clang on Linux set(CMAKE_CXX_COMPILER "/path/to/your/cxx_compiler") # e.g., /usr/bin/clang++ on macOS set(BUILD_SHARED_LIBS OFF) # 强制编译为静态 ``` - 在Windows上,如果使用Intel编译器,可以结合引用[3]中的工具集设置(如 `set(CMAKE_GENERATOR_TOOLSET "Intel C++ Compiler 2022")`)[^3],但通常编译器路径已足够。 - **运行CMake时引用工具链文件**: ```bash cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/my_toolchain.cmake ../googletest ``` 然后构建: ```bash cmake --build . ``` ### 关键注意事项 - **验证编译器设置**:CMake配置后,检查输出日志以确保指定编译器已生效(例如,查找 `-- The C compiler identification is GNU` )。如果需要调试编译器信息,可以使用 `cmake --system-information` 命令导出系统详情(如引用[1]所述,运行 `cmake --system-information information.txt` 可生成报告文件)[^1]。 - **Google Test特定选项**: - Google Test的CMakeLists默认支持静态,但 `BUILD_SHARED_LIBS=OFF` 是必需的。如果未设置,默认可能编译为动态。 - 其他选项如 `gtest_build_tests=OFF` 可禁用测试编译以加速构建。 - **平台差异**: - Windows:使用 `-G` 指定生成器(如 "Ninja" 或 "Visual Studio 17 2022"),否则可能默认MSVC(示例见引用[2])[^2]。 - Linux/macOS:环境变量 `CC` `CXX` 也可指定编译器(例如 `export CC=/usr/bin/clang` 后再运行CMake)。 - **编译器兼容性**:确保编译器支持C++11或更高标准(Google Test要求)。如果遇到错误,添加 `-DCMAKE_CXX_STANDARD=11` 到CMake命令。 ### 完整示例命令 假设在Linux上用GCC编译: ```bash # 克隆源码 git clone https://github.com/google/googletest.git mkdir gtest-build && cd gtest-build # 配置CMake:指定编译器并设置静态 cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DBUILD_SHARED_LIBS=OFF ../googletest # 编译 cmake --build . --target gtest # 只编译gtest ``` 编译后,静态(如 `libgtest.a` )位于 `lib/` 子目录。 ### 结论 通过上述方法,您可以成功使用CMake指定任意编译器(如GCC、Clang、MSVC或Intel)并将Google Test编译为静态。推荐从命令行参数开始(方法1),对高级需求使用工具链文件(方法2)。如果您需要进一步的优化(如链接时优化),可以在CMake命令中添加额外标志如 `-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值