2021-09-04 19:45

M1 Macでmoldをビルドする

moldが最近のコミットでmacOS対応されていたので、手元のMacBook Air M1でビルドできるか試してみた。

環境は以下の通り。

❯ sw_vers
ProductName:    macOS
ProductVersion: 11.5.2
BuildVersion:   20G95
❯ clang -v
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: arm64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

以下の手順でいけた。

❯ brew install xxhash openssl cmake
❯ export CPLUS_INCLUDE_PATH=(brew --prefix xxhash)/include:(brew --prefix openssl)/include
❯ export LIBRARY_PATH=(brew --prefix xxhash)/lib:(brew --prefix openssl)/lib
❯ make EXTRA_LDFLAGS="-lcrypto"

以下作業手順。

moldをgit cloneしてディレクトリに移動:

❯ pwd
/Users/okonomi/src/github.com/rui314/mold

makeするとエラー:

❯ make
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/arch-aarch64.o elf/arch-aarch64.cc
In file included from elf/arch-aarch64.cc:1:
elf/mold.h:33:10: fatal error: 'xxh3.h' file not found
#include <xxh3.h>
         ^~~~~~~~
1 error generated.
make: *** [elf/arch-aarch64.o] Error 1

ファイル名でググるとxxHashというライブラリらしい。homebrewにあったのでインストール:

❯ brew install xxhash

環境変数でインクルードパスを追加:

❯ export CPLUS_INCLUDE_PATH=(brew --prefix xxhash)/include

もう一度make:

❯ make
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/arch-aarch64.o elf/arch-aarch64.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/arch-i386.o elf/arch-i386.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/arch-x86-64.o elf/arch-x86-64.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/archive-file.o elf/archive-file.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/cmdline.o elf/cmdline.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/compress.o elf/compress.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/concurrent-map.o elf/concurrent-map.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/filepath.o elf/filepath.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/gc-sections.o elf/gc-sections.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/hyperloglog.o elf/hyperloglog.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/icf.o elf/icf.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/input-sections.o elf/input-sections.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/linker-script.o elf/linker-script.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/main.o elf/main.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/mapfile.o elf/mapfile.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/memory-mapped-file.o elf/memory-mapped-file.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/object-file.o elf/object-file.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/output-chunks.o elf/output-chunks.cc
elf/output-chunks.cc:3:10: fatal error: 'openssl/rand.h' file not found
#include <openssl/rand.h>
         ^~~~~~~~~~~~~~~~
1 error generated.
make: *** [elf/output-chunks.o] Error 1

次はopensslのファイルがない。homebrewでインストール:

❯ brew install openssl

インクルードパスを追加:

❯ export CPLUS_INCLUDE_PATH=(brew --prefix xxhash)/include:(brew --prefix openssl)/include

もう一度make:

❯ make
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/output-chunks.o elf/output-chunks.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/output-file.o elf/output-file.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/passes.o elf/passes.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/perf.o elf/perf.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/relocatable.o elf/relocatable.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/subprocess.o elf/subprocess.cc
elf/subprocess.cc:186:7: warning: 'daemon' is deprecated: first deprecated in macOS 10.5 - Use posix_spawn APIs instead. [-Wdeprecated-declarations]
  if (daemon(1, 0) == -1)
      ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h:292:6: note: 'daemon' has been explicitly marked deprecated here
int      daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0, "Use posix_spawn APIs instead.") __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
         ^
1 warning generated.
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/symbols.o elf/symbols.cc
clang++  -g -pthread -std=c++20 -fPIE -DMOLD_VERSION=\"0.9.4\" -DGIT_HASH=\"b4953951f0f09d163ca3560baf88396bef5c02c5\"  -O2 -Ithird-party/tbb/include  -c -o elf/tar.o elf/tar.cc
mkdir -p out/tbb
(cd out/tbb; cmake -G'Unix Makefiles' -DBUILD_SHARED_LIBS=OFF -DTBB_TEST=OFF -DCMAKE_CXX_FLAGS=-D__TBB_DYNAMIC_LOAD_ENABLED=0 -DTBB_STRICT=OFF ../../third-party/tbb)
/bin/sh: cmake: command not found
make: *** [out/tbb/libs/libtbb.a] Error 127

cmakeコマンドがない。これもhomebrewでインストール:

