【问题标题】:Compilation Error of C code on Linux (Same code compiles on OSX)Linux 上 C 代码的编译错误(在 OSX 上编译相同的代码)
【发布时间】:2012-08-25 01:26:28
【问题描述】:

我正在尝试在 linux 上编译一些我知道在 OSX 上编译的代码,但我遇到了一些问题。

所有文件都有名为 .h 的标题,并且所有文件都在同一个目录中。我是这样编译的:

gcc *.c -std=c99 -lpthread

虽然这段代码可以在 OSX 上编译,但我在安装 Ubuntu 时遇到了一堆奇怪的链接器错误。我是否缺少一些编译器选项?这是一个默认的 Ubuntu 服务器安装,安装了额外的包 gcc 和 build-essential。

In file included from errorLogger.h:24:0,
                 from configParser.h:17,
                 from configParser.c:9:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
configParser.c: In function ‘parseConfigFile’:
configParser.c:114:5: warning: implicit declaration of function ‘getline’ [-Wimplicit-function-declaration]
In file included from errorLogger.h:24:0,
                 from global.h:18,
                 from connection.h:19,
                 from connection.c:10:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
connection.c: In function ‘createConnectionQueue’:
connection.c:189:28: warning: assignment makes integer from pointer without a cast [enabled by default]
In file included from errorLogger.h:24:0,
                 from database.h:16,
                 from database.c:9:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
In file included from errorLogger.h:24:0,
                 from errorLogger.c:10:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
errorLogger.c: In function ‘reportError’:
errorLogger.c:63:5: warning: implicit declaration of function ‘strerror_r’ [-Wimplicit-function-declaration]
errorLogger.c: In function ‘logMessage’:
errorLogger.c:87:5: warning: implicit declaration of function ‘localtime_r’ [-Wimplicit-function-declaration]
errorLogger.c: In function ‘processErrorQueue’:
errorLogger.c:131:17: warning: implicit declaration of function ‘open’ [-Wimplicit-function-declaration]
errorLogger.c:131:57: error: ‘O_APPEND’ undeclared (first use in this function)
errorLogger.c:131:57: note: each undeclared identifier is reported only once for each function it appears in
errorLogger.c:131:68: error: ‘O_CREAT’ undeclared (first use in this function)
errorLogger.c:131:78: error: ‘O_WRONLY’ undeclared (first use in this function)
errorLogger.c:131:88: error: ‘S_IWRITE’ undeclared (first use in this function)
errorLogger.c:131:99: error: ‘S_IREAD’ undeclared (first use in this function)
errorLogger.c:146:13: warning: implicit declaration of function ‘fsync’ [-Wimplicit-function-declaration]
errorLogger.c: In function ‘startErrorLogger’:
errorLogger.c:167:36: error: ‘O_APPEND’ undeclared (first use in this function)
errorLogger.c:167:47: error: ‘O_CREAT’ undeclared (first use in this function)
errorLogger.c:167:57: error: ‘O_WRONLY’ undeclared (first use in this function)
errorLogger.c:167:67: error: ‘S_IWRITE’ undeclared (first use in this function)
errorLogger.c:167:78: error: ‘S_IREAD’ undeclared (first use in this function)
errorLogger.c:214:57: error: ‘O_EXCL’ undeclared (first use in this function)
errorLogger.c:231:27: warning: assignment makes integer from pointer without a cast [enabled by default]
errorLogger.c: In function ‘closeErrorLogger’:
errorLogger.c:246:9: warning: implicit declaration of function ‘pthread_kill’ [-Wimplicit-function-declaration]
In file included from errorLogger.h:24:0,
                 from global.h:18,
                 from global.c:9:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
