c++ - 关于“复杂”树结构的 C++ Makefile
问题描述
我发现了很多相关的问题,但我仍然无法制作自己的 Makefile。这个makefile在Windows上使用Mingw64,我希望它在*nix上运行,目前是Debian,但我希望它也能在Alpine上运行,因为它在Docker容器中使用。
项目树结构类似于:
./
src/
main.cpp
Server.cpp <- use asio and Utils/Split.h
Server.h <- use asio
Utils/
Split.h
lib/
asio/include/ <- asio library (without boost, header only)
Makefile <- That is what I am trying to do right now
Dockerfile
我尝试了多种方法,这是我最新的 Makefile(显然,它不起作用):
NAME := GameServer
CXX := g++
CXXFLAGS := -std=c++2a -DASIO_STANDALONE
SRC_DIR := ./src
LIBS := -I lib/asio-1.18.1/include \
-I lib/rapidjson-1.1.0/include \
-I src
rwildcard = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
SRCS := $(call rwildcard,$(SRC_DIR),*.cpp)
OBJS := $(SRCS:%.cpp=%.o)
.PHONY: all
all: $(NAME)
$(NAME): $(OBJS)
$(CXX) -o $@ $^
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
注意:代码 (.cpp, .h) 是有效的,它来自一个已经运行的项目,但构建在 Visual Studio 上(使用 MSVC 编译)。
这是我的 mingw32-make 完成的两个功能:
g++ -c -o src/Server.o src/main.cpp -I lib/asio/include -I src
g++ -o Server src/main.o src/Server.o
第一行:它应该从 .cpp 构建 .o 并将包含添加到 asio。我添加-I src
了添加 src/Utils,但我想这不是这样做的方式吗?
第二行:它应该(链接?)两个 .o 在一个文件中:可执行文件。
我使用这个makefile得到的错误是:
src/Server.o:main.cpp:(.text+0x36): multiple definition of 'main'
,src/main.o:main.cpp:(.text+0x36): first defined here
(这个,对于每个 .o)src/main.o:main.cpp:(.text+0x4b): undefined reference to 'Server::Server()'
(而且,对于每个服务器方法的主调用,甚至来自 asio 的一些方法)
它们出现在第二个 g++ 行开始时(g++ -o Server src/main.o src/Server.o
)
所以这是我的问题:
- 我究竟做错了什么 ?
- 有没有更好的方法来尝试在 Windows 上创建开发环境,并且仍然能够将项目复制到 Docker 容器中(然后使用 gcc 映像编译它)以使用相同的 Makefile 构建它?
抱歉,如果我忘了提及一些细节,我是 Mingw 及其环境的新手。
谢谢
编辑:更正版本:
NAME := GameServer
CXX := g++
CXXFLAGS := -std=c++1z
SRC_DIR := ./src
LIBS := -lwsock32 -lws2_32 \
-I lib/asio-1.18.1/include \
-I lib/rapidjson-1.1.0/include \
-I src
rwildcard = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
SRCS := $(call rwildcard,$(SRC_DIR),*.cpp)
OBJS := $(SRCS:%.cpp=%.o)
.PHONY: all
all: $(NAME)
$(NAME): $(OBJS)
$(CXX) -o $@ $^ $(LIBS)
$(OBJS): $(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
解决方案
考虑规则...
$(OBJS): $(SRCS)
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
这make
表明 中的所有项目都$(OBJS)
依赖于 中的所有项目$(SRCS)
。但是命令...
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
...总是编译由 . 标识的第一个依赖项$<
。碰巧在您的情况下$<
是src/main.cpp
.
相反,您可能应该使用模式规则,例如...
$(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
您还可以将该规则的范围限制为仅$(OBJS)
使用完整静态模式规则指定的那些目标...
$(OBJS): $(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $< $(LIBS)
推荐阅读
- reactjs - 无法更新 this.state.mostVoted
- reactjs - 获取带有“获取”没有正文的 html
- google-bigquery - 在 BigQuery 中存储大数字
- javascript - 什么是更好的接口或类来拦截 Angular 6 中的 API 数据
- r - 在所有页面上生成“编辑此文档”链接
- reactjs - 在 React js 中获取时如何隐藏控制台状态错误消息?
- javascript - Uncaught (in promise) NotSupportedError: 该元素没有支持的来源。在页面上播放音频单击 Chrome 扩展程序
- sql-server - SQL Server 的反应式 Web UI 是否可能?如果是,如何?
- model-view-controller - 哪个是 mvc 组件图的准确方法?
- android - 如何为 Android Studio 3.2.1 配置 Android SDK?