gcc 不会让我在添加源文件后“只编译”c 源代码

Posted

技术标签:

【中文标题】gcc 不会让我在添加源文件后“只编译”c 源代码【英文标题】:gcc won't let me 'just compile' c source after addition of source files 【发布时间】:2016-08-24 14:20:06 【问题描述】:

我正在编写一个大致如下所示的程序:

src/中的一些主要代码 Demo1/中的一些代码

我将 Demo1 的内容编译成 .o,然后是 .so,并在创建主可执行文件时使用该 .so。 (Demo1的代码在src/中)。 Demo1 使用了一个已经编译好的库 lib1,它与它的二进制文件和源代码位于一个单独的文件夹中。

这就是我构建 Demo1 的方式:

gcc -c -fpic Demo1/src/*.c -Ilib1/include -o Demo1/build/demo1.o  
gcc -shared Demo1/build/demo1.o -Llib1/lib -llib1 -o Demo1/dist/libDemo1.so

现在我向 Demo1 添加了一个新的 .c 文件和一个新的 .h,然后在我运行构建脚本(其中包含上面的两个命令等)时发生了这种情况:

gcc: 致命错误:无法将 -o 与 -c、-S 或 -E 与多个文件一起指定

这是什么意思?我认为添加源文件不会导致这种情况.. 当然,我过去一直在同一行上使用-c-o,除此之外-句子的最后一部分在语法上对我来说不是最清楚的......(这是否意味着我可以' t 指定 -o 和 -E 当 -E 有多个文件)?

我在 Ubuntu 14.04 机器上运行 gcc 4.8.4。 提前致谢。

【问题讨论】:

gcc 的手册页具体有什么不明白的地方?您是否查看了您使用的选项?它们是什么意思? 如果您以前只有一个源文件,而现在有两个,那么肯定会导致这种情况。你认为它想做什么? 【参考方案1】:

-o 选项指定(单个)输出文件。当您有以下情况时,轻率地忽略不立即相关的选项:

gcc -c file1.c file2.c -o output.o

file1.cfile2.c 的输出是否进入output.o

GCC 告诉您,您不能这样做。要么你必须使用:

gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o

或者你必须使用:

gcc -c file1.c file2.c

这就是错误消息的内容。

请注意,您的子目录中有源代码。编译器的默认输出将在当前目录中。那就是:

gcc -c Demo1/file1.c Demo1/file2.c

将创建输出文件./file1.o./file2.o。 AFAIK,没有办法指定输出 directory(例如,-o directory-name 给出了类似error: unable to open output file 'directory-name': 'Is a directory' 的错误)。因此,使用显式输出文件进行单独编译可能是您工作的最佳方式。这也是构建系统(例如 make)会做的事情。

【讨论】:

【参考方案2】:

抱怨您尝试将多个 .c 文件编译成单个 .o 文件。当您省略链接步骤时,每个源文件都会生成一个单独的输出文件。

当指定-c(仅编译)标志时,输出文件的默认名称是.c 替换为.o。这会将中间文件放在当前目录中。

让编译器在编译步骤中命名输出文件,并在链接步骤中包含所有目标文件:

cd Demo1/build
gcc -c -fpic ../src/*.c -Ilib1/include 
gcc -shared *.o -Llib1/lib -llib1 -o ../dist/libDemo1.so

另一种方法是将编译步骤拆分为每个源文件的一行。

如您所见,这对用户不是很友好,并且会随着您创建更多文件而变得混乱。

如果我是你,我会创建一个makefile(或者如果我想为我的简历增添趣味,可以学习一些更新的构建系统)。这样,您可以使用规则指定编译方式,然后使用单个命令进行构建。

【讨论】:

注意目标文件不会在Demo1/src;他们将在当前目录中。如果您想要 Demo1/src 中的目标文件,则必须使用指定的输出文件(使用 -o Demo1/src/whatever.o)分别编译每个文件。 @JonathanLeffler 感谢您提醒我。自从我在没有 makefile 帮助的情况下使用多个目录以来已经有一段时间了。当我看到我编辑的答案时,很容易理解为什么。

以上是关于gcc 不会让我在添加源文件后“只编译”c 源代码的主要内容,如果未能解决你的问题,请参考以下文章

Makefile gcc基础

静态库与动态库

#导入Word文档图片# Linux下GDB调试工具的运用

GCC 编译详解

gcc编译过程中的各种参数含义

[2018.04.28] C with Pointer