简体   繁体   English

许多C ++可执行文件的Makefile

[英]Makefile for many c++ executables

I am working on a project where I constantly need to create new c++ executables. 我正在一个项目中,我经常需要创建新的c ++可执行文件。 They all rely on some common headers and sources files, so I am wondering how to simplify the compilation and Makefile writing. 它们都依赖于一些常见的头文件和源文件,因此我想知道如何简化编译和Makefile的编写。 The best I have come up with so far is something like this: 到目前为止,我想出的最好的方法是这样的:

file1: $(BUILDDIR)/$@.o $(COMMON_OBJECTS) $(COMMON_LIBS)
    $(CCCOM) $(CCFLAGS) $(BUILDDIR)/$@.o $(COMMON_OBJECTS) -o $(BINDIR)/$@ $(LIBFLAGS)

and then I have to copy this target for each executable I want to add. 然后我必须为每个要添加的可执行文件复制此目标。 Ideally I want to define this rule once for arbitrary target and then simply call make any_file_name . 理想情况下,我想为任意目标定义一次此规则,然后简单地调用make any_file_name

Is something like that possible? 这样有可能吗? How do people organize c++ project with lots of executables? 人们如何组织具有大量可执行文件的c ++项目? (I am new to c++ and coming from python that is a very natural thing) (我是C ++的新手,来自python,这是很自然的事情)

You could make it so that each executable corresponds to a single .cpp file in a directory (eg executables/foo.cpp , executables/bar.bpp ), and then work from there -- this will save you from having to touch the Makefile every time you add another one. 可以这样做,以使每个可执行文件都对应一个目录中的单个.cpp文件(例如, executables/foo.cppexecutables/bar.bpp ),然后从那里开始工作-这将使您不必触摸Makefile每次添加另一个。

You should, probably, also set up your project to create a shared library, which the (light-weight) executables link to. 您可能还应该将项目设置为创建一个共享库,(轻量级)可执行文件链接到该共享库。 (The executables effectively just doing some command-line parsing, and offloading the actual work to library functions.) This way, you will not end up with the code from those $(COMMON_OBJECTS) being replicated in every executable. (这些可执行文件实际上只是进行了一些命令行解析,然后将实际工作$(COMMON_OBJECTS)到库函数中。)这样,您将不会获得在每个可执行文件中复制的$(COMMON_OBJECTS)的代码。

Here is an example makefile with automatic header dependency generation for you: 这是为您自动生成标头依赖项的示例makefile:

BUILD := debug
BUILD_DIR := ${BUILD}

CXX := g++

cppflags.debug :=
cppflags.release := -DNDEBUG
cppflags := ${cppflags.${BUILD}} ${CPPFLAGS}

cxxflags.debug :=
cxxflags.release := -O3
cxxflags := ${cxxflags.${BUILD}} ${CXXFLAGS}

ldflags := ${LDFLAGS}
ldlibs := ${LDLIBS}

exes := # Executables to build.

### Define executables begin.

exes += exe1
exe1.obj := exe1.o

exes += exe2
exe2.obj := exe2.o

### Define executables end.

all : ${exes:%=${BUILD_DIR}/%}

.SECONDEXPANSION:

${BUILD_DIR}:
    mkdir -p $@

# Rule to link all exes.
${exes:%=${BUILD_DIR}/%} : ${BUILD_DIR}/% : $$(addprefix ${BUILD_DIR}/,$${$$*.obj}) | $${@D}
    ${CXX} -o $@ ${ldflags} $^ ${ldlibs}

# Rule to compile C sources. And generate header dependencies.
${BUILD_DIR}/%.o : %.cc | $${@D}
    ${CXX} -o $@ -c ${cppflags} ${cxxflags} -MD -MP $<

# Include automatically generated header dependencies.
ifneq ($(MAKECMDGOALS),clean)
-include $(foreach exe,${exes},$(patsubst %.o,${BUILD_DIR}/%.d,${${exe}.obj}))
endif

clean:
    rm -rf $(BUILD_DIR)

.PHONY: all clean

Usage example: 用法示例:

$ cat exe1.cc 
#include <iostream>
int main() { std::cout << "Hello, world!\n"; }

$ cat exe2.cc 
#include <iostream>
int main() { std::cout << "Hello, world!\n"; }

$ make
mkdir -p debug
g++ -o debug/exe1.o -c     -MD -MP exe1.cc
g++ -o debug/exe1  debug/exe1.o 
g++ -o debug/exe2.o -c     -MD -MP exe2.cc
g++ -o debug/exe2  debug/exe2.o 

$ make BUILD=release 
mkdir -p release
g++ -o release/exe1.o -c -DNDEBUG  -O3  -MD -MP exe1.cc
g++ -o release/exe1  release/exe1.o 
g++ -o release/exe2.o -c -DNDEBUG  -O3  -MD -MP exe2.cc
g++ -o release/exe2  release/exe2.o 

$ make clean
rm -rf debug

$ make BUILD=release clean
rm -rf release

To simplify everything I'm assuming you have sources file1.cpp , file2.cpp and so on, and all your files reside in the same directory. 为了简化一切,我假设您具有源文件file1.cppfile2.cpp等,并且所有文件都位于同一目录中。 Then Makefile fragment below will do what you want: 然后下面的Makefile片段将执行您想要的操作:

all: $(basename $(wildcard file?.cpp))

file%: file%.cpp

To make everyhing: 使一切:

make all

To make file1 : 制作file1

make file1

To make file1 and file2 : 制作file1file2

make file1 file2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM