简体   繁体   中英

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

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?

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

Followed @Thruston shortcut and it worked for me. Thank you for the most detailed answer I have ever seen that fixed my exact problem. Great job. Signed up just to say thanks but I cant upvote or put this in a comment for Hamid's answer that worked so sorry for where this comment ends up.

@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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM