How to install llvm@13 with Homerew on macOS High Sierra 10.13.6? Got "Built target lldELF" error
Asked Answered
T

2

16

Although High Sierra is no longer supported by Homebrew, but I need to install llvm@13 formula as a dependency for other formulas. So I tried to install it this way:

$ brew install llvm
...
==> Downloading https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.0/llvm-project-13.0.0.src.tar.xz
Already downloaded: /Users/username/Library/Caches/Homebrew/downloads/8fd68fc8f968137c5080826db6e58682326235960fd8469363eb27d0799978ca--llvm-project-13.0.0.src.tar.xz
...
==> Installing llvm
==> cmake -G Unix Makefiles .. -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld;lldb;mlir;polly -DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind;openmp -DLLVM_POLLY_L
==> cmake --build .
...
[ 79%] Built target lldELF
make: *** [all] Error 2

An error is occurred after a long time of compilation. I also found this error in ~/Library/Logs/Homebrew/llvm/02.cmake:

/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm:246:52: error: use of undeclared identifier 'CPU_SUBTYPE_ARM64E'
    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
                                                   ^
1 error generated.
make[2]: *** [tools/lldb/source/Host/macosx/objcxx/CMakeFiles/lldbHostMacOSXObjCXX.dir/HostInfoMacOSX.mm.o] Error 1
make[1]: *** [tools/lldb/source/Host/macosx/objcxx/CMakeFiles/lldbHostMacOSXObjCXX.dir/all] Error 2

How can I fix that compilation error?

Tepee answered 9/11, 2021 at 22:53 Comment(0)
T
22

Install llvm with debug mode enabled:

$ brew install --debug llvm

Installation process encounters with the same error mentioned in the question, but some options are provided to fix the issue. Choose option 5:

 - raise
 - ignore
 - backtrace
 - irb
 - shell
Choose an action: 5

It gives a shell access to the current build directory of llvm formula. Find the current folder:

$ pwd
/private/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src

Change the location to the build directory:

cd llvm/build

Edit the HostInfoMacOSX.mm and remove the second part of condition:

vi ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

