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

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

问题描述

我有一个大型的 C 项目,我想从 src/文件中的所有源代码生成一个静态库,使用来自我的包含/路径的包含,以及我的 RTOS 的其他一些包含.

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

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

我目前对 Makefile 的尝试如下所示:

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 :)

提前致谢!

推荐答案

您至少有两个主要问题.

You have at least two major problems.

首先是你的 SOURCESOBJS 变量赋值错误.Make 在扩展变量时会进行简单的文本替换.所以:

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

扩展为简单:

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

这显然是不对的.如果您愿意使用 GNU make-specific 函数,这些函数对变量中的每个 单词 进行单独操作,您可以获得您想要的:

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 $@

扩展成这样:

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 为每个目标创建一个单独的规则,其中每个都包含右侧的所有先决条件.所以上面的内容和你写的一样:

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.

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

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 $@

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

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.

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

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天全站免登陆