Thanks to Joan, Paul and https://twitter.com/map, I’ve got it working. The 
trick was slightly different ./configure options for SM60:

https://github.com/janl/homebrew-couchdb/blob/master/Formula/spidermonkey60.rb

the --disable-jemalloc and --enable-posix-nspr-emulation options seem to have 
done the trick.

Thanks all!

Best
Jan
—

> On 5. Jan 2020, at 18:01, Jan Lehnardt <j...@apache.org> wrote:
> 
> Hey all,
> 
> I’m trying to get the Mac binary build set up for the 3.0 release.
> 
> The biggest change in that regard is the new SpiderMonkey version.
> 
> To make my life here a little easier, I want to separate the building of 
> SpiderMonkey and CouchDB. To that end, I’ve set up a Homebrew Tap for SM60 
> that I then just depend on being installed when building CouchDB.
> 
> This is my build script for SM60 itself: 
> https://github.com/janl/homebrew-couchdb/blob/master/Formula/spidermonkey60.rb
> 
> It produces a .dylib (think .so, but for a Mac) that looks good from the 
> outside:
> 
>> file /usr/local/lib/libmozjs-60.dylib 
> /usr/local/lib/libmozjs-60.dylib: Mach-O 64-bit dynamically linked shared 
> library x86_64
> 
>> otool -L /usr/local/lib/libmozjs-60.dylib 
> /usr/local/lib/libmozjs-60.dylib:
>       /usr/local/opt/spidermonkey60/lib/libmozjs-60.dylib (compatibility 
> version 1.0.0, current version 1.0.0)
>       /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 
> 228.0.0)
>       
> /System/Library/Frameworks/ExceptionHandling.framework/Versions/A/ExceptionHandling
>  (compatibility version 1.0.0, current version 13.0.0)
>       @executable_path/libmozglue.dylib (compatibility version 1.0.0, current 
> version 1.0.0)
>       /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current 
> version 1252.250.1)
>       /usr/local/opt/icu4c/lib/libicui18n.64.dylib (compatibility version 
> 64.0.0, current version 64.2.0)
>       /usr/local/opt/icu4c/lib/libicuuc.64.dylib (compatibility version 
> 64.0.0, current version 64.2.0)
>       /usr/local/opt/icu4c/lib/libicudata.64.dylib (compatibility version 
> 64.0.0, current version 64.2.0)
>       /usr/local/opt/nspr/lib/libplds4.dylib (compatibility version 1.0.0, 
> current version 1.0.0)
>       /usr/local/opt/nspr/lib/libplc4.dylib (compatibility version 1.0.0, 
> current version 1.0.0)
>       /usr/local/opt/nspr/lib/libnspr4.dylib (compatibility version 1.0.0, 
> current version 1.0.0)
>       /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 
> 1.2.11)
>       /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 
> 400.9.4)
> 
> Now I’m building CouchDB master. I have to add some more options to 
> src/couch/rebar.config.script to make things work:
> 
> @@ -153,7 +158,10 @@ CouchJSEnv = case SMVsn of
>         [
>             {"CXXFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
>             {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
> -        ]
> +        ] ++ case os:type() of
> +                {unix, darwin} -> [{"CC", "clang++"}];
> +                _ -> []
> +            end
> 
> 
> This sets CC to clang++, the native C++ compiler. This might seem odd, 
> normally rebar should pick that up on its own, but it doesn’t. If I don’t do 
> this, I get a number of other errors, where research had convinced me to make 
> this particular change:
> 
> 
> Undefined symbols for architecture x86_64:
>  "std::__1::basic_string<char, std::__1::char_traits<char>, 
> std::__1::allocator<char> >::__init(char const*, unsigned long)", referenced 
> from:
>      std::__1::basic_string<char, std::__1::char_traits<char>, 
> std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*) in 
> util.o
> … (full log https://gist.github.com/janl/05bda5498d1851c13966cbcd20f656f7)
> 
> Now I’m not so sure any more, maybe there is another way to resolve these 
> undefined symbols without introducing the next error.
> 
> With CC=clang++, the compilation step works all fine, but now the linker 
> complains:
> 
> Undefined symbols for architecture x86_64:
>  "_moz_arena_malloc", referenced from:
>      js_malloc(unsigned long) in util.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see 
> invocation)
> ERROR: sh(clang++ priv/couch_js/60/http.o priv/couch_js/60/main.o 
> priv/couch_js/60/utf8.o priv/couch_js/60/util.o -L/usr/local/lib -lmozjs-60 
> -lm -std=c++14 -DHAVE_CURL -lcurl  
> -L"/usr/local/Cellar/erlang/22.2.1/lib/erlang/lib/erl_interface-3.13.1/lib" 
> -lerl_interface -lei -o priv/couchjs)
> failed with return code 1 and the following output:
> Undefined symbols for architecture x86_64:
>  "_moz_arena_malloc", referenced from:
>      js_malloc(unsigned long) in util.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see 
> invocation)
> 
> ERROR: compile failed while processing /Users/jan/Work/couchdb/src/couch: 
> rebar_abort
> make: *** [couch] Error 1
> 
> 
> Which seems a lot more manageable, but I can’t for the life of me figure out 
> what’s wrong here.
> 
> The linker invocation looks fine pointing to /usr/local/lib/libmozjs-60.dylib.
> 
> our util.o indeed uses a JS_alloc() function. Said function is a macro 
> defined in jsapi.h pointing to js/Utility.js’s js_malloc, which in turn uses 
> the _moz_arena_malloc.
> 
> The symbols are all available in the libmozjs-60.dylib:
> 
> nm -gC /usr/local/lib/libmozjs-60.dylib | grep malloc
> 000000000029da8b T JS_malloc(JSContext*, unsigned long)
>                 U _malloc
>                 U _moz_arena_malloc
> 
> The only point of note is that _moz_arena_malloc is a U and JS_malloc a T 
> here. The no-C++ version garbles the JS_malloc symbol, but I’m not sure why 
> that would make _moz_arena_malloc unfindable:
> 
> 
> nm -g /usr/local/lib/libmozjs-60.dylib | grep malloc
> 000000000029da8b T __Z9JS_mallocP9JSContextm
>                 U _malloc
>                 U _moz_arena_malloc
> 
> 
> Inside SM60 moz_arena_malloc is defined in malloc_decls.h which gets included 
> via mozmemory.h and js/Utility.js which all seems cromulent. js_alloc() is an 
> inline function, which is, I think, why we get the _moz_arena_malloc missing 
> reference in our util.h, because we are not calling out to any external 
> functions actually.
> 
> What I’m not sure about now is where to continue digging:
> 
> 1. is my libmozjs-60.dylib somehow not up to snuff exporting all symbols 
> correctly for our C/C++ hybrid?
> 
> 2. is the way we link against the dylib somehow missing options. I’ve 
> experimented with every which combination of -stdlib=libc++ -std=gnu++14 and 
> whatever other settings I could find online, to no avail.
> 
> 3. is my attempt to swap in clang++ as the CC at fault and is there another 
> way to fix the “undefined std::__1::basic_string” errors (note that this 
> route still also has a missing reference for _moz_arena_malloc.
> 
> 
> Either way, http://clang.llvm.org/compatibility.html#inline suggests that if 
> js_malloc() were an `inline` function, that would explain the situation, and 
> a fix would be to mark it `static inline`. Unfortunately it is already a 
> `static inline`.
> 
> Ohey, while writing this, I found that when adding `-lc++` to LDFLAGS, I get 
> rid of the “undefined std::” errors, but the _moz_arena_malloc remains.
> 
> I would imagine that swapping in clang++ as CC automatically links against 
> libc++, which is why we get to the same place via two routes.
> 
> * * *
> 
> Any tips very much appreciated!
> 
> Best
> Jan
> -- 
> Professional Support for Apache CouchDB:
> https://neighbourhood.ie/couchdb-support/
> 

-- 
Professional Support for Apache CouchDB:
https://neighbourhood.ie/couchdb-support/

Reply via email to