[ruby-dev:50098] [Ruby trunk Bug#13489] "make test-all" fails on macOS with case-sensitive filesystem

From: nobu@...
Date: 2017-04-24 14:26:28 UTC
List: ruby-dev #50098
Issue #13489 has been updated by nobu (Nobuyoshi Nakada).


これでどうでしょうか。

```diff
diff --git i/dir.c w/dir.c
index e3099f4973..b02640e912 100644
--- i/dir.c
+++ w/dir.c
@@ -1528,34 +1528,52 @@ join_path(const char *path, long len, int dirsep, const char *name, size_t namle
 
 #ifdef HAVE_GETATTRLIST
 # if defined HAVE_FGETATTRLIST
-#   define is_case_sensitive(dirp, path) is_case_sensitive(dirp)
+#   define is_case_sensitive(dirp, path) ruby_dir_case_sensitive_p(dirp)
 # else
-#   define is_case_sensitive(dirp, path) is_case_sensitive(path)
+#   define is_case_sensitive(dirp, path) ruby_path_case_sensitive_p(path)
 # endif
-static int
-is_case_sensitive(DIR *dirp, const char *path)
-{
+typedef struct {
+    struct attrlist list;
     struct {
 	u_int32_t length;
 	vol_capabilities_attr_t cap[1];
-    } __attribute__((aligned(4), packed)) attrbuf[1];
-    struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, 0, ATTR_VOL_INFO|ATTR_VOL_CAPABILITIES};
-    const vol_capabilities_attr_t *const cap = attrbuf[0].cap;
+    } __attribute__((aligned(4), packed)) attr;
+} vol_case_sensitive_attr_t;
+#define vol_case_sensitive_attr_init \
+    {{ATTR_BIT_MAP_COUNT, 0, 0, ATTR_VOL_INFO|ATTR_VOL_CAPABILITIES}}
+
+static inline int
+vol_case_sensitive_p(const vol_capabilities_attr_t *const cap)
+{
     const int idx = VOL_CAPABILITIES_FORMAT;
     const uint32_t mask = VOL_CAP_FMT_CASE_SENSITIVE;
-
-#   if defined HAVE_FGETATTRLIST
-    if (fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
-	return -1;
-#   else
-    if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW))
-	return -1;
-#   endif
     if (!(cap->valid[idx] & mask))
 	return -1;
     return (cap->capabilities[idx] & mask) != 0;
 }
 
+# if defined HAVE_FGETATTRLIST
+static int
+ruby_dir_case_sensitive_p(DIR *dirp)
+{
+    vol_case_sensitive_attr_t a = vol_case_sensitive_attr_init;
+
+    if (fgetattrlist(dirfd(dirp), &a.list, &a.attr, sizeof(a.attr), FSOPT_NOFOLLOW))
+	return -1;
+    return vol_case_sensitive_p(a.attr.cap);
+}
+# endif
+
+int
+ruby_path_case_sensitive_p(const char *path)
+{
+    vol_case_sensitive_attr_t a = vol_case_sensitive_attr_init;
+
+    if (getattrlist(path, &a.list, &a.attr, sizeof(a.attr), FSOPT_NOFOLLOW))
+	return -1;
+    return vol_case_sensitive_p(a.attr.cap);
+}
+
 static char *
 replace_real_basename(char *path, long base, rb_encoding *enc, int norm_p, int flags, rb_pathtype_t *type)
 {
diff --git i/file.c w/file.c
index c576c85c0a..be528fee1b 100644
--- i/file.c
+++ w/file.c
@@ -242,6 +242,8 @@ rb_str_encode_ospath(VALUE path)
 
 #ifdef __APPLE__
 # define NORMALIZE_UTF8PATH 1
+int ruby_path_case_sensitive_p(const char *path);
+
 static VALUE
 rb_str_append_normalized_ospath(VALUE str, const char *ptr, long len)
 {
@@ -272,10 +274,12 @@ rb_str_normalize_ospath(const char *ptr, long len)
     const char *p = ptr;
     const char *e = ptr + len;
     const char *p1 = p;
-    VALUE str = rb_str_buf_new(len);
     rb_encoding *enc = rb_utf8_encoding();
-    rb_enc_associate(str, enc);
+    VALUE str = rb_enc_str_new(ptr, len, enc);
 
+    if (ruby_path_case_sensitive_p(RSTRING_PTR(str)) == 1)
+	return str;
+    rb_str_set_len(str, 0);
     while (p < e) {
 	int l, c;
 	int r = rb_enc_precise_mbclen(p, e, enc);
````

----------------------------------------
Bug #13489: "make test-all" fails on macOS with case-sensitive filesystem
https://bugs.ruby-lang.org/issues/13489#change-64449

* Author: watson1978 (Shizuo Fujita)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
普段使用している macOS は HFS+ case-sensitive でフォーマットしています。
"make test-all" をそのマシン上で実行すると以下のようなエラーが発生し、
どうやら conftest.c でのコンパイルエラーが原因のようです。

conftest.c には

~~~
#include <Ruby/Ruby.h>
~~~

 という行が生成されるらしいのですが、
case-sensitive なファイルシステムではそのファイルパスを見つけることができません。

~~~
#include <ruby/ruby.h>
~~~
と生成されるべきかと思います。

https://github.com/ruby/ruby/blob/3e92b635fb5422207b7bbdc924e292e51e21f040/test/mkmf/test_framework.rb#L24-L33
の have_framework("Ruby") でinclude文が生成されているのかと思われます。


### エラーログ

~~~
$ make test-all -j 8

... snip ...

# Running tests:


Retrying...
[  3/121] TestMkmf::TestHaveFramework#test_multi_frameworks = 0.10 s
  1) Failure:
TestMkmf::TestHaveFramework#test_multi_frameworks [/Users/watson/src/ruby/test/mkmf/test_framework.rb:29]:
have_framework: checking for Ruby... -------------------- no

"clang -o conftest -I. -I/Users/watson/src/ruby/.ext/include/x86_64-darwin16 -I/Users/watson/src/ruby/include -I./test  -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -pipe conftest.c  -L. -L/Users/watson/src/ruby -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/openssl/lib     -lruby.2.5.0-static -framework CoreFoundation  -framework Ruby -lpthread -lgmp -ldl -lobjc "
conftest.c:3:10: fatal error: 'Ruby/Ruby.h' file not found
#include <Ruby/Ruby.h>
         ^
1 error generated.
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: #include <Ruby/Ruby.h>
4:
5: int main(void){return 0;}
/* end */

"clang -o conftest -I. -I/Users/watson/src/ruby/.ext/include/x86_64-darwin16 -I/Users/watson/src/ruby/include -I./test  -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -pipe conftest.c  -L. -L/Users/watson/src/ruby -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/openssl/lib     -lruby.2.5.0-static -framework CoreFoundation -ObjC -framework Ruby -lpthread -lgmp -ldl -lobjc "
conftest.c:3:10: fatal error: 'Ruby/Ruby.h' file not found
#include <Ruby/Ruby.h>
         ^
1 error generated.
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: #include <Ruby/Ruby.h>
4:
5: int main(void){return 0;}
/* end */

--------------------

try as Objective-C

[  4/121] TestMkmf::TestHaveFramework#test_single_framework = 0.10 s
  2) Failure:
TestMkmf::TestHaveFramework#test_single_framework [/Users/watson/src/ruby/test/mkmf/test_framework.rb:25]:
have_framework: checking for Ruby... -------------------- no

"clang -o conftest -I. -I/Users/watson/src/ruby/.ext/include/x86_64-darwin16 -I/Users/watson/src/ruby/include -I./test  -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -pipe conftest.c  -L. -L/Users/watson/src/ruby -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/openssl/lib     -lruby.2.5.0-static -framework CoreFoundation  -framework Ruby -lpthread -lgmp -ldl -lobjc "
conftest.c:3:10: fatal error: 'Ruby/Ruby.h' file not found
#include <Ruby/Ruby.h>
         ^
1 error generated.
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: #include <Ruby/Ruby.h>
4:
5: int main(void){return 0;}
/* end */

"clang -o conftest -I. -I/Users/watson/src/ruby/.ext/include/x86_64-darwin16 -I/Users/watson/src/ruby/include -I./test  -I/usr/local/opt/openssl/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens  -pipe conftest.c  -L. -L/Users/watson/src/ruby -L/usr/local/opt/openssl/lib -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/openssl/lib     -lruby.2.5.0-static -framework CoreFoundation -ObjC -framework Ruby -lpthread -lgmp -ldl -lobjc "
conftest.c:3:10: fatal error: 'Ruby/Ruby.h' file not found
#include <Ruby/Ruby.h>
         ^
1 error generated.
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: #include <Ruby/Ruby.h>
4:
5: int main(void){return 0;}
/* end */

--------------------

try as Objective-C

[ 20/121] TestFileExhaustive#test_expand_path = 0.00 s
  3) Failure:
TestFileExhaustive#test_expand_path [/Users/watson/src/ruby/test/ruby/test_file_exhaustive.rb:750]:
"\uFEFF".
<"/var/folders/fs/gltv6wcd3m70hcgqcp2njt_80000gn/T/rubytest-file20170420-79876-gvlo69/file.test"> expected but was
<"/var/folders/fs/gltv6wcd3m70hcgqcp2njt_80000gn/T/rubytest-file20170420-79876-gvlo69/file.test">.

Finished tests in 223.305106s, 75.8290 tests/s, 9835.1132 assertions/s.
16933 tests, 2196231 assertions, 3 failures, 0 errors, 80 skips

ruby -v: ruby 2.5.0dev (2017-04-20 trunk 58401) [x86_64-darwin16]
make: *** [yes-test-all] Error 3
[trunk][~/src/ruby]$                                                                                                           rbenv:2.4.1
~~~




-- 
https://bugs.ruby-lang.org/

In This Thread

Prev Next