【问题标题】:GCC Output Object File in Same Directory as Source FileGCC 输出目标文件与源文件位于同一目录中
【发布时间】:2017-03-24 01:05:11
【问题描述】:

假设我有一个这样的文件夹结构:

|
| - src
    |- file.c
    |- folderOne
        |- file2.c
        |- file3.S
    |- folderTwo
        |-folderThree
            |- file4.c

我目前有一个生成文件,可以像这样抓取我的所有程序集和 C 文件:

S_SRC  = $(wildcard *.S) $(wildcard **/*.S)
C_SRC  = $(wildcard *.c) $(wildcard **/*.c)

S_OBJS = $(patsubst %.S,%.o,$(filter %.S,$(S_SRC)))
C_OBJS = $(patsubst %.c,%.o,$(filter %.c,$(C_SRC)))

OBJS   = $(S_OBJS) $(C_OBJS)

这些行只获取所有.c.S 文件,并创建它们等效的.o 值。我的管道在源文件上运行 GCC,然后手动链接它们。

我使用以下语法运行 GCC:

$(OBJS): $(C_SRC) $(S_SRC)
    $(CC) $(CC_F) $(S_SRC) $(C_SRC) -o $(OBJS)

我将源文件传递给 GCC 的地方。 CC_F 变量是我的标志变量:

CC_F   = -m32 -Wall -Wextra -Werror -g -c

然后我想像这样运行我的链接器:

$(PROGR): $(OBJS) $(LINK_SRC)
    $(LD) $(LD_F) -o $(PROGR) $(OBJS)

同样,LD_F 只是我的链接器标志。

我目前遇到的问题是,对于不止一次的源文件,GCC 无法解析命令,输出如下内容:

gcc -m32 -Wall -Wextra -Werror -g -c  src/file1.S  src/file2.c -o src/file1.o src/file2.o
gcc: error: src/file2.o: No such file or directory

我想做的是让 GCC 将每个源文件的目标文件输出到与源文件相同的目录中。在给定的示例中,运行 makefile 应该会产生以下布局:

|
| - src
    |- file.c
    |- file.o
    |- folderOne
        |- file2.c
        |- file2.o
        |- file3.S
        |- file3.o
    |- folderTwo
        |-folderThree
            |- file4.c
            |- file4.o

在我当前的设置以及不同数量的目录/文件下,这怎么可能。

【问题讨论】:

  • 您不能有多个输出文件。文件src/file2.o 被视为源对象但不存在。更改您的 Makefile 以一次编译一个源并输出一个对象。
  • @alvits 你能告诉我怎么做吗?

标签: c gcc makefile


【解决方案1】:

gcc 不允许在一次调用中使用多个输出文件。您需要运行 gcc 的次数与您需要创建的目标文件的数量一样多。

一个目标文件可能包含 1 个或多个编译源。

你需要从你的 Makefile 中移除这个块:

$(OBJS): $(C_SRC) $(S_SRC)
    $(CC) $(CC_F) $(S_SRC) $(C_SRC) -o $(OBJS)

假设每个源文件需要 1 个目标文件,请将其替换为:

**/%.o: **/%.c
    $(CC) $(CC_F) -c -o $@ $<

这将在与通过目录递归的源文件相同的目录中创建目标文件。

【讨论】:

  • 对您的解决方案的一个警告是:假设我有一个未知数量的目录,那么 make 将如何处理这个问题?
  • 如果您有任意数量的文件夹,您如何知道将哪些目标文件链接在一起以生成可执行程序?这就是 autoconf 和 automake 派上用场的地方。您需要删除您的问题并专门询问 automake 和 autoconf 功能。此答案适用于您的原始帖子。得到答案后不要更改问题。
  • 我确切地知道哪些目标文件要链接在一起,因为我可以从任意数量的目录和任意数量的文件中获取源文件名,并将它们全部转换为 .o 扩展名,同时保持到每个文件都有我的遗嘱卡。生成目标文件后,我需要做的就是将它们传递给我的链接器,因此在 GCC 触及其中任何一个之前,我知道它们都在哪里。
  • @Tanishqdubey - 我更新了答案以在需要时递归编译源代码。
猜你喜欢
  • 1970-01-01
  • 2016-10-24
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 2012-11-26
相关资源
最近更新 更多