In file included from main.c:23:0:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
main.c: In function ‘main’:
main.c:53:5: warning: implicit declaration of function ‘blockSignals’ [-Wimplicit-function-declaration]
main.c:61:45: error: invalid application of ‘sizeof’ to incomplete type ‘struct addrinfo’ 
main.c:62:29: error: invalid application of ‘sizeof’ to incomplete type ‘struct addrinfo’ 
main.c:64:10: error: dereferencing pointer to incomplete type
main.c:65:10: error: dereferencing pointer to incomplete type
main.c:66:10: error: dereferencing pointer to incomplete type
main.c:66:23: error: ‘AI_PASSIVE’ undeclared (first use in this function)
main.c:66:23: note: each undeclared identifier is reported only once for each function it appears in
main.c:69:5: warning: implicit declaration of function ‘getaddrinfo’ [-Wimplicit-function-declaration]
main.c:73:9: warning: implicit declaration of function ‘gai_strerror’ [-Wimplicit-function-declaration]
main.c:73:9: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat]
main.c:73:9: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat]
main.c:81:41: error: dereferencing pointer to incomplete type
main.c:83:30: error: dereferencing pointer to incomplete type
main.c:83:46: error: dereferencing pointer to incomplete type
main.c:83:64: error: dereferencing pointer to incomplete type
main.c:96:30: error: dereferencing pointer to incomplete type
main.c:96:44: error: dereferencing pointer to incomplete type
main.c:112:5: warning: implicit declaration of function ‘freeaddrinfo’ [-Wimplicit-function-declaration]
main.c:138:9: error: unknown type name ‘fd_set’
main.c:142:9: warning: implicit declaration of function ‘FD_ZERO’ [-Wimplicit-function-declaration]
main.c:143:9: warning: implicit declaration of function ‘FD_SET’ [-Wimplicit-function-declaration]
main.c:145:9: warning: implicit declaration of function ‘pselect’ [-Wimplicit-function-declaration]
In file included from signalHandling.c:10:0:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
signalHandling.c:12:18: error: unknown type name ‘sigset_t’
signalHandling.c: In function ‘setHandler’:
signalHandling.c:51:53: error: invalid application of ‘sizeof’ to incomplete type ‘struct sigaction’ 
signalHandling.c:52:36: error: invalid application of ‘sizeof’ to incomplete type ‘struct sigaction’ 
signalHandling.c:54:5: warning: implicit declaration of function ‘sigemptyset’ [-Wimplicit-function-declaration]
signalHandling.c:54:30: error: dereferencing pointer to incomplete type
signalHandling.c:60:9: warning: implicit declaration of function ‘sigaddset’ [-Wimplicit-function-declaration]
signalHandling.c:60:35: error: dereferencing pointer to incomplete type
signalHandling.c:67:17: error: dereferencing pointer to incomplete type
signalHandling.c:72:9: warning: implicit declaration of function ‘sigaction’ [-Wimplicit-function-declaration]

【问题讨论】:

标签: c linux gcc ubuntu linker


【解决方案1】:

您可能遗漏了一些#includes,它们在 OS X 上被隐式引入,但在 Linux 上却没有。

从错误消息来看,您可能至少缺少包含:

  • <signal.h>(用于sigset_t 和其他人)
  • <fcntl.h>(用于O_*)
  • <unistd.h>(一堆东西)
  • <netdb.h>(用于各种网络函数和常量)
  • <stdio.h>(用于getline)

您可能还需要定义一些功能宏(例如,_POSIX_C_SOURCE)来获得某些系统相关的功能,包括strerror_r 和pselect。

【讨论】:

  • 更不用说stdio.h(getline)和string.h(strerror_r)。
  • 好吧,这只是关于 S_IWRITE 的错误,不过我已经包含了 sys/stat.h。
  • @charliehorse55:修复你的代码。所有的。这不是编译器的错,而是你的代码的错。如果你在 C99 中遇到这么多错误,我永远不想运行你的代码。
  • @netcoder 他们真的不是错误。对strerror_r 的未定义引用?如果我已经有#include <string.h>(在 OSX 上编译需要),那代码问题如何
  • @charliehorse55 欢迎来到编写可移植代码的有趣世界;-)
【解决方案2】:

我假设直接目标是让代码完全编译,一旦完成,您将返回并修改源代码,以便它在两个平台上开箱即用。这意味着黑客在短期内是可以接受的;当您了解可移植性问题时,它们将得到正确修复。 (如果有什么安慰的话,最初开发软件的系统的第一个替代系统通常是最难的;之后,它通常会变得更容易。)

