如何每次在 c++11 和 c++98 的单个构建中使用 cmake 2.8.2 来创建共享库时重新编译源文件?

How to recompile source file every time while using cmake 2.8.2 in single build for c++11 and c++98 for shared library creation?

我的项目目录结构为:

Root
  Source
    Common
      MyFolder
      ++ My 3 source files and header 

当我构建我的项目时,它会生成 3 到 4 个共享库。 Lib1 使用 c++98 编译,其他使用 c++11。标志被添加到位于根目录的 CmakeList.txt 中。 我需要为 Lib1 和其他库编译我的 3 个源文件。但是这里发生的事情是编译器首先使用 c++11 为 lib 编译我的源文件,然后它也尝试为 Lib1 使用相同的 .o 文件。因此,对于使用 c++11 生成的 .o 文件,当将其用于 c++98 编译库时会抛出异常。

那么如何在 CmakeList.txt 中编写这样的编译器而不是尝试使用相同的 .o 文件将为 Lib1(c++98 编译库)再次编译源文件

是否有任何我可以指定的标志,以便它不会采用预编译的 .o 文件并再次编译它?

这里的标志并没有被不同的共享库覆盖,但实际上 make 文件的同一个目标文件被用于不同的标志

大多数构建系统假定编译对象在同一遍中保持不变。为了避免开枪,我建议告诉构建系统它们实际上是 不同的 对象,但仍然是从相同的源文件编译的。

我不熟悉 cmake,但这是你使用 make 的方式:

例如,您有一个 a.cpp,您想针对不同的编译器选项编译 2 次:

#include <stdio.h>    
int main(int argc, char* argv[]) {
  printf ("Hello %d\n", TOKEN);
  return 0;
}

Makefile 看起来像:

SRC := $(wildcard *.cpp)
OBJ_1 := $(patsubst %.cpp,%_1.o,$(SRC))
OBJ_2 := $(patsubst %.cpp,%_2.o,$(SRC))

all: pass1 pass2

pass1: $(OBJ_1)
        gcc -o $@ $(OBJ_1) -lstdc++

pass2: $(OBJ_2)
        gcc -o $@ $(OBJ_2) -lstdc++

%_1.o: %.cpp
        gcc -DTOKEN=1 -c $< -o $@
%_2.o: %.cpp
        gcc -DTOKEN=2 -c $< -o $@

clean:
        rm -f $(OBJ_1) $(OBJ_2)

我在这里所做的是从相同的源文件生成两个不同的对象列表,您甚至可以对依赖项(-MMD -MP 标志)执行相同的操作。

这与 makefile 和 cmake 通常的工作方式有点相反。

大多数用户认为 make 执行增量构建非常重要。

makefile 的常用方法是 make clean,这应该删除创建的任何二进制文件和目标文件。

但是,有时我会编写 cmake 脚本,这些脚本在源目录上使用 globbing 到 assemble 项目。 (这意味着,它说 "just grab all *.cpp files in the /src folder and make an executable from them"。)makefile 无法检查目录中的文件,因此在我添加新文件后 make build 将被破坏,并且 make clean 不会修复它 -- cmake.

需要重新生成整个 makefile

通常我做的是,我写一个简单的bash脚本,命名为rebuild.sh之类的,

#!/bin/bash
rm -rf build
mkdir build
cd build
cmake ..
make -j3
./tests

我把它放在我的存储库的根目录中,并将 /build 添加到我的 .gitignore。当我想进行完全重建时,我会调用它——它会破坏构建目录,所以它是万无一失的。当我想要增量重建时,我只需在 /build 目录中再次键入 make

如果您使用 travis-ci 进行持续集成,rebuild.sh 脚本也可以起到双重作用。