我正在使用这些Makefile基本上用于我的所有项目,使其适应我需要生成的不同类型的库或可执行文件。 这些时候我需要编译具有几个公共文件的不同目标和一个依赖于不同目标的文件。
我尝试类似的东西
# Add inputs and outputs from these tool invocations to the build variables
# All Target
RM := rm -rf
CXX:= g++
LD := g++
CC := gcc
TARGET = ../../Libs/libdemo.so
# definition of additional libraries for linking
LIBS := -L/data/somelib_lib/ -lsomelib1 -lsomelib2
# definition of include directories
# for each you need to add -I
INCLUDE := -I../../include
#compiler definition
CFLAGS= -std=c++11 -Wall -Wextra -c -fmessage-length=0 -fPIC -MMD -MP -D __GXX_EXPERIMENTAL_CXX0X__ -D_GLIBCXX_USE_NANOSLEEP
# All of the sources participating in the build are defined here
# Add inputs and outputs from these tool invocations to the build variables
LINKER_FLAG= -shared
target1: CPP_SRCS += \
src/main1.cpp
target1: CPP_DEPS += \
src/main1.d
target1: CFLAGS += -O0 -g3
target1: LINKER_FLAG += -g
target1: $(TARGET)
@echo "main1 called"
target2: CPP_SRCS += \
src/main2.cpp
target2: CPP_DEPS += \
src/main2.d
target2: CFLAGS += -O0 -g3
target2: LINKER_FLAG += -g
target2: $(TARGET)
@echo "main2 called"
profile: CFLAGS += -pg
profile: $(TARGET)
@echo "profile called"
valgrind: CFLAGS += -g -O1
valgrind: LINKER_FLAG += -g
valgrind: $(TARGET)
all: CFLAGS += -O3
all: $(TARGET)
@echo "all called"
CPP_SRCS += \
../src/file1.cpp \
../src/file2.cpp \
../src/LoadParams.cpp \
../src/file3.cpp \
CPP_DEPS += \
./src/file1.d \
./src/file2.d \
./src/LoadParams.d \
./src/file3.d \
OBJECTDIR = ./
OBJECTS=$(CPP_SRCS:%.cpp=$(OBJECTDIR)%.o)
# Tool invocations
$(TARGET): $(OBJECTS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C++ Linker'
$(LD) $(LIBS) $(LINKER_FLAG) -o "$@" $(OBJECTS)
$(RM) $(OBJECTS)
$(RM) $(CPP_DEPS)
@echo 'Finished building target: $@'
@echo ' '
clean:
@echo "clean called"
$(RM) $(TARGET)
$(RM) $(OBJECTS)
$(RM) $(CPP_DEPS)
#echo "$@ and $^"
$(OBJECTDIR)/%.o: %.cpp
@echo 'Building file: $<'
@echo 'Invoking: GCC C++ Compiler'
$(CXX) $(CFLAGS) $(INCLUDE) -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
现在的问题是,如果我调用make target1,编译器只编译4个文件而不包含文件main1.cpp,而在链接期间,该命令包含5个.o文件,当然缺少main1.o文件。 这意味着$(OBJECTS)正确生成但在变量CPP_SRC不包含main1.cpp文件之后。 有人可以解释这种奇怪的行为,并给我一些关于如何正确解决问题的提示(或建议更好的方法来执行相同的任务)? 提前致谢
答案 0 :(得分:1)
问题在于:
target1: CPP_SRCS += src/main1.cpp
这是target-specific variable assignment,因此它可以在规则的正文中找到(以及先决条件规则),但不在先决条件列表中规则(或先决条件)。所以这个:
OBJECTS=$(CPP_SRCS:%.cpp=$(OBJECTDIR)%.o)
$(TARGET): $(OBJECTS)
...
不会将main1.o
放入先决条件列表中。如果不清楚,请尝试:
$(TARGET): $(OBJECTS)
@echo the variable OBJECTS contains $(OBJECTS)
@echo but the prerequisite list is $^
有几种方法可以解决这个问题,但请注意,由于 target1
和target2
都构建了libdemo.so
,,因此无法完美溶液
一种方法是为库提供不同的名称:
libdemo1.so: main1.o
libdemo2.so: main2.o
libdemo1.so libdemo2.so: $(OBJECTS)
@echo Building target: $@ from objects: $^
$(LD) $(LIBS) $(LINKER_FLAG) -o $@ $^
另一种是使用递归:
target1: main1.o
@$(MAKE) $(TARGET) CFLAGS=$(CFLAGS) LINKER_FLAG=$(LINKER_FLAG)