首先要尝试的是:

gcc *.c -std=gnu99 -lpthread

这告诉系统头文件定义比-std=c99 更多的符号。 (关于这个话题有一些异议,这没关系。至少,如果您将 -pedantic 添加到 -std=c99 编译中,那么除非您还请求 POSIX 支持,否则不会公开 POSIX 定义的标准 C 标头中的符号 — 见下文. 由于您没有-pedantic,这可能不是编译中的一个因素,在这种情况下,悄悄地转到下一个建议,这是未来可移植到 POSIX 系统的基础。)

如果这不足以让你回到正轨,那么你可能需要使用类似的东西:

gcc *.c -std=gnu99 -D_XOPEN_SOURCE=700 -lpthread

这表示“为我提供与 POSIX 2008 对应的 POSIX 和 X/Open 函数”。您可以为旧版本尝试 600 和 500,但在 Linux 上您可能不需要这样做。在适当的时候,您可能会通过配置标头或配置工具自动设置_XOPEN_SOURCE。当您完全编译时,在命令行上指定它是可以的。在适当的时候,您将使用 makefile 或等效项来控制编译,而不是在 shell 中键入 gcc 命令行。)

sigset_t 在 POSIX 下的 <signal.h> 中定义。因此,明确请求 POSIX 支持应该让事情再次正确编译。如果您仍然得到诸如 sigset_t 未声明的类型,那么 Mac OS X 上必须有一个标头,其中包含诸如 <signal.h> 之类的标准标头,但它在 Linux 上执行了一些不相关的任务(因此不包括 <signal.h>) .这将需要源代码审查。但是,它相对不太可能是必要的。

【讨论】:

  • -std=c99 和-std=gnu99 之间的唯一区别是编译器是否会接受某些 GCC 语言扩展。不影响头文件的内容。
  • 很高兴了解<signal.h>,但是通过添加-std=gnu99 来解决可移植性问题?我不是很高兴...
  • @NormanRamsey:有一个短期的“编译”和“任何黑客都可以”操作,这就是我要解决的问题。然后是设计的解决方案,它使黑客变得不必要,因为代码自动或几乎自动在两个系统上正常工作(无论是因为autoconf 还是保守的假设或......)。诸如-std=c99 之类的任何选项都固有地特定于GCC;它一般不适用于其他编译器。
  • 在绝望的情况下,使用 (1) gcc 和 -H 选项(以及您正在使用的任何其他选项)列出头文件的安装位置,以及 (2) @ 987654343@(假设大部分标头都在/usr/include)。这将告诉您sigset_t 是否在您的 Linux 机器上的某个地方定义。如果没有,您需要安装一些额外的软件包。如果是,那么您必须弄清楚如何定义它。您可以对任何其他缺失的符号重复 grep 练习。
  • 该 grep 命令返回一些文件,包括在 /usr/include/ 中运行时的 signal.h。使用 -H 运行 gcc 表明它包含 signal.h 的来源。
【解决方案3】:

您需要包含额外的头文件,因为不同的系统头包含其他不同的系统头。

另外,例如 gcc 一直在努力不包含它不应该包含的标头。

signalHandling.h 是否包括定义 sigset_t 的#include <signal.h>?

编辑

在与 OP 交谈后,问题似乎是编译/链接问题。先将源代码编译成目标文件,然后链接它们似乎已经解决了他们的问题。

【讨论】:

  • signalHandling.h 确实包含 signal.h
  • 你看过signal.h grep -w sigset_t * signal.h:50:typedef __sigset_t sigset_t;
  • 是的,该行存在于signal.h
  • 如果您尝试编译 configParser.c 并将 -E 传递给 gcc - 您可能需要将输出通过管道传输到某处并查找它。
  • 顺便说一句 - 将 -E 传递给 gcc 使它只是预处理文件 - 它不会编译它们。如果存在宏扩展问题/#define 问题,这可以帮助调试。基本上这显示了 gcc 将尝试为您编译的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
相关资源
最近更新 更多