在Makefile

时间:2018-01-08 12:10:27

标签: c++ makefile

我在一个目录中有多个源文件,其中一些负责主可执行文件,一些负责共享库,而后者又是主可执行文件所需要的。因此我按以下方式编写了makefile:

CC=gcc
CXX=g++
CFLAGS=-I$(DIR) -fPIC -c -fopenmp
CXXLFLAGS=-I$(DIR) -fopenmp -O3 -g -march=native -std=gnu++17 -fPIC -c
CXXFLAGS=-I$(DIR) -fopenmp -O3 -g -march=native -std=gnu++17 -c
LDFLAGS=-lfftw3 -lgomp -lm -larmadillo -lpthread -lX11 -lboost_system -lboost_program_options -L/opt/intel/mkl/lib/intel64 -lmkl_rt
LDMAINFLAGS=-lfftw3 -lgomp -lm -larmadillo -lpthread -lX11 -lboost_system -lboost_program_options -L/opt/intel/mkl/lib/intel64 -lmkl_rt -lpulse_propagation
LIBSOURCES=source/image_processing.cpp source/pulse_propagation.cpp
LIBOBJECTS=source/image_processing.o source/pulse_propagation.o
MAINSOURCES=source/fftw.cpp source/fftw++.cc 
MAINOBJECTS=source/fftw.o source/fftw++.o 
EXECUTABLE=fftw
LIBRARY=libpulse_propagation.so

.PHONY: default all clean

default: all

all: $(LIBRARY) main

main: $(LIBRARY) $(MAINOBJECTS)
    $(CXX) $(LDFLAGS) $(MAINOBJECTS) -o $(EXECUTABLE)

$(LIBRARY): $(LIBOBJECTS)
    $(CXX) $(LDFLAGS) -shared $^ -o $@

$(LIBOBJECTS): $(LIBSOURCES)
    $(CXX) $(CXXLFLAGS) $^ -o $@

$(MAINOBJECTS): $(MAINSOURCES)
    $(CXX) $(CXXFLAGS) $^ -o $@

clean_compile:
    rm -f source/*.o

clean:
    rm -f source/*.o $(EXECUTABLE) $(LIBRARY)

所有内容都标有属于主要可执行文件的MAIN以及库中的其他所有内容。我想循环遍历LIBSOURCES / MAINSOURCES中的文件并编译它们。我希望如果我不必使用.cpp.o: - 宏,那么根据它是库文件还是主文件有不同的标志。我尝试使用$<,它执行了两次编译(ok),但总是使用变量列表中的第一个值。使用$^时,会同时使用这两个文件,但也会导致错误。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

您的source/fftw++.cc代替source/fftw++.cpp会使一切变得无用复杂。如果你可以重命名它,那么以下应该做你想要的:

$(LIBOBJECTS): CXXFLAGS := $(CXXLFLAGS)

$(LIBOBJECTS) $(MAINOBJECTS): %.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -o $@

第一行定义CXXFLAGS目标的变量$(LIBOBJECTS)的值。以下规则是static pattern rule,它只转换为具有一个目标和一个先决条件的规则。它与您的规则完全不同,它声明了所有源文件作为所有相应目标文件的先决条件。不是你想要的。

如果您无法重命名source/fftw++.cc,则可以拆分源和对象列表:

MAINCPPSOURCES=source/fftw.cpp
MAINCCSOURCES=source/fftw++.cc 
MAINCPPOBJECTS=source/fftw.o
MAINCCOBJECTS=source/fftw++.o 

$(LIBOBJECTS): CXXFLAGS := $(CXXLFLAGS)

$(LIBOBJECTS) $(MAINCPPOBJECTS): %.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -o $@

$(MAINCCOBJECTS): %.o: %.cc
    $(CXX) $(CXXFLAGS) $< -o $@

最后,如果你计算可能的东西,而不是在Makefile中硬连接它,它可能会更好(更容易维护):

MAINCPPOBJECTS = $(patsubst %.cpp,%.o,$(MAINCPPSOURCES))
MAINCCOBJECTS = $(patsubst %.cc,%.o,$(MAINCCSOURCES))
...