我有一个之前编译过的c++程序,但在修改了Jamfiles后,该程序不再编译,并且ld
发出了一个duplicate symbol error
。即使我还原到原始Jamfiles,运行bjam clean
,手动删除对象文件,并从clang切换到gcc 4.2.1 on MacOs 10.6.7,问题仍然存在。
简化程序描述如下:有main.cpp
和四个文件a.h,cpp
和b.h,cpp
,它们被编译成一个静态库,该库链接到main.o
。 main.cpp
和b.cpp
都依赖于包含有冲突符号off.h
的文件,但是两个中间文件依赖于不同的off.h
版本,而a.h
和a.cpp
则没有任何依赖关系。
在你询问之前,我确保所有文件都包含了多重定义守卫(#ifndef
, #define
, #endif
),并且虽然我发现有一个文件缺少了这些守卫,但它没有引用off.h
。更重要的是,b.h
没有包含任何引用off.h
的内容,只有实现b.cpp
对off.h
进行了引用。这让我感到困惑。
更加令我困惑的是,我能够从b.cpp
中删除对off.h
的引用,并且如预期一样成功重新编译。然而,当我将引用添加回去时,它也成功编译,并在清除对象文件后继续编译。由于符号不应该冲突,我已经避免了符号重复,也已经清除了任何之前/不完全的构建,因此我仍然不知道为什么它无法编译。
我已经成功编译了我的程序,因此我怀疑我是否能够再现它以测试任何建议。然而,我对于这种情况的发生感到好奇,如果将来我遇到这种行为,除了我已经做过的事情之外,我还可以做什么来修复它呢?
bjam clean
或rm *.o *.a
删除了所有对象和库文件。如果没有被删除,那么在重新编译时它们应该已经被覆盖了。此外,默认情况下,当您更改编译器时,bjam会在不同的目录中进行编译,因此由libtool或其他工具进行的任何缓存都会使这种分离变得毫无意义。此类缓存会让我觉得很难创建可靠的构建,这是相当令人反感的。 - rcollyergit clean -dfx
(警告:这将会清除git未跟踪的任何文件,不询问,无例外) - bdonlanrm -f
或操作系统的等效命令,而我正在使用Mercurial作为我的版本控制系统,它具有清除功能。 - rcollyer