❯ brew install cmake

make実行:

❯ make
mkdir -p out/tbb
(cd out/tbb; cmake -G'Unix Makefiles' -DBUILD_SHARED_LIBS=OFF -DTBB_TEST=OFF -DCMAKE_CXX_FLAGS=-D__TBB_DYNAMIC_LOAD_ENABLED=0 -DTBB_STRICT=OFF ../../third-party/tbb)
-- The CXX compiler identification is AppleClang 12.0.5.12050022
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning at CMakeLists.txt:109 (message):
  You are building oneTBB as a static library.  This is highly discouraged
  and such configuration is not supported.  Consider building a dynamic
  library to avoid unforeseen issues.


-- CMAKE_BUILD_TYPE is not specified. Using default: RelWithDebInfo
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Checking for one of the modules 'hwloc'
-- TBBBind build target is disabled due to unsupported environment
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/okonomi/src/github.com/rui314/mold/out/tbb
/Library/Developer/CommandLineTools/usr/bin/make -C out/tbb tbb
[  3%] Building CXX object src/tbb/CMakeFiles/tbb.dir/address_waiter.cpp.o
[  6%] Building CXX object src/tbb/CMakeFiles/tbb.dir/allocator.cpp.o
[ 10%] Building CXX object src/tbb/CMakeFiles/tbb.dir/arena.cpp.o
[ 13%] Building CXX object src/tbb/CMakeFiles/tbb.dir/arena_slot.cpp.o
[ 17%] Building CXX object src/tbb/CMakeFiles/tbb.dir/concurrent_bounded_queue.cpp.o
[ 20%] Building CXX object src/tbb/CMakeFiles/tbb.dir/dynamic_link.cpp.o
[ 24%] Building CXX object src/tbb/CMakeFiles/tbb.dir/exception.cpp.o
[ 27%] Building CXX object src/tbb/CMakeFiles/tbb.dir/governor.cpp.o
[ 31%] Building CXX object src/tbb/CMakeFiles/tbb.dir/global_control.cpp.o
[ 34%] Building CXX object src/tbb/CMakeFiles/tbb.dir/itt_notify.cpp.o
[ 37%] Building CXX object src/tbb/CMakeFiles/tbb.dir/main.cpp.o
[ 41%] Building CXX object src/tbb/CMakeFiles/tbb.dir/market.cpp.o
[ 44%] Building CXX object src/tbb/CMakeFiles/tbb.dir/misc.cpp.o
[ 48%] Building CXX object src/tbb/CMakeFiles/tbb.dir/misc_ex.cpp.o
[ 51%] Building CXX object src/tbb/CMakeFiles/tbb.dir/observer_proxy.cpp.o
[ 55%] Building CXX object src/tbb/CMakeFiles/tbb.dir/parallel_pipeline.cpp.o
[ 58%] Building CXX object src/tbb/CMakeFiles/tbb.dir/private_server.cpp.o
[ 62%] Building CXX object src/tbb/CMakeFiles/tbb.dir/profiling.cpp.o
[ 65%] Building CXX object src/tbb/CMakeFiles/tbb.dir/rml_tbb.cpp.o
[ 68%] Building CXX object src/tbb/CMakeFiles/tbb.dir/rtm_mutex.cpp.o
[ 72%] Building CXX object src/tbb/CMakeFiles/tbb.dir/rtm_rw_mutex.cpp.o
[ 75%] Building CXX object src/tbb/CMakeFiles/tbb.dir/semaphore.cpp.o
[ 79%] Building CXX object src/tbb/CMakeFiles/tbb.dir/small_object_pool.cpp.o
[ 82%] Building CXX object src/tbb/CMakeFiles/tbb.dir/task.cpp.o
[ 86%] Building CXX object src/tbb/CMakeFiles/tbb.dir/task_dispatcher.cpp.o
[ 89%] Building CXX object src/tbb/CMakeFiles/tbb.dir/task_group_context.cpp.o
[ 93%] Building CXX object src/tbb/CMakeFiles/tbb.dir/version.cpp.o
[ 96%] Building CXX object src/tbb/CMakeFiles/tbb.dir/queuing_rw_mutex.cpp.o
[100%] Linking CXX static library ../../appleclang_12.0_cxx11_64_relwithdebinfo/libtbb.a
[100%] Built target tbb
(cd out/tbb; ln -sf *_relwithdebinfo libs)
clang++  elf/arch-aarch64.o elf/arch-i386.o elf/arch-x86-64.o elf/archive-file.o elf/cmdline.o elf/compress.o elf/concurrent-map.o elf/filepath.o elf/gc-sections.o elf/hyperloglog.o elf/icf.o elf/input-sections.o elf/linker-script.o elf/main.o elf/mapfile.o elf/memory-mapped-file.o elf/object-file.o elf/output-chunks.o elf/output-file.o elf/passes.o elf/perf.o elf/relocatable.o elf/subprocess.o elf/symbols.o elf/tar.o -o mold -L/opt/homebrew/opt/xxhash/lib  -pthread -lz -lxxhash -ldl -lm out/tbb/libs/libtbb.a
Undefined symbols for architecture arm64:
  "_RAND_bytes", referenced from:
      mold::elf::BuildIdSection<mold::elf::X86_64>::write_buildid(mold::elf::Context<mold::elf::X86_64>&) in output-chunks.o
      mold::elf::BuildIdSection<mold::elf::I386>::write_buildid(mold::elf::Context<mold::elf::I386>&) in output-chunks.o
      mold::elf::BuildIdSection<mold::elf::AARCH64>::write_buildid(mold::elf::Context<mold::elf::AARCH64>&) in output-chunks.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mold] Error 1

