C++ Lib文件和定义

C++ Lib文件和定义,c++,compiler-construction,linker,c-preprocessor,C++,Compiler Construction,Linker,C Preprocessor,我正在使用几个外部库,我不希望将它们的所有源代码和头文件都包含在我的主源代码目录或项目文件中。一种选择是将库编译为lib文件并像那样链接它们。但是我不确定在创建lib文件之前或之后对定义进行评估(它是哪一个?)。如果是在那之前,显然我不能仅仅打包它们,因为它们可能无法在不同的编译器或系统上正常工作 因此,如果我不能将库打包为lib文件,有没有办法链接到c或cpp源文件中?可能不会,因为它们必须先编译,但也许我错了 编辑:下面是一个基于答案的后续问题。你认为创建lib文件的makefile会太麻烦

我正在使用几个外部库,我不希望将它们的所有源代码和头文件都包含在我的主源代码目录或项目文件中。一种选择是将库编译为lib文件并像那样链接它们。但是我不确定在创建lib文件之前或之后对定义进行评估(它是哪一个?)。如果是在那之前,显然我不能仅仅打包它们,因为它们可能无法在不同的编译器或系统上正常工作

因此,如果我不能将库打包为lib文件,有没有办法链接到c或cpp源文件中?可能不会,因为它们必须先编译,但也许我错了


编辑:下面是一个基于答案的后续问题。你认为创建lib文件的makefile会太麻烦吗?我仍然不想将源代码添加到我的项目或源代码目录中。

define
s即使在编译之前也要进行评估。它们由预处理器处理,预处理器准备代码供编译器使用。是的,在创建库之前对它们进行评估

您不能链接源代码。只能链接到对象文件、静态库或动态库(共享对象文件/DLL)


使用动态链接是一个很好的选择,特别是当外部文件很大和/或您将在许多可执行文件中使用它们时。

库是一个二进制文件,所以所有定义显然都已经在中了

为了确定顺序,将定义作为编译过程的第一阶段进行计算,这一步骤称为预处理。在此阶段,对于创建的每个cpp文件,一个文件包含递归地在其文件中添加的所有
#include
,并计算所有宏

无论如何,第三方都不应该依赖于您的编译标志,只有一个例外——发布/构建库。只有在这种情况下,您才需要2个版本的第三个库

至于是否在编译代码时编译第三方LIB一次或每次的问题,这取决于。如果你只是为自己而做,而不是做看起来容易的事情,但是如果我们谈论的是开发团队和需要长期维护的项目,那么就要考虑更多的事情

所以我们讨论的是一个团队的一些解决方案,我们想多次编译这个库

在这种情况下,我个人努力编译第三部分库一次,并多次使用它。这减少了每个开发人员每个构建的编译时间,这意味着更快的开发

很好,但是你把这些LIB放在哪里。我喜欢Physycal分离-第三方库和我的代码不在同一棵树中。这可以避免一些非故意的错误。一个好的构建系统,大多数时候是强制性的,应该是可重构的。这意味着,如果您年复一年地签出代码,您可以编译并接收完全相同的二进制文件

有一次我在我的机器上使用了一些外部只读树。这棵树只由我管理。 为了使我的源代码可以重新构建,每个第三方库的下一个版本都放在包含它的版本的目录中,并且我的源代码树被更新到这一点。如果您在多台机器上构建,那么在所有这些机器上都应该可以看到只读树


另外一个解决方案是检查您的SCM工具(我想您使用了一个)是否能够在一次检查中组合来自存储库的多个子尝试。对于每个第三方库,都有一个子树。这样,您构建的所有计算机上都可以使用第三方库。我现在在subversion上使用这些方法-它被称为svn:external。在CVS AFAIK上,它被称为CVS模块。另外一个优点是库由源代码管理系统管理,因此您可以跟踪对第三方库所做的所有更改。

您必须包含头,以允许编译使用库方法/定义的代码。@Drakosha是的,我真的必须每次都显式吗?如果使用的是lib文件,我想可以安全地假设它们知道头是如何工作的谢谢你的详细回答。将源代码树与包含外部依赖项的树分离是我试图完成的另一件事。