oknm.jp

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で追加の引数を渡せるらしい。

参考: https://github.com/rui314/mold/blob/main/build-static.sh#L27

❯ 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)

動いてそう。