- 编译命令: -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",
®ion.start, ®ion.end, permissions, ®ion.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 编译安装成功。