知玩指南
白蓝主题五 · 清爽阅读
首页  > 驱动工具

更换编译环境后报错?别慌,这些坑我都踩过

最近帮同事调试一个老项目,本来顺顺利利的,结果他换了台电脑重装环境,一编译就报错,红得跟番茄酱似的。其实这种情况太常见了,尤其是从旧系统迁到新环境,或者团队协作时每个人用的工具链不一样,编译器版本、库路径、依赖版本稍微有点出入,立马就给你脸色看。

常见错误类型先认准

报错千奇百怪,但归类也就那几样:找不到头文件、链接失败、语法不兼容、宏定义冲突。比如你以前用 GCC 7 编译没问题,换到 GCC 11 就提示 -Werror=stringop-overflow 被当成错误直接中断,这就是编译器变严格了。

还有人从 Windows 换到 Linux 环境,路径分隔符写死成反斜杠,include 的时候直接炸锅:

#include \utils\common.h

改成正斜杠或者用预处理器判断平台才是正解:

#ifdef _WIN32
    #include <utils\\common.h>
#else
    #include <utils/common.h>
#endif

依赖库版本对不上最头疼

项目用了 OpenCV 3.4,新环境装了个 4.5,函数签名变了几个,cv::imread 多了个参数默认值倒还好,可要是用了废弃的 CV_BGR2GRAY 这种宏,编译器直接报未定义。这时候别急着删代码,先查文档看对应的新命名是什么,OpenCV 就把 CV_ 换成了 COLOR_ 开头。

更隐蔽的是动态库链接问题。本地编译通过,运行时报 libxxx.so.7: cannot open shared object file,八成是新环境装的库版本号变了,比如 libssl.so.1.1 变成了 .so.3。用 ldd 可执行文件 查依赖,再用 find /usr -name "libxxx*.so" 找实际路径,软链接一下就能临时救场。

Makefile 和 CMake 最容易“水土不服”

很多老项目用的 Makefile 里硬编码了编译器路径和库位置,换机器后 gcc 实际在 /usr/bin/gcc,而 Makefile 写的是 /opt/gcc-7/bin/gcc,自然找不到。建议改成自动探测:

CC := $(shell which gcc)

CMake 项目也别觉得高枕无忧。有的机器没装 ninja,只用了 make,生成器不一致可能导致编译顺序出问题。初始化时明确指定:

cmake -G "Unix Makefiles" ..

环境变量别忽略

特别是涉及 Java 或交叉编译的工具链,JAVA_HOMEANDROID_NDK_ROOT 这些没配,报错信息可能根本不提这些变量,而是说“找不到jni.h”,绕半天才发现是路径没对上。新环境搭好第一件事,把这些关键变量写进 ~/.bashrc~/.zshrc

字符编码也能搞事情

有个项目在 Windows 下用 GBK 写的中文注释,Linux 默认 UTF-8 编译,gcc 报一堆 syntax error。看着代码明明没错,就是过不了。用 file 源文件.c 看编码,再用 iconv 转一下就行:

iconv -f GBK -t UTF-8 source.c -o source_utf8.c

实在搞不清哪出问题,最笨也最有效的办法:把老环境的编译命令完整抓出来,用 make -n 或开启 CMake verbose 模式,对比新旧命令差在哪,逐项排查。