在 Ubuntu 虚拟机上编译 libquic 遇到的错误及解决过程记录

  • 编译命令: -DCMAKE_BUILD_TYPE=Debug …

问题:

1、当前 cmake 版本:2.8.12.2

在位置 libquic/src/third_party/boringssl/src/CMakeLists.txt:403 出现错误:
Parse error. Expected “(”, got newline with text "
".
原因:该位置用了多行注释的语法 “#[[]]”,该语法在 cmake3.0+ 中才支持。
解决:手动使用单行注释 #。

2、Could not find Go

该机器未安装 Golang。
通过命令 cat /etc/os-release 查训到系统为 Centos 7,因此根据安装文档安装 golang.

3、Object library target “crypto” may not link to anything

依赖库 boringssl 依赖的 cmake 版本比较高,因此升级到 cmake 3.13。
升级过程请参考(博客](http://jotmynotes.blogspot.com/2016/10/updating-cmake-from-2811-to-362-or.html)。
我的完整执行过程如下:

sudo yum remove cmake
wget https://cmake.org/files/LatestRelease/cmake-3.13.0.tar.gz
tar -zxf cmake-3.13.0.tar.gz
cd cmake-3.13.0/
sudo ./bootstrap --prefix=/usr/local

至此 cmake 执行成功。

4、执行 make 时出错,unrecognized command line option ‘-std=gnu++14’

该选项 g++ 4.9+ 才支持。查看 g++ (GCC) 7.3.0 支持,编写 hello world 程序,
编译命令 g++ -std=gnu++14 test.cpp -o test, 成功编译。
排查到问题为系统存在多个 g++,默认采用最低版本。

sudo find / -name g++
/usr/local/bin/g++ # 7.3.0
/usr/bin/g++  # 4.8.5

解决:删除默认的 g++ 版本,并拷贝 7.3.0 的 g++、c++ 到 /usr/bin 目录下。

删除 build 目录下所有文件,重新执行 cmake -DCMAKE_BUILD_TYPE=Debug … 的编译命令。

5、make 时出错:libquic/src/base/debug/proc_maps_linux.cc:130:26: error: expected ‘)’ before ‘SCNxPTR’

出错位置的代码:

 if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4c %llx %hhx:%hhx %ld %n",
               &region.start, &region.end, permissions, &region.offset,
               &dev_major, &dev_minor, &inode, &path_index) < 7) {
      DPLOG(WARNING) << "sscanf failed for line: " << line;
      return false;
    }

查找到 SCNxPTR 是一个宏,用于整数格式控制,而搜索整个项目代码发现该宏未定义,
根据其在项目中的注释内容,

// In 32-bit mode, Bionic's inttypes.h defines PRI/SCNxPTR as an
// unsigned long int, which is incompatible with Bionic's stdint.h
// defining uintptr_t as an unsigned int:

可知,该宏定义在 inttypes.h 中。

定位到该头文件出现在:

/usr/include/inttypes.h
/usr/include/c++/4.8.2/tr1/inttypes.h

第一个有该宏的定义,而第二个没有,显然编译时找的是第二个文件。

解决:由于 g++ 是直接拷贝二进制执行文件,所以造成头文件不匹配,因此通过编译 g++ 源码来安装新版的 g++。
安装目录为 /usr/local;安装后发现 7.3.0/tr1/inttypes.h 中也没有 “SCNxPTR” 的宏。

然后找到出错文件所依赖的头文件的原始路径:确定引用的是定义了宏 SCNxPTR 的文件,/usr/include/inttypes.h
因此重新拷贝 linux 中成功编译了的 libquic 文件夹。
仍然出现一样的错误。

单独写一个测试文件:

  • 测试出错文件的包含方式是否成功包含了需要的头文件,经测试,确认包含了
  • 无条件包含该头文件,并打印里面所有宏的值:无法打印,提示符号未定义。
  • 发现同样的错误,在 Ubuntu1804 虚拟机上并未发生,怀疑是直接拷贝 g++ 文件的问题,为完全拷贝正确的可执行文件。
    因此重新安装 gcc 到目录 /usr 下。
    仍然是原来的错误。

最后只能怀疑是 inttypes.h 中的宏未起作用,也就是被开关控制着,而开关未打开,于是该宏未定义。
果然看到多余的一个 #if 语句,为了确认,只能比对成功编译的环境与虚拟机环境下的 inttypes.h 文件。
diff 发现果然成功编译的环境多了一行

#if !defined __cplusplus || defined __STDC_FORMAT_MACROS

在编译命令中增加一个宏 __STDC_FORMAT_MACROS,发现编译成功。
原因:该头文件属于 glibc,gilbc2.17 及之前的版本存在该宏开关,之后的版本取消了,详见博客的 Notes 部分。

解决:在 cmakelists.txt 中增加一个判断(使用 execute_process 执行 shell 子程序),若 glibc 版本小于等于 2.17,则打开宏开关,大于则不处理。

至此 libquic 编译安装成功。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值