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

发布了104 篇原创文章 · 获赞 12 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/fpcc/article/details/102664881