扩展一个简单的makefile以支持不同的隐式编译器标志

时间:2012-11-29 00:03:31

标签: c++ makefile gnu-make

我是非常新的文件 - 所以请和我一起讨论这个问题。

我一直在使用相当简单的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并明确地为每个源文件拼出标志,但就扩展到大小而言,这似乎是一个可怕的想法。

3 个答案:

答案 0 :(得分:2)

Makefile可以有target-specific variable values。类似的东西:

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

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

  

目标特定变量还有一个特殊功能:何时   您定义了一个特定于目标的变量,变量值也在其中   影响该目标的所有先决条件及其所有先决条件   先决条件等(除非这些先决条件覆盖该变量   用他们自己的特定目标变量值)。所以,例如,a   声明如下:

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

将在prog的配方中将CFLAGS设置为'-g',但它也会设置   在创建prog.o,foo.o和bar.o的食谱中CFLAGS到'-g',   以及任何创造先决条件的食谱。

答案 1 :(得分:2)

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

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

更新:这是一个例子

all:  build-lib1 build-lib2 build-lib3

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

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

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

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

etc...

答案 2 :(得分:2)

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

Makefile

all: mylib1.so mylib2.so

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

mylib1.so: $(SRCS)
    test -d mylib1 || mkdir mylib1
    $(MAKE) -f ../lib.mak -C mylib1 TARGET=mylib1.so CXXFLAGS=-DMYLIB=1
    cp mylib1/mylib1.so mylib1.so

mylib2.so: $(SRCS)
    test -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)

$(TARGET): $(OBJS)
    $(CXX) -shared -o $@ $^

第二个makefile实际上构建了库,但只使用了一组CXXFLAGS。主makefile为具有单独CXXFLAGS的每个版本调用第一个makefile,并位于单独的目录中。 VPATH可以更轻松地编译不在同一目录中的源文件。

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

test -d mylib1 || mkdir mylib1
make -f ../lib.mak -C mylib1 TARGET=mylib1.so CXXFLAGS=-DMYLIB=1
make[1]: Entering directory `/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]: Leaving directory `/home/depp/Maketest2/mylib1'
cp mylib1/mylib1.so mylib1.so
test -d mylib2 || mkdir mylib2
make -f ../lib.mak -C mylib2 TARGET=mylib2.so CXXFLAGS=-DMYLIB=2
make[1]: Entering directory `/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]: Leaving directory `/home/depp/Maketest2/mylib2'
cp mylib2/mylib2.so mylib2.so