序
前文《【开发工具】之windows下gnu makefile编写》介绍了借助GUNWIN32编写windows下的Makefile,本文异曲同工,介绍在MINGW下编写windows下的makefile
1. 相关flag放在一个config.mk文件中
小编习惯于将系统配置的相关flags放在一个独立的文件中,方便以后系统扩展,因此新建名为config.mk的文件,内容为:
OS := $(shell uname)
ifeq ($(findstring MINGW, $(OS)), MINGW)
CC := c99wrap cl
CPP := c99wrap cl
AR := lib
LD := c99wrap link
RC := rc
ASM := yasm
ifeq ($(platform), x86_32)
ARCH_DEF :=
OUT_DIR := ../out
EXTRA_CFLAGS := -DWIN32
EXTRA_ASMFLAGS := -f win32
EXTRA_RCFLAGS := -DWIN32
endif
ifeq ($(platform), x86_64)
ARCH_DEF :=
OUT_DIR := ../out
EXTRA_CFLAGS := -DWIN64
EXTRA_ASMFLAGS := -f x64
EXTRA_RCFLAGS := -DWIN64
endif
endif ##MINGW
2. makefile_lib的编写
新建名为makefile的文件,内容为:
include config.mk
### 假设库的目录结构如下且同一“-”长度的属于同一目录
### -3rdparty #第三方库相关的库文件
### -src #源码路径(包含C文件及头文件)
### -demo #demo示例源码路径
### -build #build目录下有各平台相关的文件夹
### --windows #windows文件夹
### ---makefile_lib #windows下lib的makefile
### ---makefile_demo #windows下demo的makefile
### ---dll_info.t #资源文件模板
### ---dll_info.rc #资源文件
### --objs #obj文件输出目录
### --out #库输出目录
SRCS_DIR := .../../src
OBJS_DIR := ../objs
vpath %.c $(SRCS_DIR)/
vpath %.asm $(SRCS_DIR)/
vpath %.h $(SRCS_DIR)/
C_SRCS := $(wildcard $(SRCS_DIR)/*.c)
A_SRCS := $(wildcard $(SRCS_DIR)/*.asm)
C_OBJS := $(notdir $(subst .c,.o, $(C_SRCS)))
A_OBJS := $(notdir $(subst .asm, .o, $(A_SRCS)))
OBJS := $(filter-out notuse.o, $(C_OBJS) $(A_OBJS))
OBJS_PREFIX := $(addprefix $(OBJS_DIR)/, $(OBJS))
TARGET_NAME := $(OUT_DIR)/lib_sample.lib $(OUT_DIR)/sample.dll
DLL_EXPORT_SYMBOL := $(OUT_DIR)/sample.symbol
DLL_DEF := $(OUT_DIR)/sample.def
DLL_IMPLIB := $(OUT_DIR)/sample.lib
DLL_PDB := $(OUT_DIR)/sample.pdb
OUT_PDB := -debug -PDB:$(DLL_PDB)
CFLAGS := $(EXTRA_CFLAGS)
CFLAGS += -Dstrtod=avpriv_strtod -Dsnprintf=avpriv_snprintf -D_snprintf=avpriv_snprintf -Dvsnprintf=avpriv_vsnprintf
RCFLAGS := $(EXTRA_RCFLAGS)
ASMFLAGS := $(EXTRA_ASMFLAGS)
SRCS_INC := -I. -I$(SRCS_DIR)
LIBRARY_STATIC := -out:$(filter %.lib, $(TARGET_NAME))
LIBRARY_DYNAMIC := -out $(filter %.dll, $(TARGET_NAME))
.PHONY: clean all
all:$(TARGET_NAME)
$(filter %.lib, $(TARGET_NAME)):$(OBJS)
$(AR) $(LIBRARY_STATIC) $(OBJS_PREFIX)
$(filter %.dll, $(TARGET_NAME)):$(OBJS)
makedef $(DLL_EXPORT_SYMBOL) $(OBJS_PREFIX) > $(DLL_DEF)
SubWCRev ./ ./dll_info.t ./dll_info.rc
$(RC) $(RCFLAGS) -fo $(OBJS_DIR)/dll_info.res ./dll_info.rc
$(LD) -dll -def:$(DLL_DEF) -implib:$(DLL_IMPLIB) $(LIBRARY_DYNAMIC) $(OBJS_PREFIX) $(OBJS_DIR)/dll_info.res $(OUT_PDB)
%.o:%.c
$(CC) $(SRCS_INC) $(CFLAGS) -Fo $(OBJS_DIR)/$@ $<
%.o:%.asm:
$(ASM) $(SRCS_INC) $(ASMFLAGS) $< -o $(OBJS_DIR)/$@
clean:
rm -rf $(OBJS_PREFIX) $(TARGET_NAME) $(DLL_IMPLIB) $(DLL_PDB)
3. 关于上述DLL_EXPORT_SYMBOL := $(OUT_DIR)/sample.symbol的写法
sample.symbol中的内容如:
LIBSAMPLE {
global: SAMPLE_*
local:*;
};
(1)、使用MinGW中自带的makedef工具,外加命令**makedef $(DLL_EXPORT_SYMBOL) $(OBJS_PREFIX) > $(DLL_DEF)**便可导出库中的符号,即动态库的引导库;
(2)、global SAMPLE_* 表示所有以SAMPLE_开头的函数符号都会导出即外部可见。
4、Makefile_demo的编写
include config.mk
DEMO_SRC_DIR = ../../demo
vpath %.c $(DEMO_SRC_DIR)
vpath %.h $(DEMO_SRC_DIR)
DEMO_SRCS := $(wildcard $(DEMO_SRC_DIR )/*c)
DEMO_OBJS := $(subst .c,.o, $(DEMO_SRCS))
DEMO_INC := $(DEMO_SRC_DIR)
DEMO_CFLAGS := $(EXTRA_CFLAGS)
DEMO_CFLAGS += -I $(DEMO_INC )
LIB_NAME := $(OUT_DIR)/libxxx.lib
DEMO_LDFLAGS := -libpath:$(LIB_NAME)
TARGET_DEMO= $(OUT_DIR)/xxx.exe
.PHONY: clean all
all: clean $(LIB_NAME) $(TARGET_DEMO)
$(TARGET_DEMO):$(DEMO_OBJS)
$(LD) $(DEMO_LDFLAGS) -PDB:$(OUT_DIR)/demo.pdb -debug -out $@ $< $(LIB_NAME)
%.o:%.c:
$(CC) $(DEMO_CFLAGS) -c -Fo $@ $<
$(LIB_NAME):
make -C ../lib -f Makfile_lib
clean:
rm -rf $(DEMO_OBJS) $(TARGET_DEMO)
make -C ./ -f Makfile_lib clean