Linux上C代码的编译错误(OSX上编译的代码相同)

Linux上C代码的编译错误(OSX上编译的代码相同),c,linux,gcc,ubuntu,linker,C,Linux,Gcc,Ubuntu,Linker,我试图在linux上编译一些我知道在OSX上编译的代码,但我遇到了一些问题 所有文件都有名为.h的标题,并且所有文件都位于同一目录中。我是这样编译的: gcc *.c -std=c99 -lpthread 虽然这段代码是在OSX上编译的,但在我的Ubuntu安装中却出现了一些奇怪的链接器错误。我是否缺少一些编译器选项?这是一个默认的Ubuntu服务器安装,安装了附加的包gcc和build-essential In file included from errorLogger.h:24:0,

我试图在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]

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

首先要尝试的是:

gcc *.c -std=gnu99 -lpthread
这会告诉系统头文件定义比
-std=c99
多得多的符号。(在这个主题上有一些不同意见,这是可以的。至少,如果您将
-pedantic
添加到
-std=c99
编译中,那么POSIX定义的标准C头中的符号不会公开,除非您也请求POSIX支持-请参见下文。因为您没有
-pedantic
,这可能不是编译中的一个因素s、 在这种情况下,请悄悄地转到下一个建议,这是将来可移植到POSIX系统的基础。)

如果这还不足以让您回到正轨,那么您可能需要使用以下方法:

gcc *.c -std=gnu99 -D_XOPEN_SOURCE=700 -lpthread
这表示“为我提供对应于POSIX 2008的POSIX和X/Open函数”。对于旧版本,您可以尝试600和500,但在Linux上可能不需要这样做。在适当的时候,您可能会通过配置头或配置工具自动设置
\u XOPEN\u SOURCE
。虽然您需要编译一些东西,但在命令行中指定它是可以的。在适当的时候,您将使用
makefile
或等效工具来控制编译,而不是在shell中键入
gcc
命令行。)


sigset\u t
在POSIX下的
中定义。因此,明确请求POSIX支持应该可以让事情再次正确编译。如果您仍然得到未声明的类型,例如
sigset\u t
,那么Mac OS X上必须有一个包含标准头的头,例如
,但它在Linux上执行一些不相关的任务(因此不包括
)。这需要对源代码进行仔细检查。但是,它相对来说不太可能是必需的。

您需要包括其他头文件,因为不同的系统头包括其他不同的系统头文件

另外,例如,gcc一直在努力避免包含不应该包含的标题

在定义sigset的地方,
signalHandling.h
是否包括
#include

编辑


与OP讨论后,问题似乎是编译/链接问题。首先将源代码编译成目标文件,然后链接它们,这似乎解决了它们的问题。

您可能缺少一些在OS X上隐式引入的
#include
s,但在Linux上没有

从错误消息判断,您可能至少缺少以下内容:

  • (用于
    sigset\u t
    和其他)
  • (对于
    O.*
  • (对于一堆东西)
  • (用于各种网络功能和常数)
  • (用于
    getline

您可能还需要定义一些功能宏(例如,
\u POSIX\u C\u SOURCE
)来获得某些依赖于系统的函数,包括
strerror\u r
pselect

对于初学者来说,
gcc-std=c99-lpthread*.C
gcc对参数顺序没有偏好,这不完全正确,请参阅
-std=c99
-std=gnu99
之间的唯一区别是编译器是否接受某些GCC语言扩展。它不影响头文件的内容。很高兴了解
,但通过添加
-std=gnu99
解决了可移植性问题?我不太高兴…@NormanRamsey:有一个短期的“编译”和“任何黑客都可以”操作,这就是我要解决的问题。然后是工程解决方案,它使得黑客行为变得不必要,因为代码自动或几乎自动地在两个系统上正常工作(无论是因为
autoconf
还是保守的假设或…)。任何选项,如
-std=c99
,本质上都是特定于GCC的;一般来说,它不适用于其他编译器。如果需要删除,请使用(1)
gcc
-H
选项(以及您正在使用的任何其他选项)列出头的安装位置,以及(2)
cd/usr/include;grep-r-e sigset_t-l.
(假设大多数头都在
/usr/include
中)。这将告诉您是否在Linux机器上的某个地方定义了
sigset\u t
。如果没有,您需要安装一些额外的软件包。如果是的话,那么你必须找出如何定义它。您可以对任何其他缺少的符号重复
grep
练习。该grep命令在/usr/include/中运行时会返回一些文件,包括signal.h。用-H运行gcc表明它包含signal.H from。更不用说
stdio.H
(对于
getline
)和
string.H
(对于
strerror\u r
)。好吧,这仅仅是关于
S IWRITE
的错误,我已经包含了
sys/stat.H