Makefile编译所有src并生成静态库 [英] Makefile to compile all src and generate static library

查看:91
本文介绍了Makefile编译所有src并生成静态库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大型的C项目,我想使用我的include/路径中的include和我的RTOS的其他includes从src/文件中的所有源代码生成一个静态库./p>

在行命令中,我有一组工作步骤:

  gcc src/drivers/* src/packets/*(...更多文件)-c -I ./include -I ../SatelliteSim/Source/include/-I ../SatelliteSim/Project/-I ../SatelliteSim/Source/portable/GCC/POSIX/-m32 -DDEBUG = 1 -g -UUSE_STDIO -D__GCC_POSIX __ = 1 -pthread 

然后, ar -rsc telecommands.a * .o

我目前对Makefile的尝试如下:

  CXXFLAGS:= -I./include -I ../SatelliteSim/Source/include/-I ../SatelliteSim/Project/-I ../SatelliteSim/Source/portable/GCC/POSIX/-m32 -DDEBUG = 1 -g -UUSE_STDIO -D__GCC_POSIX __ = 1 -pthread模块:=命令/命令\driver_toolkit/driver_toolkit \(...更多模块")来源:= src/$(MODULES).cOBJS:= bin/$(MODULES).o全部:telecommands.atelecommands.a:$(OBJS)ar -rsc $ @ $ ^$(OBJS):$(源)$(CXX)$(CXXFLAGS)-c $ ^ -o $ @ 

但是在编译步骤中,我的包含文件出现了问题.

希望有人可以指出我做错了:)

提前谢谢!

解决方案

您至少有两个主要问题.

第一个是您的 SOURCES OBJS 变量分配错误.当扩展变量时,Make会直接进行文本替换.所以:

  MODULES:= foo bar biz来源:= src/$(MODULES).cOBJS:= bin/$(MODULES).o 

扩展为:

  SOURCES:= src/foo bar biz.cOBJS:= bin/foo bar biz.o 

这显然是不对的.如果您愿意使用针对变量中每个 word 单独运行的GNU make特定功能,则可以获取所需的内容:

  SOURCES:= $(patsubst%,src/%.c,$(MODULES))OBJS:= $(patubst%,bin/%.o,$(MODULES)) 

您的下一个问题是:

  $(OBJS):$(源)$(CXX)$(CXXFLAGS)-c $ ^ -o $ @ 

扩展为以下内容:

  bin/foo.o bin/bar.o bin/biz.o:src/foo.c src/bar.c src/biz.c$(CXX)$(CXXFLAGS)-c $ ^ -o $ @ 

同样,make不会以某种方式推断出您希望使用某种字符串匹配试探法将左侧的每个目标文件与右侧的某个源文件进行某种方式的匹配.那不是make的工作方式.如果左侧有多个目标,make将为每个目标创建一个单独的规则,其中每个目标都包含右侧的所有先决条件.因此,以上内容与您编写的内容相同:

  bin/foo.o:src/foo.c src/bar.c src/biz.c$(CXX)$(CXXFLAGS)-c $ ^ -o $ @bin/bar.o:src/foo.c src/bar.c src/biz.c$(CXX)$(CXXFLAGS)-c $ ^ -o $ @bin/biz.o:src/foo.c src/bar.c src/biz.c$(CXX)$(CXXFLAGS)-c $ ^ -o $ @ 

这意味着它将编译所有源文件以创建每个目标文件.

在makefile文件中,您必须编写一个规则,该规则根据该目标的先决条件一次构建一个一个目标.因此,例如,您可以使用模式规则:

  bin/%.o:src/%.c$(CXX)$(CXXFLAGS)-c $<-o $ @ 

请注意,我只使用 $< 而不是 $ ^ ,因为您只想编译源文件.请注意,这会为每个源文件一次调用编译器,以生成该输出文件.Make不适用于单次调用生成工具会生成许多不同输出的环境(尽管如果您愿意将自己限制在GNU make 4.3或更高版本,则可以根据需要执行此操作.)

如果标头发生更改,这将不会重建任何目标文件,因为您没有列出任何标头作为先决条件.

您提到在编译步骤中遇到我的包含文件问题,但这对我们没有帮助.如果修复了makefile后仍然存在编译问题,则可以打开一个新问题,但请准确(剪切并粘贴)您看到的错误类型以及用于生成产生这些错误的打印的编译行.

I've got a large-ish C project, and I want to generate a static library from all of my sources in the src/ file using the includes from my include/ path, and some other includes for my RTOS.

I have a working set of steps in the line commands that work:

gcc src/drivers/* src/packets/* (...more files) -c -I ./include -I ../SatelliteSim/Source/include/ -I ../SatelliteSim/Project/ -I ../SatelliteSim/Source/portable/GCC/POSIX/ -m32 -DDEBUG=1 -g -UUSE_STDIO -D__GCC_POSIX__=1 -pthread

then, ar -rsc telecommands.a *.o

My current attempt at the Makefile looks like this:

CXXFLAGS := -I./include -I../SatelliteSim/Source/include/ -I../SatelliteSim/Project/ -I../SatelliteSim/Source/portable/GCC/POSIX/ -m32 -DDEBUG=1 -g -UUSE_STDIO -D__GCC_POSIX__=1 -pthread


MODULES := commands/commands \
    driver_toolkit/driver_toolkit \
    (... more 'modules')

SOURCES := src/$(MODULES).c
OBJS := bin/$(MODULES).o

all: telecommands.a

telecommands.a: $(OBJS)
    ar -rsc $@ $^

$(OBJS): $(SOURCES)
    $(CXX) $(CXXFLAGS) -c $^ -o $@

But i'm getting an issue with my include files in the compilation step.

Hopefully someone can point out what I'm doing wrong :)

Thanks in advance!

解决方案

You have at least two major problems.

The first is your SOURCES and OBJS variable assignments are wrong. Make does straightforward textual replacement when it expands variables. So:

MODULES := foo bar biz

SOURCES := src/$(MODULES).c
OBJS := bin/$(MODULES).o

expands to simply:

SOURCES := src/foo bar biz.c
OBJS := bin/foo bar biz.o

which is clearly not right. If you are willing to use GNU make-specific functions, which operate individually on each word in the variable, you can get what you want:

SOURCES := $(patsubst %,src/%.c,$(MODULES))
OBJS := $(patubst %,bin/%.o,$(MODULES))

The next problem you have is this:

$(OBJS): $(SOURCES)
        $(CXX) $(CXXFLAGS) -c $^ -o $@

which expands to something like this:

bin/foo.o bin/bar.o bin/biz.o : src/foo.c src/bar.c src/biz.c
        $(CXX) $(CXXFLAGS) -c $^ -o $@

Again, make is not going to somehow infer that you want each object file on the left to somehow be matched with some source file on the right, using some string matching heuristic. That's not how make works. If there are multiple targets on the left side, make creates a separate rule for each one where each one contains all the prerequisites on the right side. So the above is the same as if you'd written:

bin/foo.o : src/foo.c src/bar.c src/biz.c
        $(CXX) $(CXXFLAGS) -c $^ -o $@
bin/bar.o : src/foo.c src/bar.c src/biz.c
        $(CXX) $(CXXFLAGS) -c $^ -o $@
bin/biz.o : src/foo.c src/bar.c src/biz.c
        $(CXX) $(CXXFLAGS) -c $^ -o $@

which means that it will compile all the source files to create each object file.

In makefiles you have to write a rule that builds one target at a time, from the prerequisites of that target. So for example you can use a pattern rule:

bin/%.o : src/%.c
        $(CXX) $(CXXFLAGS) -c $< -o $@

Note I used $< instead of $^ because you only want to compile the source file. Note that this invokes the compiler one time for each source file, to generate that output file. Make is not well-suited to environments where a single invocation of the build tool generates many different outputs (although if you're willing to restrict yourself to GNU make version 4.3 or higher you can do it if you want).

This will not rebuild any object files if headers change because you've not listed any headers as prerequisites.

You mention getting an issue with my include files in the compilation step but that's not helpful information to us. If you still have compilation problems after fixing your makefile, you can open a new question but please include exactly (cut and paste) the kinds of errors you see and also the compile line that make prints that generates these errors.

这篇关于Makefile编译所有src并生成静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