makefile没有将.o和可执行文件放在相应的obj和bin目录中

时间:2017-06-18 00:53:43

标签: c++ makefile

我是c ++和制作文件的新手。我目前正在尝试使用反复试验制作一个makefile而且我被卡住了。这是我的makefile的副本。

# SYNOPSIS:
#
#   make TARGET - makes the given target.
#   make clean  - removes all files generated by make.

# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.

# Points to the root of Google Test, relative to where this file is.
GTEST_DIR = deps/googletest/googletest

# Points to the root of Pulse Waves, relative to where this file is.
PULSE_DIR = deps/PulseWaves

# Where to find user code.
USER_DIR =src

# Different directories
BIN=bin
OBJ=obj
LIB=lib

#Create directories if needed
$(BIN):
    mkdir $@
$(OBJ):
    mkdir $@
$(LIB):
    mkdir $@

# Flags passed to the preprocessor.
# Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include

# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread -I$(PULSE_DIR)/inc
CFLAGS += -g -Wall -Wextra -pthread -I$(PULSE_DIR)/inc

# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
TESTS = $(BIN)/cmdLine_unittests $(BIN)/FullWaveformIngestion_unittests

# All Google Test headers.  Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/ \
                $(GTEST_DIR)/include/gtest/internal/


# Builds gtest.a and gtest_main.a.

# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/ $(GTEST_DIR)/src/ $(GTEST_HEADERS)

# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized.  This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
$(OBJ)/gtest-all.o : $(BIN) $(LIB) $(OBJ) $(GTEST_SRCS_)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
            $(GTEST_DIR)/src/gtest-all.cc -o $@

$(OBJ)/gtest_main.o : $(GTEST_SRCS_)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
            $(GTEST_DIR)/src/gtest_main.cc -o $@

$(LIB)/gtest.a : $(OBJ)/gtest-all.o
    $(AR) $(ARFLAGS) $@ $^

$(LIB)/gtest_main.a : $(OBJ)/gtest-all.o $(OBJ)/gtest_main.o
    $(AR) $(ARFLAGS) $@ $^

# Builds a test.  A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.

$(BIN)/%_unittests:$(USER_DIR)/%_unittests.o $(USER_DIR)/%.o $(LIB)/gtest_main.a
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ -L$(PULSE_DIR)/lib -lpulsewaves

$(USER_DIR)/%_unittests.o: $(USER_DIR)/%_unittests.cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $^ 

$(USER_DIR)/FullWaveformIngestion.o: $(USER_DIR)/FullWaveformIngestion.cpp
    $(CXX) -c -o $@ $^ $(CFLAGS) -L$(PULSE_DIR)/lib

$(USER_DIR)/ScannerInformation.o: $(USER_DIR)/ScannerInformation.cpp
    $(CXX) -c -o $@ $^ $(CFLAGS) -L$(PULSE_DIR)/lib

$(USER_DIR)/%.o: $(USER_DIR)/%.cpp
    $(CXX) -c -o $@ $^ $(CFLAGS)

$(BIN)/lidarDriver: $(USER_DIR)/lidarDriver.o $(USER_DIR)/cmdLine.o $(USER_DIR)/ScannerInformation.o
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ -L$(PULSE_DIR)/lib -lpulsewaves

.PHONY: test

lidarDriver: $(USER_DIR)/lidarDriver.o $(USER_DIR)/cmdLine.o $(USER_DIR)/parseFile.o $(USER_DIR)/ScannerInformation.o
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ -L$(PULSE_DIR)/lib -lpulsewaves

test: $(TESTS)
    $(BIN)/cmdLine_unittests
    $(BIN)/FullWaveformIngestion_unittests

clean: 
    rm -f $(BIN)/*
    rm -f $(OBJ)/*
    rm -f $(LIB)/*
    rm -f $(USER_DIR)/*.o

其他一切都按照预期的方式运作。我有相应目录中的其他文件。但是,我试图将lidarDriver.o放在obj目录中,并将binarDriver可执行文件放在bin目录中。无法弄清楚我需要做什么..请帮忙。

1 个答案:

答案 0 :(得分:0)

您有两个规则来构建obj/中的目标文件:

$(OBJ)/gtest-all.o : $(BIN) $(LIB) $(OBJ) $(GTEST_SRCS_)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc -o $@

$(OBJ)/gtest_main.o : $(GTEST_SRCS_)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc -o $@

在我们担心构建obj/lidarDriver.o之前,让我们清理它们。

第一个规则有七个目录作为先决条件,第二个规则有四个。正确的数字是1,$(OBJ)(第二个缺失)。

$(OBJ)/gtest-all.o : $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc -o $@

$(OBJ)/gtest_main.o : $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc -o $@

当规则从源文件构建目标文件时,将该源文件作为规则的先决条件是有意义的(因此,自上次构建对象以来,当源已被修改时,Make将重建对象) :

$(OBJ)/gtest-all.o : $(GTEST_DIR)/src/gtest-all.cc $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc -o $@

$(OBJ)/gtest_main.o : $(GTEST_DIR)/src/gtest_main.cc $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc -o $@

现在我们可以通过automatic variable $<删除冗余,它扩展到先决条件列表的第一个成员(就像$@扩展为规则的名称一样) 。这对您的目的来说并不是绝对必要的,但它使规则更加清晰。

$(OBJ)/gtest-all.o : $(GTEST_DIR)/src/gtest-all.cc $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $< -o $@

$(OBJ)/gtest_main.o : $(GTEST_DIR)/src/gtest_main.cc $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $< -o $@

我们可以进一步简化,但那是另一天。现在,您可以为obj/lidarDriver.o添加规则:

$(OBJ)/lidarDriver.o : $(GTEST_DIR)/src/lidarDriver.cc $(OBJ)
    $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $< -o $@

现在对$(BIN)/lidarDriver规则稍作修改:

$(BIN)/lidarDriver: $(OBJ)/lidarDriver.o ...
    ...

我们已经完成了。