Go 程序在 MacOS Catalina 升级后不会 运行
Go programs won't run after MacOS Catalina upgrade
这可能是一个奇怪的问题,但是在 MacOS Catalina 升级后,一些用 Go 编写的程序不会 运行 在我的 MacBook Pro 上。
然而,一个基本的“Hello World”程序 运行s,但后来我使用 net/http
包编写程序时出现以下错误:
Note: The programs are correct, they run fine inside a Docker container
输出(IntelliJ):
# runtime/cgo
In file included from gcc_darwin_amd64.c:6:
/usr/local/include/pthread.h:331:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:2: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:331:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:34: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:540:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:2: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:540:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:34: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
我已经尝试过的东西:
- 重新安装
go
- 重新安装
xcode
- 检查
GOPATH
& GOROOT
是否设置正确
已用:
MacOS version - Catalina 10.15.6
Go version - go1.15.2 darwin/amd64
在终端 window 中键入 xcode-select -print-path
并检查您的安装目录。在我的例子中,输出是:/Applications/Xcode.app/Contents/Developer
如果情况相同,则在您的终端上使用以下命令可以解决问题:
sudo xcode-select --switch /Library/Developer/CommandLineTools
另一种选择是使用CGO_CPPFLAGS,如issue中所述,但它会在会话中起作用:
export CGO_CPPFLAGS="-Wno-error -Wno-nullability-completeness -Wno-expansion-to-defined -Wno-builtin-requires-header"
可悲的是,none 的试用成功了。
我使用 IntelliJ IDEA Ultimate 已经有一段时间了。所以我尝试使用 IDE 设置 Go SDK、GOROOT 和 GOPATH(只是我想到的一个想法)。
我 uninstalled/deleted 我的 MacBook 上所有与 Go 相关的东西。
然后我在IntelliJ上安装了Go插件IDEA,果然提示Go SDK不可用,GOROOT和GOPATH都没有设置。
我按照说明进行操作,IntelliJ IDEA 负责其余的工作!
它下载并安装了 Go SDK,要求我 select GOPATH,它索引了一些东西,现在一切都运行得很好!
这是 macOS 工具附带的 <pthread.h>
中的错误:
这个宏甚至是伪造的,原因不止一个! <pthread.h>
中的定义是这样的:
#define _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT \
defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1))
宏展开式没有正确括起来。在同一个文件中这样使用宏:
#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT
扩展为:
#if !defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1))
!
仅适用于第一个测试 defined(SWIFT_CLASS_EXTRA)
而不是整个布尔表达式。
编译器没有检测到这个问题,它只是抱怨来自宏扩展的 defined
预处理器运算符,它具有 C 标准中指定的未定义行为:
6.10.1 Conditional inclusion
[...]
Constraints
1 The expression that controls conditional inclusion shall be an integer constant expression except that: identifiers (including those lexically identical to keywords) are interpreted as described below; and it may contain unary operator expressions of the form
defined identifier
or
defined ( identifier )
which evaluate to 1
if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define
preprocessing directive without an intervening #undef
directive with the same subject identifier), 0
if it is not.
2 Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token (6.4).
Semantics
3 Preprocessing directives of the forms
#
if
constant-expression new-line groupopt
#
elif
constant-expression new-line groupopt
check whether the controlling constant expression evaluates to nonzero.
4 Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined
is generated as a result of this replacement process or use of the defined
unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and the defined
unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0
, and then each preprocessing token is converted into a token. The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6. For the purposes of this token conversion and evaluation, all signed integer types and all unsigned integer types act as if they have the same representation as, respectively, the types intmax_t
and uintmax_t
defined in the header <stdint.h>
. This includes interpreting character constants, which may involve converting escape sequences into execution character set members. Whether the numeric value for these character constants matches the value obtained when an identical character constant occurs in an expression (other than within a #if
or #elif
directive) is implementation-defined. Also, whether a single-character character constant may have a negative value is implementation-defined.
此相关短语是 如果令牌 defined
是由于此替换过程或使用 defined
一元运算符而生成的,与指定的两个运算符之一不匹配宏替换之前的形式,行为未定义。
目前还不清楚 generated 是否只是作为宏扩展的一部分生成,或者更具体地说,是通过标记粘贴生成的。 clang 似乎认为宏扩展产生的任何 defined
标记在 #if
控制表达式中具有未定义的行为。
出于这两个原因,这似乎是 <pthread.h>
中的错误,需要 Apple 修复。
这可能是一个奇怪的问题,但是在 MacOS Catalina 升级后,一些用 Go 编写的程序不会 运行 在我的 MacBook Pro 上。
然而,一个基本的“Hello World”程序 运行s,但后来我使用 net/http
包编写程序时出现以下错误:
Note: The programs are correct, they run fine inside a Docker container
输出(IntelliJ):
# runtime/cgo
In file included from gcc_darwin_amd64.c:6:
/usr/local/include/pthread.h:331:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:2: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:331:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:34: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:540:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:2: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
/usr/local/include/pthread.h:540:6: error: macro expansion producing 'defined' has undefined behavior [-Werror,-Wexpansion-to-defined]
/usr/local/include/pthread.h:200:34: note: expanded from macro '_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT'
我已经尝试过的东西:
- 重新安装
go
- 重新安装
xcode
- 检查
GOPATH
&GOROOT
是否设置正确
已用:
MacOS version - Catalina 10.15.6
Go version - go1.15.2 darwin/amd64
在终端 window 中键入 xcode-select -print-path
并检查您的安装目录。在我的例子中,输出是:/Applications/Xcode.app/Contents/Developer
如果情况相同,则在您的终端上使用以下命令可以解决问题:
sudo xcode-select --switch /Library/Developer/CommandLineTools
另一种选择是使用CGO_CPPFLAGS,如issue中所述,但它会在会话中起作用:
export CGO_CPPFLAGS="-Wno-error -Wno-nullability-completeness -Wno-expansion-to-defined -Wno-builtin-requires-header"
可悲的是,none 的试用成功了。
我使用 IntelliJ IDEA Ultimate 已经有一段时间了。所以我尝试使用 IDE 设置 Go SDK、GOROOT 和 GOPATH(只是我想到的一个想法)。
我 uninstalled/deleted 我的 MacBook 上所有与 Go 相关的东西。
然后我在IntelliJ上安装了Go插件IDEA,果然提示Go SDK不可用,GOROOT和GOPATH都没有设置。
我按照说明进行操作,IntelliJ IDEA 负责其余的工作!
它下载并安装了 Go SDK,要求我 select GOPATH,它索引了一些东西,现在一切都运行得很好!
这是 macOS 工具附带的 <pthread.h>
中的错误:
这个宏甚至是伪造的,原因不止一个! <pthread.h>
中的定义是这样的:
#define _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT \
defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1))
宏展开式没有正确括起来。在同一个文件中这样使用宏:
#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT
扩展为:
#if !defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1))
!
仅适用于第一个测试 defined(SWIFT_CLASS_EXTRA)
而不是整个布尔表达式。
编译器没有检测到这个问题,它只是抱怨来自宏扩展的 defined
预处理器运算符,它具有 C 标准中指定的未定义行为:
6.10.1 Conditional inclusion
[...]
Constraints
1 The expression that controls conditional inclusion shall be an integer constant expression except that: identifiers (including those lexically identical to keywords) are interpreted as described below; and it may contain unary operator expressions of the form
defined identifier
or
defined ( identifier )
which evaluate to
1
if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a#define
preprocessing directive without an intervening#undef
directive with the same subject identifier),0
if it is not.2 Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token (6.4).
Semantics
3 Preprocessing directives of the forms
#
if
constant-expression new-line groupopt
#
elif
constant-expression new-line groupoptcheck whether the controlling constant expression evaluates to nonzero.
4 Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token
defined
is generated as a result of this replacement process or use of thedefined
unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and thedefined
unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number0
, and then each preprocessing token is converted into a token. The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6. For the purposes of this token conversion and evaluation, all signed integer types and all unsigned integer types act as if they have the same representation as, respectively, the typesintmax_t
anduintmax_t
defined in the header<stdint.h>
. This includes interpreting character constants, which may involve converting escape sequences into execution character set members. Whether the numeric value for these character constants matches the value obtained when an identical character constant occurs in an expression (other than within a#if
or#elif
directive) is implementation-defined. Also, whether a single-character character constant may have a negative value is implementation-defined.
此相关短语是 如果令牌 defined
是由于此替换过程或使用 defined
一元运算符而生成的,与指定的两个运算符之一不匹配宏替换之前的形式,行为未定义。
目前还不清楚 generated 是否只是作为宏扩展的一部分生成,或者更具体地说,是通过标记粘贴生成的。 clang 似乎认为宏扩展产生的任何 defined
标记在 #if
控制表达式中具有未定义的行为。
出于这两个原因,这似乎是 <pthread.h>
中的错误,需要 Apple 修复。