【发布时间】:2016-11-12 16:11:06
【问题描述】:
问题:在 Ruby 解释器 C 代码中有几个部分在 macOS 和 BSD 上调用 __syscall 函数。这在 macOS 领域是非常糟糕的行为,因为它是一个私有(且易变)的 API。
__syscall 用法仅根据 HAVE_ 定义有条件地包含在内,所以我想知道是否可以在没有它的情况下编译 Ruby。这是来自io.c 的示例:
#if defined(HAVE___SYSCALL) && (defined(__APPLE__) || defined(__OpenBSD__))
/* Mac OS X and OpenBSD have __syscall but don't define it in headers */
off_t __syscall(quad_t number, ...);
#endif
...some time later...
static VALUE
rb_f_syscall(int argc, VALUE *argv)
{
VALUE arg[8];
...a bunch of platform checks that usually end up doing this...
# define SYSCALL __syscall
...some time later...
switch (argc) {
case 1:
retval = SYSCALL(num);
break;
case 2:
retval = SYSCALL(num, arg[0]);
break;
case 3:
retval = SYSCALL(num, arg[0],arg[1]);
break;
... and so on up to case 8...
}
... function returns and then...
#undef SYSCALL
}
眼尖的读者也会注意到,即使是 Ruby 开发人员也不喜欢使用 __syscall - 他们想用 DL (Fiddle) 库代替它。
约束:我不想分叉 Ruby 解释器源来执行此操作,因为这将导致对分叉的持续繁琐维护。相反,我想在编译执行此操作的 Ruby 时将参数传递给构建工具。
问题:我是否可以强制未定义相关的 HAVE__ 宏之一,或者禁用 configure.in 中的 AC_CHECK_HEADERS,从而防止在此处使用 __syscall,方法是将参数传递给构建工具?
【问题讨论】:
-
您准备重新生成配置脚本吗?如果是这样,您只需创建一个包含您需要的代码的合适文件(例如
acmacsyscall.m4),然后调整构建过程以便拾取文件(可能使用aclocal -I .作为一个步骤 - 或者如果您使用不同的目录将.m4文件保留在别处)。当然,您还必须安排调用宏;这可能意味着在configure.ac的某处添加一行,或者在configure脚本的顶级构建中使用的任何输入文件。