适当的Makefile来替换一个gcccompile/link运行?
Appropriate Makefile to replace a gcc compile/link run?
我的目标是使用单个 Makefile
跨各种平台编译 C 应用程序。
我在做项目的时候忙于重新学习C,所以还没有时间去钻研make
;相反,我在某些 .bat
/ .sh
文件中有一个长的 gcc
命令。不用说,每次我更改一个这样的文件时,我都必须对其他文件进行相同的更改。因此,make
。需要处理的条件:
- 为多个 OS 和架构构建,即现在(至少)32 位和 64 位用于 Windows 和 Linux,因此我需要在
Makefile
,可执行文件应进入 /build
下的不同文件夹:即 /win32
、/win64
、/lin32
、/lin64
(等等,将来).
- 所需的 DLL 应与构建的可执行文件一起复制。
- 单独编译和 link 阶段(感谢@EtanReisner)
问题: 谁能告诉我如何使用以下信息构建 Makefile
?并解释每个部分如何工作/为什么我的特定情况需要它?我了解构建 Makefile
的先决条件方法。提前致谢。
这是我的项目目录树:
+---bin
+---include
| +---enet
| +---GL
| +---libxml
| \---ncursesw
+---lib
+---src
+---fonts
\---shaders
和 mingw gcc
用于 Windows 32 位编译:
gcc -Iinclude ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../Disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -lglfw3-32 -lopengl32 -lgdi32 -lenet-32 -lws2_32 -lwinmm -llibxml2-32 -L. -ldll32/libncursesw6 -std=c11 -m32 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -O0 -o ./build/win32/wa
gcc
Linux 64 位编译:
gcc -Iinclude -I/usr/include/libxml2 ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -L/usr/lib -l:libglfw.so.3 -lncurses -lGL -lxml2 -lenet -lm -std=c11 -m64 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -g -o ./wa-64.elf
(值得区分这些。)
反复试验导致了以下结果...正在进行中,但基础知识已经存在。特点:
- 无需手动列出源/目标文件(所有相关源都应在
src
中)
- 使用 .c/.o 文件列表的共享逻辑将编译和 link 阶段分开
- OS & 体系结构自动检测 (WIP),手动覆盖 arch (
例如
make BITS=32
)
- 适用于 Win 和 *nixes 的清理
- 编译时在 .DLL 中复制(WIP 提供要复制的 DLL 列表)
感谢Yanick Rochon, Samuel and Trevor Robinson for their answers, and to those who wrote the GNU Makefile examples。
CC = gcc
#Directories
HDRDIR = include
SRCDIR = ./src
OBJDIR = ./obj
BINDIR = ./bin
LIBDIR = lib
#File lists
HDRS := $(wildcard $(HDRDIR)/*.h)
SRCS := $(wildcard $(SRCDIR)/*.c)
OBJS := $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
#Autodetect OS / architecture
OS =
BITS = 32
#ifeq ($(shell echo "check_quotes"),"check_quotes")
ifeq ($(OS),Windows_NT)
OS := win
EXT := .exe
rm := del /q
cp := copy /y
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CFLAGS += -D IA32
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
OS := lin
EXT := .elf
rm := rm -f
cp := cp
CCFLAGS += -D LINUX
BITS = $(shell getconf LONG_BIT)
endif
ifeq ($(UNAME_S),Darwin)
OS := osx
EXT :=
rm := rm -f
cp := cp
CCFLAGS += -D OSX
BITS = $(shell getconf LONG_BIT)
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
#Define flags for compile & link
CFLAGS = -I$(HDRDIR) -std=c11 -m64 -fopenmp -Wall -Werror -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -w -O0 -DGLEW_STATIC
LFLAGS = -L$(LIBDIR)
#Do we want verbose linker messages?
LVERBOSE := false
LLIBS =
ifeq ($(OS),win)
LLIBS += -lglfw3-$(BITS) -lglew32s -lglew32 -lopengl32 -lgdi32 -lwinmm
endif
ifeq ($(OS),lin)
LLIBS += -lglew32s -lglew32 -lGL -lm
endif
ifeq ($(LVERBOSE),true)
LFLAGS += -Wl,--verbose
endif
TARGET = program$(EXT)
#Rules
$(BINDIR)/$(TARGET): $(OBJS)
@$(CC) -o ./$@ $(OBJS) $(LFLAGS) $(LLIBS)
@echo Linking complete.
@$(cp) $(LIBDIR)\glfw3.dll $(BINDIR)
@echo DLLs accompanying executable.
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o ./$@
@echo Compiled $<.
.PHONEY: clean
clean:
ifeq ($(OS),win)
@$(rm) $(subst /,\,$(OBJS))
@$(rm) $(subst /,\,$(BINDIR)/*.*)
else
@$(rm) $(OBJS)
@$(rm) $(BINDIR)/*
endif
@echo Cleanup complete.
#$(subst /,\, $(SOMETHING)) replaces all (make-native) forward slashes with backslashes, for Windows.
我的目标是使用单个 Makefile
跨各种平台编译 C 应用程序。
我在做项目的时候忙于重新学习C,所以还没有时间去钻研make
;相反,我在某些 .bat
/ .sh
文件中有一个长的 gcc
命令。不用说,每次我更改一个这样的文件时,我都必须对其他文件进行相同的更改。因此,make
。需要处理的条件:
- 为多个 OS 和架构构建,即现在(至少)32 位和 64 位用于 Windows 和 Linux,因此我需要在
Makefile
,可执行文件应进入/build
下的不同文件夹:即/win32
、/win64
、/lin32
、/lin64
(等等,将来). - 所需的 DLL 应与构建的可执行文件一起复制。
- 单独编译和 link 阶段(感谢@EtanReisner)
问题: 谁能告诉我如何使用以下信息构建 Makefile
?并解释每个部分如何工作/为什么我的特定情况需要它?我了解构建 Makefile
的先决条件方法。提前致谢。
这是我的项目目录树:
+---bin
+---include
| +---enet
| +---GL
| +---libxml
| \---ncursesw
+---lib
+---src
+---fonts
\---shaders
和 mingw gcc
用于 Windows 32 位编译:
gcc -Iinclude ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../Disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -lglfw3-32 -lopengl32 -lgdi32 -lenet-32 -lws2_32 -lwinmm -llibxml2-32 -L. -ldll32/libncursesw6 -std=c11 -m32 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -O0 -o ./build/win32/wa
gcc
Linux 64 位编译:
gcc -Iinclude -I/usr/include/libxml2 ./src/main.c ./src/MainCtrl.c ./src/MainView.c ./src/PerspectiveView.c ./src/LogView.c ./src/LobbyView.c ./src/TerminalView.c ./src/World.c ./src/Chunk.c ./src/CellPattern.c ./src/CellPlan.c ./src/GridPoint.c ./src/Entity.c ./src/InfluenceRadial.c ./src/AoIList.c ./src/AoI.c ./src/ChunkRenderable.c ./src/PrimitiveRenderable.c ./src/Geometry.c ./src/glew/glew.c ./src/stb/stb_image_aug.c ../curt/list_generic.c ../curt/map_generic.c ../curt/intMap.c ../curt/floatMap.c ../hedgehog/hedgehog.c ./src/Inputs.c ./src/InputResponse.c ./src/Network.c ../disjunction/c/disjunction.c ./src/my/math/Range.c ./src/my/math/Point.c -Llib -L/usr/lib -l:libglfw.so.3 -lncurses -lGL -lxml2 -lenet -lm -std=c11 -m64 -w -Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -fopenmp -g -o ./wa-64.elf
(值得区分这些。)
反复试验导致了以下结果...正在进行中,但基础知识已经存在。特点:
- 无需手动列出源/目标文件(所有相关源都应在
src
中) - 使用 .c/.o 文件列表的共享逻辑将编译和 link 阶段分开
- OS & 体系结构自动检测 (WIP),手动覆盖 arch (
例如
make BITS=32
) - 适用于 Win 和 *nixes 的清理
- 编译时在 .DLL 中复制(WIP 提供要复制的 DLL 列表)
感谢Yanick Rochon, Samuel and Trevor Robinson for their answers, and to those who wrote the GNU Makefile examples。
CC = gcc
#Directories
HDRDIR = include
SRCDIR = ./src
OBJDIR = ./obj
BINDIR = ./bin
LIBDIR = lib
#File lists
HDRS := $(wildcard $(HDRDIR)/*.h)
SRCS := $(wildcard $(SRCDIR)/*.c)
OBJS := $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
#Autodetect OS / architecture
OS =
BITS = 32
#ifeq ($(shell echo "check_quotes"),"check_quotes")
ifeq ($(OS),Windows_NT)
OS := win
EXT := .exe
rm := del /q
cp := copy /y
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CFLAGS += -D IA32
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
OS := lin
EXT := .elf
rm := rm -f
cp := cp
CCFLAGS += -D LINUX
BITS = $(shell getconf LONG_BIT)
endif
ifeq ($(UNAME_S),Darwin)
OS := osx
EXT :=
rm := rm -f
cp := cp
CCFLAGS += -D OSX
BITS = $(shell getconf LONG_BIT)
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
#Define flags for compile & link
CFLAGS = -I$(HDRDIR) -std=c11 -m64 -fopenmp -Wall -Werror -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wlogical-op -Wcast-align -Wconversion -Wpedantic -Wfloat-equal -w -O0 -DGLEW_STATIC
LFLAGS = -L$(LIBDIR)
#Do we want verbose linker messages?
LVERBOSE := false
LLIBS =
ifeq ($(OS),win)
LLIBS += -lglfw3-$(BITS) -lglew32s -lglew32 -lopengl32 -lgdi32 -lwinmm
endif
ifeq ($(OS),lin)
LLIBS += -lglew32s -lglew32 -lGL -lm
endif
ifeq ($(LVERBOSE),true)
LFLAGS += -Wl,--verbose
endif
TARGET = program$(EXT)
#Rules
$(BINDIR)/$(TARGET): $(OBJS)
@$(CC) -o ./$@ $(OBJS) $(LFLAGS) $(LLIBS)
@echo Linking complete.
@$(cp) $(LIBDIR)\glfw3.dll $(BINDIR)
@echo DLLs accompanying executable.
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o ./$@
@echo Compiled $<.
.PHONEY: clean
clean:
ifeq ($(OS),win)
@$(rm) $(subst /,\,$(OBJS))
@$(rm) $(subst /,\,$(BINDIR)/*.*)
else
@$(rm) $(OBJS)
@$(rm) $(BINDIR)/*
endif
@echo Cleanup complete.
#$(subst /,\, $(SOMETHING)) replaces all (make-native) forward slashes with backslashes, for Windows.