You need to change the line 246 from:

    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {

to:

    if (cputype == CPU_TYPE_ARM64) {

Then re-run the last command:

$ cmake --build .

It takes some time to be completed:

...
[100%] Linking CXX executable ../../../../bin/lldb-vscode
cd /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/tools/lldb/tools/lldb-vscode && /usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_link_script CMakeFiles/lldb-v
scode.dir/link.txt --verbose=1
/usr/local/Homebrew/Library/Homebrew/shims/mac/super/clang++  -stdlib=libc++ -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wn
o-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-c
lass-memaccess -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wno-deprecated-declarations -Wno-unkn
own-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -O3 -DNDEBUG -Wl,-search_paths_first -Wl,-headerpad_max_install_names  -stdlib=libc++ -Wl,-sectcreate,__
TEXT,__info_plist,/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/tools/lldb/tools/lldb-vscode/lldb-vscode-Info.plist  -Wl,-dead_strip CMakeFiles/lldb-vscode.dir/
lldb-vscode.cpp.o CMakeFiles/lldb-vscode.dir/BreakpointBase.cpp.o CMakeFiles/lldb-vscode.dir/ExceptionBreakpoint.cpp.o CMakeFiles/lldb-vscode.dir/FifoFiles.cpp.o CMakeFiles/lldb-vsc
ode.dir/FunctionBreakpoint.cpp.o CMakeFiles/lldb-vscode.dir/IOStream.cpp.o CMakeFiles/lldb-vscode.dir/JSONUtils.cpp.o CMakeFiles/lldb-vscode.dir/LLDBUtils.cpp.o CMakeFiles/lldb-vsco
de.dir/OutputRedirector.cpp.o CMakeFiles/lldb-vscode.dir/ProgressEvent.cpp.o CMakeFiles/lldb-vscode.dir/RunInTerminal.cpp.o CMakeFiles/lldb-vscode.dir/SourceBreakpoint.cpp.o CMakeFi
les/lldb-vscode.dir/VSCode.cpp.o -o ../../../../bin/lldb-vscode  -Wl,-rpath,@loader_path/../lib ../../../../lib/liblldb.13.0.0.dylib -lpthread ../../../../lib/libclang-cpp.dylib ../
../../../lib/libLLVM.dylib
[100%] Built target lldb-vscode
/usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_progress_start /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/CMakeFiles 0

Then run the install command:

$ cmake --build . --target install

The tail of the result should be:

...
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./CheckAtomic.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./TableGen.cmake

Execute the last command:

$ cmake --build . --target install-xcode-toolchain

The tail of the results should be:

...
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./CheckAtomic.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./TableGen.cmake
Built target install-xcode-toolchain
/usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_progress_start /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/CMakeFiles 0

Then press control+d to return to debug menu. Because the two last commands were run manually, you need to ignore the rest of errors by choosing the option 2:

 - raise
 - ignore
 - backtrace
 - irb
 - shell
Choose an action: 2
==> cmake --build . --target install
...
cmake
--build
.
--target
install

Error: could not load cache
BuildError: Failed executing: cmake --build . --target install
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2
==> cmake --build . --target install-xcode-toolchain
...

cmake
--build
.
--target
install-xcode-toolchain

Error: could not load cache

BuildError: Failed executing: cmake --build . --target install-xcode-toolchain
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2

It will continue to install to the rest:

==> Fixing /usr/local/Cellar/llvm/13.0.0_1/bin/FileCheck permissions from 755 to 555
==> Fixing /usr/local/Cellar/llvm/13.0.0_1/bin/analyze-build permissions from 755 to 555
...
==> Changing dylib ID of /usr/local/Cellar/llvm/13.0.0_1/lib/libunwind.1.0.dylib
  from @rpath/libunwind.1.dylib
    to /usr/local/opt/llvm/lib/libunwind.1.dylib
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FromPathLoader): loading /usr/local/opt/llvm/.brew/llvm.rb
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
  LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"

llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have llvm first in your PATH, run:
  echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc

For compilers to find llvm you may need to set:
  export LDFLAGS="-L/usr/local/opt/llvm/lib"
  export CPPFLAGS="-I/usr/local/opt/llvm/include"

==> Summary
🍺  /usr/local/Cellar/llvm/13.0.0_1: 10,907 files, 1.8GB, built in 1418 minutes 39 seconds

It can be verified this way, the default llvm@10 pre-installed:

$ /usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

And the new Homebrew version of llvm@13:

$ /usr/local/opt/llvm/bin/clang --version
Homebrew clang version 13.0.0
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
Tepee answered 9/11, 2021 at 22:53 Comment(13)
Isn't the first option 5 (shell) instead of 2 (ignore)? – Syndetic
@Syndetic You're right. It should be the shell option. I fixed it. – Tepee
This was helpful -- I was able to take a short cut by making the suggested edit to the file in the temp build dir before the build process got that far, so there was no error and no need to invoke the debug shell. It just carried straight on with the build. – Erectile
Thanks @HamidRohani - I never would have figured this out! Hey, I think you may have missed one step... Before invoking cmake --build . I had to first run cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On. Thanks! – Psychometrics
@Psychometrics what does this cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On. do? I tried it before this cmake --build . --target install-xcode-toolchain. – Clemente
ty, for providing a detailed answer with this. i too am experimenting with installing llvm@13 on a macos high sierra box. i have homebrew tap that i use for experiments and created a patch for llvm loosely based on what you provided in your answer. i'm testing my formula now. do you mind taking a look at my patch file and seeing if it would work to build llvm. i attempted to fill in the missing define statement as opposed removing it from the logical AND as you suggested. github.com/ipatch/homebrew-us-05/blob/dev/patches/… – Halfhour
bash-3.2$ cmake --build . --target install-xcode-toolchain gmake: *** No rule to make target 'install-xcode-toolchain'. Stop. I found it was turned off in llvm.rb, -DLLVM_CREATE_XCODE_TOOLCHAIN=OFF – Chatman
I needed to also execute 'brew install libintl' in the original shell to prevent a linker error at the end. The active debug shell will not pick this up, so best to do it before all the other commands or you'll have to start over again. – Frostwork
If cmake still fails then you might also want to switch from command line tools: sudo xcode-select --reset It fixes the *** No rule to make target 'install-xcode-toolchain' error. – Feudal
thank you for this! A shortcut to avoid dropping into a shell: after running brew install ... is : wait for 5 minutes so that the build-dir is setup and all files are written by brew. Then cd to the build dir cd /private/tmp/llvm* and edit the culprit file lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm as per the instructions above. It takes ages to compile that file so you have plenty of time to fix it before the compiler hits on it and dies. In this way you avoid all the cmake install... from the shell. – Nondisjunction
@ipatch: I don't think your patch is correct. The CPU_SUBTYPE_* macros are not in the same value space as the CPU_TYPE_* macros. See @Dr_Ogi's answer for the correct value of the CPU_SUBTYPE_ARM64E macro. – Stadiometer
I just tried that but got an error while exiting with CTRL+D. Is there any way to re-enter the debug menu after that, without Homebrew untaring and recompiling everything again? – Footpoundal
I ended up redoing everything and putting in "cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On" as suggested by @dr-ogi above. I also ran "exit 0" this time instead of CTRL + D (the issue was that the last time I was missing the XCode Toolchain hence the final command before exiting had a non-zero exit code, crashing the debug shell) – Footpoundal
P
7

@HamidRohani provides a great solution for those still tinkering in High Sierra (10.13). Getting a recent version of LLVM to compile on my old MAC with an older XCode (clang version 10.0.1 in my case) was a great help. My nominal contribution...

Alternatively, you could define the symbol after line 41 in HostInfoMacOSX.mm:

// Kludge: Symbol definition extracted from a modern machine.h
#ifndef CPU_SUBTYPE_ARM64E
#    define CPU_SUBTYPE_ARM64E        ((cpu_subtype_t) 2)
#endif

Now, there's no need to modify line 246. And the definition would resolve any (possible) subsequent references. And let me aggregate the steps shown above conducted in brew's debug-shell:

cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On
cmake --build .
cmake --build . --target install
cmake --build . --target install-xcode-toolchain

Regarding the LLVM-related variable, setting LLVM_CREATE_XCODE_TOOLCHAIN to On directs CMake to generate a target named 'install-xcode-toolchain'. 1 The target is a work-around to System Integrity Protection (SIP); "Xcode toolchains are a mostly-undocumented feature that allows multiple copies of low level tools to be installed to different locations, and users can easily switch between them." 2

Brew's Caveats Brew gives you few caveats necessary to use the new compiler: "because macOS already provides this software and installing another version in parallel can cause all kinds of trouble." To use your new compiler, "You need to have llvm first in your PATH and for compilers to find llvm you may need to set" LDFLAGS and CDFLAGS. But since these gems-of-wisdom appear near the end of a million-lines of output, let me re-iterate here:

export PATH="/usr/local/opt/llvm/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"

Setting PATH is straight forward. I however, didn't need to set LDFLAGS or CPPFLAGS. Further, no joy with this additional caveat, "To use the bundled libc++ please add the following LDFLAGS":

export LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"

Anyway, moving on... To demonstrate that all's good, a C++ foo program that incorporates <filesystem>; a library not in High Sierra:

#include <iostream>

// C++17: Modern C++ compiler has std filesystem                                                                                            
#include <filesystem>
namespace fs = std::filesystem;
typedef std::filesystem::path my_path;

using namespace std;
int main ()
{
  fs::path path{"/tmp"};
  path /= "foo.txt";

  ofstream ofs(path);
  ofs << "Hello World." << endl;
  ofs.close();

  return 0;
}

Clearly, a nonsensical program, But to compile:

unset CPPFLAGS
unset LDFLAGS
clang++ -std=c++17  -L/usr/local/opt/llvm/lib  foo.cpp -o foo

Again, showing That I didn't need CPPFLAGS and LDFLAGS. And so, The executable links to the correct libc++ library:

MacIntel:c++fs mjo$ otool -L foo
foo:
    /usr/local/opt/llvm/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)

Enjoy.

Pendergast answered 22/5, 2022 at 1:8 Comment(1)
I appreciate everyone's work on this build issue. Is there any reason this method should not work for 10.14.6, Mojave? – Dnieper

© 2022 - 2024 β€” McMap. All rights reserved.