假设我们有一个客户端 - 服务器应用程序,由一个makefile编译。服务器使用libtask为并行客户端服务。客户端使用ncurses来获取某些图形。 目录树看起来像这样:
./
--bin/
--obj/
--src/
----client/*.c
----server/*.c
--makefile
所以,这是makefile。我们可以简化它吗?我读了一些关于stackoverflow的相关问题,我认为它几乎是理想的,除了链接二进制文件,我们可以看到重复的命令。关于样式/跨平台工作的一些建议将是有用的。谢谢!
.PHONY: all clean
TASKLIB = -ltask
CURSESLIB = -lncurses
CFLAGS = -Wall -Werror -pedantic
bin = server client
obj_dir = obj
bin_dir = bin
ssource := src/server
csource := src/client
search_wildcard s := $(addsuffix /*.c, $(ssource))
search_wildcard c := $(addsuffix /*.c, $(csource))
sobjs = $(addprefix $(obj_dir)/, $(patsubst %.c, %.o, $(notdir $(wildcard $(search_wildcard s)))))
cobjs = $(addprefix $(obj_dir)/, $(patsubst %.c, %.o, $(notdir $(wildcard $(search_wildcard c)))))
all: $(bin)
@echo "done!"
server: CFLAGS+=$(TASKLIB)
client: CFLAGS+=$(CURSESLIB)
clean:
rm $(sobjs) $(cobjs) $(obj_dir)/*.d $(bin_dir)/client $(bin_dir)/server
VPATH := $(ssource) $(csource)
server: $(sobjs)
@test -d $(bin_dir) || mkdir $(bin_dir)
@echo "Linking $(@F)..."
@$(CC) $< $(CFLAGS) -o $(bin_dir)/$@
client: $(cobjs)
@test -d $(bin_dir) || mkdir $(bin_dir)
@echo "Linking $(@F)..."
@$(CC) $< $(CFLAGS) -o $(bin_dir)/$@
$(obj_dir)/%.o: %.c
@test -d $(obj_dir) || mkdir $(obj_dir)
@echo "Compiling $(@F)..."
@$(CC) $< $(CFLAGS) -c -MD -o $@
include $(wildcard $(obj_dir)/*.d)
答案 0 :(得分:0)
CMake是一个跨平台的构建系统生成器。项目使用名称为CMakeLists.txt的源树的每个目录中包含的与平台无关的CMake列表文件指定其构建过程。用户使用CMake在其平台上为本机工具生成构建系统来构建项目。
http://www.cmake.org/cmake/help/cmake2.4docs.html
http://linux.die.net/man/1/cmake
也许这可以帮到你
答案 1 :(得分:0)
你可能比你需要的更通用:例如,我不会使目录可配置 - 只对install
目标的目的地有意义。
无论如何,这就是我编写makefile(未经测试)的方式:
CFLAGS := -Wall -Werror -pedantic
RM := rm -f
MKDIR := mkdir -p
BINARIES := bin/server bin/client
SERVER_OBJECTS := $(patsubst src/%.c, obj/%.o, $(wildcard src/server/*.c))
CLIENT_OBJECTS := $(patsubst src/%.c, obj/%.o, $(wildcard src/client/*.c))
OBJECTS := $(SERVER_OBJECTS) $(CLIENT_OBJECTS)
.PHONY : build clean realclean
build : $(BINARIES)
clean :
$(RM) $(OBJECTS) $(OBJECTS:%.o=%.d)
realclean : clean
$(RM) $(BINARIES)
bin/server : LDLIBS := -ltask
bin/client : LDLIBS := -lncurses
bin/server : $(SERVER_OBJECTS)
bin/client : $(CLIENT_OBJECTS)
$(BINARIES) :
@$(MKDIR) $(dir $@)
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
include $(wildcard obj/*.d)
$(OBJECTS) : obj/%.o : src/%.c
@$(MKDIR) $(dir $@)
$(CC) $(CFLAGS) -c -MD -o $@ $<
答案 2 :(得分:0)
我有几点意见:
将$(obj_dir)添加到服务器和客户端的配方中。就目前而言,每次运行make都会重建二进制文件。
添加一个配方来制作目录(bin和obj)并从客户端&amp;中删除它们。服务器食谱
$&LT;对于服务器和客户端配方应该是$ ^
通过删除bin /和obj /
或许使用-MMD而不是-MD来排除系统依赖性
向CFLAGS添加更多警告
LDFLAGS应该用于链接而不是CFLAGS
如果在服务器和客户端目录中使用相同的文件名,则构建将失败。
以下是我更改的行:
all: $(bin_dir) $(obj_dir) $(bin_dir)/server $(bin_dir)/client
@echo "done!"
clean:
rm -rf $(obj_dir) $(bin_dir)
$(bin_dir) $(obj_dir) :
test -d $@ || mkdir $@
$(bin_dir)/server: $(sobjs)
$(CC) $^ $(CFLAGS) -o $@
$(bin_dir)/client: $(cobjs)
$(CC) $^ $(CFLAGS) -o $@
$(obj_dir)/%.o: %.c
$(CC) $< $(CFLAGS) -c -MMD -o $@
如Christoph所示,您还可以将服务器和客户端配方合并为一个。我的猜测是专家可以做得更小,但遗憾的是我不是一个。 $(sobjs)
和$(cobjs)
看起来特别适合减少。