コンパイルは通ったみたい。次のリンクの段階でエラー。_RAND_bytesというシンボルが見つからない?
ググるとopensslで定義されてるみたい。ライブラリのパスを通す:


❯ export LIBRARY_PATH=(brew --prefix xxhash)/lib:(brew --prefix openssl)/lib

makeしてもまだエラーが出る:

❯ make
clang++  elf/arch-aarch64.o elf/arch-i386.o elf/arch-x86-64.o elf/archive-file.o elf/cmdline.o elf/compress.o elf/concurrent-map.o elf/filepath.o elf/gc-sections.o elf/hyperloglog.o elf/icf.o elf/input-sections.o elf/linker-script.o elf/main.o elf/mapfile.o elf/memory-mapped-file.o elf/object-file.o elf/output-chunks.o elf/output-file.o elf/passes.o elf/perf.o elf/relocatable.o elf/subprocess.o elf/symbols.o elf/tar.o -o mold  -pthread -lz -lxxhash -ldl -lm out/tbb/libs/libtbb.a
Undefined symbols for architecture arm64:
  "_RAND_bytes", referenced from:
      mold::elf::BuildIdSection<mold::elf::X86_64>::write_buildid(mold::elf::Context<mold::elf::X86_64>&) in output-chunks.o
      mold::elf::BuildIdSection<mold::elf::I386>::write_buildid(mold::elf::Context<mold::elf::I386>&) in output-chunks.o
      mold::elf::BuildIdSection<mold::elf::AARCH64>::write_buildid(mold::elf::Context<mold::elf::AARCH64>&) in output-chunks.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mold] Error 1

clang++の引数を見るとopensslのライブラリが指定されてないみたい。EXTRA_LDFLAGSで追加の引数を渡せるらしい。
❯ make EXTRA_LDFLAGS="-lcrypto"
clang++  elf/arch-aarch64.o elf/arch-i386.o elf/arch-x86-64.o elf/archive-file.o elf/cmdline.o elf/compress.o elf/concurrent-map.o elf/filepath.o elf/gc-sections.o elf/hyperloglog.o elf/icf.o elf/input-sections.o elf/linker-script.o elf/main.o elf/mapfile.o elf/memory-mapped-file.o elf/object-file.o elf/output-chunks.o elf/output-file.o elf/passes.o elf/perf.o elf/relocatable.o elf/subprocess.o elf/symbols.o elf/tar.o -o mold -lcrypto -pthread -lz -lxxhash -ldl -lm out/tbb/libs/libtbb.a
ln -sf mold ld
clang -fPIC -shared -o mold-wrapper.so elf/mold-wrapper.c -ldl

通った!

❯ ./mold -v
mold 0.9.4 (b4953951f0f09d163ca3560baf88396bef5c02c5; compatible with GNU ld and GNU gold)

動いてそう。