我编写了以下makefile,它成功地将当前文件夹中的所有.cpp
编译成静态库。
使用clean_library
目标是因为如果我尝试编译并且已经存在.a
文件,则编译将停止并显示以下错误:
ar: libbackend.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: libbackend.a: Inappropriate file type or format
make: *** [libbackend] Error 1
我想加快编译,只编译那些更改的.cpp
。目前,每次都会重新创建所有.o
个文件。
我可以删除-arch
部分并删除依赖项clean_library
。
如果没有它,我怎样才能达到相同的行为?
解决方法是创建一个针对单个体系结构构建的目标,并仅在需要/工作完成时调用为所有体系结构构建的目标。
CC = g++
FLAGS = -g -std=c++14 -Wall -Wextra -O0 #debug
# FLAGS = -std=c++14 -Ofast # release
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
OUT = my_library
$(OUT): $(OBJS)
ar rcs $(OUT).a $^
# libtool -static -o $(OUT).a $^ #other possibilty
%.o: %.cpp Makefile #clean_library
$(CC) $(FLAGS) -c $< -o $@ -arch x86_64 -arch i386
.PHONY: clean clean_library
clean: clean_library
rm -rf *.o
clean_library:
rm -rf $(OUT).a
答案 0 :(得分:1)
您的问题不清楚您想要做什么。您的目标是以不同的方式多次编译相同的代码吗?
您不能以不同方式编译完全相同的目标,并且仍然只更新已修改的文件:make无法知道预先存在的目标文件的编译方式。当make启动并看到foo.o
文件时,它是否已编译为调试?发布?没有办法知道,所以这不起作用。您必须重新编译所有内容才能确定。
人们如何解决这个问题,不同类型的编译输出的名称不同。最常见的方法是使用子目录:将为调试编译的所有文件放在debug
子目录中,并将所有编译好的文件放在release
子目录中。所以你的makefile看起来像这样:
CC = g++
debug_FLAGS = -g -std=c++14 -Wall -Wextra -O0
release_FLAGS = -std=c++14 -Ofast
SRCS := $(wildcard *.cpp)
OBJS := $(SRCS:.cpp=.o)
OUT := my_library.a
all: debug/$(OUT) release/$(OUT)
%/$(OUT):
ar rcs $@ $^
# libtool -static -o $@ $^ #other possibilty
debug/$(OUT): $(addprefix debug/,$(OBJS))
debug/%.o: %.cpp Makefile | debug
$(CC) $(debug_FLAGS) -c $< -o $@ -arch x86_64 -arch i386
release/$(OUT): $(addprefix release/,$(OBJS))
release/%.o: %.cpp Makefile | release
$(CC) $(release_FLAGS) -c $< -o $@ -arch x86_64 -arch i386
debug release:
mkdir -p $@
clean:
rm -rf debug release
.PHONY: debug release clean
如果你想拥有很多不同的选择,那么获得更多的花哨可能是值得的,但只有两个你可能不需要额外的努力。