Make对不同的目标文件使用相同的源文件 [英] Make uses same source file for different object files

查看:99
本文介绍了Make对不同的目标文件使用相同的源文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Make为不同的目标文件选择相同的源文件.两者都是文件列表,仅具有不同的文件名.在目标文件之间进行切换,而不在源文件之间进行切换.

Make chooses the same source file for different object files. Both are a list of files, only with different filenames. Make switches between the object files but not the source files.

我已经在StackOverflow上尝试了一些带有相关问题的答案,尽管这些解决方案要么看起来太复杂,不能满足需要,有些则无法工作,而另一些则需要将文件放在一个目录中.

I've already tried some of the answers on StackOverflow with related problems, though those solutions either seem too complicated for what's needed, some don't work and others need the files to be in one directory.

我还尝试过一次(使用gcc)一起编译文件,但是这给文件其余部分的链接带来了一些问题.

I've also tried compiling the files together in one go (with gcc), but this gives some problems with the linking of the rest of the file.

$(OBJFILES): $(SRCFILES)
    $(CC) $(CCFLAGS) -c $< -o $@

$(OBJFILES)包含以下文件: src/kernel.o src/screen/screen_basic.o

$(OBJFILES) contains the following files: src/kernel.o src/screen/screen_basic.o

$(SRCFILES)包含以下文件: src/kernel.c src/screen/screen_basic.c

And $(SRCFILES) contains these files: src/kernel.c src/screen/screen_basic.c

基本上,src/kernel.c会同时编译为src/kernel.osrc/screen/screen_basic.o,而src/screen/screen_basic.c则不会编译.

Basically, src/kernel.c gets compiled to both src/kernel.o and src/screen/screen_basic.o, while src/screen/screen_basic.c never gets compiled.

make运行的内容(我将gcc的选项替换为变量名以使其简短):

What's run by make (I replaced the options for gcc with the variable names to keep it short):

i686-elf-gcc $(CFLAGS) $(WARNINGS) -c src/kernel.c -o src/kernel.o

i686-elf-gcc $(CFLAGS) $(WARNINGS) -c src/kernel.c -o src/screen/screen_basic.o

我真的不知道您需要什么来查看出了什么问题.因此,源文件(全部)位于 https://github.com/m44rtn/vireo-内核. 很高兴知道这是对项目的重写.在上一个版本"中,我手动将文件名添加到了makefile中,效果很好,但是在必须添加新文件或四处移动文件时效果不佳.该makefile位于master分支上(不再是默认分支).

I don't really know what you need to see what's going wrong. So, the source files (all of them) are at https://github.com/m44rtn/vireo-kernel. It may be nice to know that this is a rewrite of the project. In the previous 'version' I manually added the file names to the makefile, which worked perfectly, but isn't nice when you have to add new files or when you're moving them around. That makefile is on the master branch (which ISN'T the default branch anymore).

最新版本:

GNU Make 4.2.1
Built for x86_64-pc-linux-gnu

因此,我希望它能很好地工作.我以为它将只编译列表中的所有文件.不幸的是,事实并非如此.我真的不知道这是怎么回事.

So, I expected this to work absolutely great. I thought it would just compile all files in the list. Unfortunately, it didn't. I don't really know what's going wrong here.

它将kernel.c编译为kernel.o和screen_basic.o.我当然希望它可以将kernel.c编译为kernel.o,并将screen_basic.c编译为screen_basic.o.

It compiles kernel.c to both kernel.o and screen_basic.o. I, of course, had hoped it would compile kernel.c to kernel.o and screen_basic.c to screen_basic.o.

稍后,两个文件被链接.但是,由于它们相同,所以链接器会抛出错误,因为所有内容都定义了两次,这并不理想.

Later on, the two files get linked. However, because they are the same, the linker throws errors because everything is defined twice, which isn't ideal.

我试图通过一次编译每个C文件来解决它,但是这给将Assembly文件与C文件链接带来了一些问题(有时使其成为非GRUB可多重启动的,在我的情况下,这是必须的) ).

I've tried to solve it by compiling every C file in one go, but this gave some issues with linking the Assembly files with the C files (sometimes making it non GRUB multibootable, which is necessarry to have, in my case).

我不知道makefile怎么这样才能表现出来.

I do not know what's wrong with the makefile for it to behave like this.

我尝试过的所有来自堆栈溢出的解决方案:

某些解决方案涉及将所有文件都扔到根目录中,而仅使用:

Some solutions involve throwing all files in the root directory and just using:

%.o: %.c
       (..)

但是,该项目将有很多文件.这使得所有内容都在同一目录中非常烦人,非常快.我认为这还行不通,但是我不知道这是真的,还是我的大脑对我说谎.抱歉.

However, this project will have a lot of files. This makes having everything in the same directory very annoying, very fast. I think this didn't work as well, but I don't know if that's true or just my brain lying to me. Sorry.

我听说过有关静态规则"的信息:

I've heard something about 'static rules':

$(OBJFILES): %.o: %.c
      (..)

这没有用,但是我可能用错了.我不知道.

This didn't work, however I may have used it wrong. I don't know.

我希望makefile尽可能保持不变,因为它非常方便(它会自动检测所有文件).

I like the makefile to stay the same as much as possible, because it's a very convenient one (it just detects all files automatically).

我真的希望我提供了足够的信息,并且还没有问过这个问题.如果是这样,我很抱歉.

I really hope I've provided enough information, and that this question wasn't already asked. If it has been, I'm sorry in advance.

如果您需要更多信息,请询问! :)

If you need more information, please ask! :)

-编辑- 尽管已经使用了五年,但我还是以这种方式制作新手.我一直用错了.我的makefile可能很丑或很糟糕.我确实使用了一个示例来编写makefile.

--EDIT-- I'm quite new to make in this way, although I've used it for five years. I've always used it wrong. It is possible that my makefile is very ugly or bad. And I did use an example to write the makefile.

推荐答案

模式规则不会将所有对象都放在根目录中,请考虑

The pattern rule does not put all objects in root directory, consider

CFILES := path/to/a.c b.c
OBJFILES := $(foreach f,$(CFILES),$(f:%.c=%.o))

all: $(OBJFILES)

%.o: %.c
    $(CC) $(CCFLAGS) -c $< -o $@

这是您得到的:

cc -c path/to/a.c -o path/to/a.o
cc -c b.c -o b.o


以下内容不是建议,而是makefile编程中的一种练习.

如果有$(SRCFILES),并且想一次编译一次,则可以使用:

If you have $(SRCFILES) and want to compile them one at a time, you can use:

define compile
$1.o: $1.c
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach src,$(SRCFILES),$(eval $(call compile, $(src:%.c=%))))

如果源和对象列表的对应关系不是按名称,而是仅按列表中的位置,则可以销毁CFILES列表

If the correspondence of lists of sources and objects is not by name, but only by placement in list, you can destroy the CFILES list

define compile
src := $(CFILES)
CFILES := $(wordlist 2, $(words $(CFILES)), $(CFILES))
$1: $(src)
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))

或者您可以使用帮助程序列表来保持CFILES不变:

Or you may use a helper list, to keep CFILES unchanged:

helperlist := $(CFILES)

define compile
src := $(firstword $(helperlist))
helperlist := $(wordlist 2, $(words $(helperlist)), $(helperlist))
$1: $(src)
    $(CC) $(CCFLAGS) -c $$< -o $$@
endef

$(foreach obj,$(OBJFILES),$(eval $(call compile, $(obj))))

这篇关于Make对不同的目标文件使用相同的源文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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