1

我一直在使用一个相当简单的makefile。我用 .cc 文件列表定义了 OBJS。我设置了依赖项并包含标志并将所有这些附加到 $CXXFLAGS。它看起来像这样:

SRCS = file1.cc file2.cc file3.cc
OBJS = $(SRCS:.cc=.o)
CXXFLAGS=some flags
CXXFLAGS+=some include dirs
$(mylib.so): $OBJS
    $CXX -shared -o $@ $^

mylib.so (隐式)使用 CXXFLAGS 并且一切都构建得很好。

除了 mylib.so 之外,我最近还需要 mylib_1.so 和 mylib_2.so。每个 .so 都依赖于所有相同的 .cc 文件,但编译器标志都不同(包括包含目录)。

如何获取它,以便我可以根据目标 .so 设置编译器标志?我遇到的问题是,如果我多次设置 CXXFLAGS ,它就会被覆盖。这几乎就像我需要一个 if/else 情况。

我尝试设置三个不同的标志,$CXXFLAGS1、$CXXFLAGS2、$CXXFLAGS3,并使用这些标志

$(mylib1.so): $OBJS
    $CXX $(CXXFLAGS1) -shared -o $@ $^

但这不起作用。

我如何完成我想做的事情?有 3 个单独的 makefile 会更好吗?我确实找到了让它工作的方法。我可以停止使用 $OBJS 并为每个源文件明确地拼出标志,但这在缩放到大小方面似乎是一个可怕的想法。

4

3 回答 3

3

您的示例中的 CXXFLAGS1 仅在创建 .so 文件的阶段使用,而不是用于编译实际的 C++ 源代码(我假设这是您正在尝试做的事情)。

要实现上述目的,请考虑让 Makefile 为 3 个不同的目标调用自身 3 次,并将 CXXFLAGS(具有不同的值)作为 MAKEFLAGS 的一部分或在命令行中传递。

更新:这是一个例子

全部:构建-lib1 构建-lib2 构建-lib3

构建-lib1:
    $(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS1)" lib1.so

构建-lib2:
    $(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS2)" lib2.so

构建-lib3:
    $(MAKE) $(MAKEFLAGS) CXXFLAGS="$(CXXFLAGS3)" lib3.so

$(lib1.so): $OBJS
    $(CXX) -共享 -o $@ $^

ETC...

于 2012-11-29T00:17:29.860 回答
2

Makefile 可以有特定于目标的变量值。就像是:

$(mylib1.so): CXXFLAGS += -lib1flags
$(mylib2.so): CXXFLAGS += -lib2flags
$(mylib3.so): CXXFLAGS += -lib3flags

根据文档,标志将传播到先决条件目标。

特定于目标的变量还有一个特殊功能:当您定义特定于目标的变量时,该变量值也对该目标的所有先决条件及其所有先决条件等都有效(除非这些先决条件用它们的自己的目标特定变量值)。因此,例如,这样的语句:

 prog : CFLAGS = -g
 prog : prog.o foo.o bar.o

将在 prog 的配方中将 CFLAGS 设置为“-g”,但它也会在创建 prog.o、foo.o 和 bar.o 的配方中以及创建其先决条件的任何配方中将 CFLAGS 设置为“-g” .

于 2012-11-29T00:11:33.440 回答
2

我会通过递归调用来做到这一点。我会使用两个makefile:

Makefile

全部:mylib1.so mylib2.so

SRCS := file1.cc file2.cc file3.cc

mylib1.so: $(SRCS)
    测试-d mylib1 || mkdir mylib1
    $(MAKE) -f ../lib.mak -C mylib1 目标=mylib1.so CXXFLAGS=-DMYLIB=1
    cp mylib1/mylib1.so mylib1.so

mylib2.so: $(SRCS)
    测试-d mylib2 || mkdir mylib2
    $(MAKE) -f ../lib.mak -C mylib2 TARGET=mylib2.so CXXFLAGS=-DMYLIB=2
    cp mylib2/mylib2.so mylib2.so

lib.mak,在同一目录中:

VPATH = ..

SRCS := file1.cc file2.cc file3.cc
OBJS := $(SRCS:.cc=.o)

$(目标): $(OBJS)
    $(CXX) -共享 -o $@ $^

第二个 makefile 实际构建库,但只使用一组CXXFLAGS. 主 makefile 调用每个版本的第一个 makefile,CXXFLAGS并在单独的目录中使用单独的目录。这VPATH使得编译不在同一目录中的源文件变得更加容易。

我用空运行测试了这个设置,

测试-d mylib1 || mkdir mylib1
make -f ../lib.mak -C mylib1 TARGET=mylib1.so CXXFLAGS=-DMYLIB=1
make[1]: 进入目录`/home/depp/Maketest2/mylib1'
g++ -DMYLIB=1 -c -o file1.o ../file1.cc
g++ -DMYLIB=1 -c -o file2.o ../file2.cc
g++ -DMYLIB=1 -c -o file3.o ../file3.cc
g++ -shared -o mylib1.so file1.o file2.o file3.o
make[1]: 离开目录`/home/depp/Maketest2/mylib1'
cp mylib1/mylib1.so mylib1.so
测试-d mylib2 || mkdir mylib2
make -f ../lib.mak -C mylib2 TARGET=mylib2.so CXXFLAGS=-DMYLIB=2
make[1]: 进入目录`/home/depp/Maketest2/mylib2'
g++ -DMYLIB=2 -c -o file1.o ../file1.cc
g++ -DMYLIB=2 -c -o file2.o ../file2.cc
g++ -DMYLIB=2 -c -o file3.o ../file3.cc
g++ -shared -o mylib2.so file1.o file2.o file3.o
make[1]: 离开目录`/home/depp/Maketest2/mylib2'
cp mylib2/mylib2.so mylib2.so
于 2012-11-29T00:21:19.243 回答