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

C++ 扩展简单makefile以支持不同的隐式编译器标志,c++,makefile,gnu-make,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 $@ $^ prog : CFLAGS = -g

我一直在使用一个相当简单的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 $@ $^
 prog : CFLAGS = -g
 prog : prog.o foo.o bar.o
mylib.so(隐式地)使用CXXFLAGS,并且一切都构建得很好

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

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

我试着设置三个不同的标志,$CXXFLAGS1、$CXXFLAGS2、$CXXFLAGS3,并在行中使用它们

$(mylib1.so): $OBJS
    $CXX $(CXXFLAGS1) -shared -o $@ $^
但这是行不通的

我怎样才能完成我想做的事情?有3个单独的makefile更好吗?我确实找到了一个办法让它发挥作用。我可以停止使用$OBJS并明确地为每个源文件指定标志,但从扩展到大小的角度来看,这似乎是一个可怕的想法。

Makefiles可能有。比如:

$(mylib1.so): CXXFLAGS += -lib1flags
$(mylib2.so): CXXFLAGS += -lib2flags
$(mylib3.so): CXXFLAGS += -lib3flags
根据文档,标志将传播到先决条件目标

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

SRCS = file1.cc file2.cc file3.cc
OBJS = $(SRCS:.cc=.o)
CXXFLAGS=some flags
CXXFLAGS+=some include dirs
$(mylib.so): $OBJS
    $CXX -shared -o $@ $^
 prog : CFLAGS = -g
 prog : prog.o foo.o bar.o
将在prog的配方中将CFLAGS设置为“-g”,但也将设置为 在创建prog.o、foo.o和bar.o的配方中,CFLAGS到'-g', 以及任何创造先决条件的食谱

Makefiles可以具有。比如:

$(mylib1.so): CXXFLAGS += -lib1flags
$(mylib2.so): CXXFLAGS += -lib2flags
$(mylib3.so): CXXFLAGS += -lib3flags
根据文档,标志将传播到先决条件目标

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

SRCS = file1.cc file2.cc file3.cc
OBJS = $(SRCS:.cc=.o)
CXXFLAGS=some flags
CXXFLAGS+=some include dirs
$(mylib.so): $OBJS
    $CXX -shared -o $@ $^
 prog : CFLAGS = -g
 prog : prog.o foo.o bar.o
将在prog的配方中将CFLAGS设置为“-g”,但也将设置为 在创建prog.o、foo.o和bar.o的配方中,CFLAGS到'-g', 以及任何创造先决条件的食谱


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

为了达到上述目的,请考虑使MaFo文件调用3个不同目标的3次,并将CXXFLAGS(具有不同的值)作为MaFLAG或命令行的一部分。 更新:以下是一个示例

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... 全部:build-lib1 build-lib2 build-lib3 build-lib1: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags1)”lib1.so build-lib2: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags2)”lib2.so build-lib3: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags3)”lib3.so $(lib1.so):$OBJS $(CXX)-共享-o$@$^ 等
您的示例中的CXXFrass1只用于创建.so文件的阶段,而不是用于编译实际C++源(这是您正在尝试做的,我假设)。

为了达到上述目的,请考虑使MaFo文件调用3个不同目标的3次,并将CXXFLAGS(具有不同的值)作为MaFLAG或命令行的一部分。 更新:以下是一个示例

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... 全部:build-lib1 build-lib2 build-lib3 build-lib1: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags1)”lib1.so build-lib2: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags2)”lib2.so build-lib3: $(MAKE)$(MAKEFLAGS)cxflags=“$(cxflags3)”lib3.so $(lib1.so):$OBJS $(CXX)-共享-o$@$^ 等
我将通过一个递归调用来实现这一点。我将使用两个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 第二个makefile实际上构建了库,但只使用了一组
CXXFLAGS
。主makefile使用单独的
cxflags
在单独的目录中为每个版本调用第一个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 测试-d mylib1 | | mkdir mylib1 make-f../lib.mak-C mylib1 TARGET=mylib1.so cxflags=-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 cxflags=-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
我将通过一个递归调用来实现这一点。我将使用两个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 第二个makefile实际上构建了库,但只使用了一组
CXXFLAGS
。主makefile使用单独的
cxflags
在单独的目录中为每个版本调用第一个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 测试-d mylib1 | | mkdir mylib1 make-f../lib.mak-C mylib1目标