【发布时间】:2024-01-24 10:45:01
【问题描述】:
这是我的目录结构:
.
├── a.out
├── assets
│ └── ...
├── build
│ ├── apps
│ └── objects
├── include
│ └── engine
│ └── Class.h
├── Makefile
└── src
├── engine
│ └── Class.cpp
└── program.cpp
我可以使用以下命令将program.cpp 编译成a.out:
g++ src/engine/*.cpp src/program.cpp -Iinclude/ -L/usr/lib -lstdc++ -lm -lsfml-graphics -lsfml-window -lsfml-system -Wall
虽然这行得通,但这个项目可能会发展壮大,显然制作一个严肃的 Makefile 比直接使用单行编译更可取。所以我使用了我以前多次使用过的 Makefile 格式,它工作得非常好,但我过去从未将它链接到外部库。这是我正在使用的 Makefile:
CXX := -g++
CXXFLAGS := -std=gnu++0x -g -Wall
LDFLAGS := -L/usr/lib -lstdc++ -lm -lsfml-graphics -lsfml-window -lsfml-system
BUILD := ./build
OBJ_DIR := $(BUILD)/objects
APP_DIR := $(BUILD)/apps
TARGET := program
INCLUDE := -Iinclude/
SRC := $(wildcard src/engine/*.cpp) $(wildcard src/*.cpp)
OBJECTS := $(SRC:%.cpp=$(OBJ_DIR)/%.o)
all: build $(APP_DIR)/$(TARGET)
$(OBJ_DIR)/%.o: %.cpp
@mkdir -p $(@D)
$(CXX) $(CXXFLAGS) $(INCLUDE) -o $@ -c $<
$(APP_DIR)/$(TARGET): $(OBJECTS)
@mkdir -p $(@D)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/$(TARGET) $(OBJECTS)
.PHONY: all build clean debug release
build:
@mkdir -p $(APP_DIR)
@mkdir -p $(OBJ_DIR)
debug: CXXFLAGS += -DDEBUG -g
debug: all
release: CXXFLAGS += -O2
release: all
clean:
-@rm -rvf $(OBJ_DIR)/*
-@rm -rvf $(APP_DIR)/*
但是,这会导致编译错误,表现为对 SFML 方法的未定义引用:
./build/objects/src/engine/Class.o: In function `Class::draw()':
/dir/Class.cpp:60: undefined reference to `sf::RenderTarget::getView() const'
我很困惑为什么会发生这种情况,因为上面的一个衬里编译得很好。如果我从我的代码中删除所有对 SFML 的引用,Makefile 也可以正常工作。添加的LDFLAGS 是否还不够,即使它们是使我的一个班轮链接到 SFML 所需的全部?如果是这样,还需要什么?
【问题讨论】:
-
哇...确实做到了。我什至没有意识到改变这样的事情的顺序可能很重要。我认为这值得在答案中指出。你介意写一下,或者添加一两行关于这里发生的事情吗?我真的很好奇你是怎么想出来的。
标签: makefile compilation linker g++ sfml