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

makefile not putting the .o and executable in the respective obj and bin directories

本文关键字:obj bin 可执行文件 makefile      更新时间:2023-10-16

我是c++和制作文件的新手。我目前正在尝试做一个反复试验的制作文件,但我卡住了。这是我的制作文件的副本。

# 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目录中,将lidarDriver可执行文件放在bin目录中。不知道我需要做什么。.请帮忙。

您有两个规则可以在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 $@

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

$(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 ...
...

我们完成了。