AdaCore / gnat-llvm

LLVM based GNAT compiler
179 stars 18 forks source link

Some problems on M1 Mac #35

Closed simonjwright closed 11 months ago

simonjwright commented 11 months ago

This is on an M1 Mac running GCC 13.1.0 built for aarch64-apple-darwin and Homebrew (llvm 16.0.6), with GCC sources at commit 92f2ec4 of Wed Aug 23 11:25:20 2023 +0800 and GNAT-LLVM at f97227c of 22 Aug 2023.

The problems are probably (my opinion) just Mac ones, not related to the machine architecture.

The first problem is that the compilation of llvm_wrapper.cc fails:

/opt/gcc-13.1.0-aarch64/bin/g++ -c -x c++ -g -I/opt/homebrew/Cellar/llvm/16.0.6/include -std=c++17 -stdlib=libc++ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MMD -MF llvm_wrapper.d -specs=/private/var/folders/_q/fvnxz46903z9hjh38fz0lyhm0000gs/T/GNAT-TEMP-000004.TMP /Volumes/Miscellaneous3/gnat-llvm/llvm-interface/llvm_wrapper.cc
g++: error: unrecognized command-line option '-stdlib=libc++'

   compilation of llvm_wrapper.cc failed

Looking at Options Controlling C++ Dialect, under --stdlib=libstdc++,libc++ it says "When G++ is configured to support this option ..." -- can you say how? (GNAT CE 2020 doesn't support it).

I worked round this by

diff --git a/llvm-interface/gnat_llvm_c.gpr b/llvm-interface/gnat_llvm_c.gpr
index 412f9c50..e5c5545e 100644
--- a/llvm-interface/gnat_llvm_c.gpr
+++ b/llvm-interface/gnat_llvm_c.gpr
@@ -14,7 +14,7 @@ project GNAT_LLVM_C is
          when "llvm" =>
             for Driver ("C++") use "g++";
          when others =>
-            null;
+            for Driver ("C++") use "clang++";
       end case;

       case Build is

which gave rise to this

/opt/homebrew/opt/llvm/bin/clang++ -c -x c++ -g -I/opt/homebrew/Cellar/llvm/16.0.6/include -std=c++17 -stdlib=libc++ -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MMD -MF llvm_wrapper.d -specs=/private/var/folders/_q/fvnxz46903z9hjh38fz0lyhm0000gs/T/GNAT-TEMP-000004.TMP /Volumes/Miscellaneous3/gnat-llvm/llvm-interface/llvm_wrapper.cc
clang-16: warning: argument unused during compilation: '-specs=/private/var/folders/_q/fvnxz46903z9hjh38fz0lyhm0000gs/T/GNAT-TEMP-000004.TMP' [-Wunused-command-line-argument]

but otherwise seemed OK.


The second problem is that the link of llvm-gnat1 failed with a lot of missing symbols, starting

Undefined symbols for architecture arm64:
  "__ZNKSt3__110error_code7messageEv", referenced from:
      __ZNK5clang6SrcMgr12ContentCache15getBufferOrNoneERNS_17DiagnosticsEngineERNS_11FileManagerENS_14SourceLocationE in libclangBasic.a(SourceManager.cpp.o)
  "__ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4findEcm", referenced from:
      __ZNK5clang7targets17HexagonTargetInfo16getTargetDefinesERKNS_11LangOptionsERNS_12MacroBuilderE in libclangBasic.a(Hexagon.cpp.o)
      __ZNK5clang7targets17HexagonTargetInfo14initFeatureMapERN4llvm9StringMapIbNS2_15MallocAllocatorEEERNS_17DiagnosticsEngineENS2_9StringRefERKNSt3__16vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSF_ISH_EEEE in libclangBasic.a(Hexagon.cpp.o)
...

traceable to the remarks here,

To use the bundled libc++ please add the following LDFLAGS: LDFLAGS="-L$HOMEBREW_PREFIX/opt/llvm/lib/c++ -Wl,-rpath,$HOMEBREW_PREFIX/opt/llvm/lib/c++"

You also need to actually say -lc++! so, this patch:

diff --git a/llvm-interface/Makefile b/llvm-interface/Makefile
index d4306951..0d973b37 100644
--- a/llvm-interface/Makefile
+++ b/llvm-interface/Makefile
@@ -36,6 +36,8 @@ LDFLAGS=$(shell $(LLVM_CONFIG) --libs all --ldflags --system-libs)
 CXXFLAGS=
 ALL_CXXFLAGS=$(shell $(LLVM_CONFIG) --cxxflags) $(CXXFLAGS) $(CLANG_CXXFLAGS)

+LDFLAGS += -L$(HOMEBREW_PREFIX)/opt/llvm/lib/c++ -Wl,-rpath,$(HOMEBREW_PREFIX)/opt/llvm/lib/c++ -lc++
+
 ifeq ($(OS),Windows_NT)
   LN_S=cp -p
   LDFLAGS+=-Wl,--stack=0x2000000
@@ -128,7 +130,7 @@ LD_PATH=$(shell dirname $(shell gcc --print-prog-name=cc1))
 LIBSTDCXX_PATH=$(CXX_PREFIX)/lib64
 BOOT_DIRS=obj obj-tools bin lib

-stage1:
+stage1:
        $(MAKE) GPRBUILD="gprbuild -v -gnatwns" build-opt gnatlib-automated
        $(RMDIR) stage1
        $(MKDIR) stage1

works (I also tried with just LDFLAGS += -lc++, builds OK; uses the system libc++ rather than Homebrew's).


The fourth problem arose while building a program:

$ gprbuild -P try_lldb --target=llvm
Bind
   [gprbind]      try_lldb.bexch
   [Ada]          try_lldb.ali
Link
   [link]         try_lldb.adb
clang: error: unsupported option '-static-libgcc'
gprbuild: link of try_lldb.adb failed
gprbuild: failed command was: /Volumes/Miscellaneous3/gnat-llvm/llvm-interface/bin/llvm-gcc try_lldb.o b__try_lldb.o -L/Users/simon/tmp/ -L/Users/simon/tmp/ -L/Volumes/Miscellaneous3/gnat-llvm/llvm-interface//lib/rts-native/adalib/ -static-libgcc /Volumes/Miscellaneous3/gnat-llvm/llvm-interface//lib/rts-native/adalib/libgnat.a -o try_lldb

Worked round this problem by putting this in the GPR:

   package Linker is
      for Driver use "g++";
   end Linker;

but now we get ..


.. the fifth problem, to do with ghost-only packages:

$ gprbuild -P try_lldb --target=llvm
Bind
   [gprbind]      try_lldb.bexch
   [Ada]          try_lldb.ali
Link
   [link]         try_lldb.adb
ld: in /Volumes/Miscellaneous3/gnat-llvm/llvm-interface//lib/rts-native/adalib/libgnat.a(a-nbnbig.o),
archive member 'a-nbnbig.o' with length 0 is not mach-o or llvm bitcode
file '/Volumes/Miscellaneous3/gnat-llvm/llvm-interface//lib/rts-native/adalib/libgnat.a' for architecture arm64
collect2: error: ld returned 1 exit status
gprbuild: link of try_lldb.adb failed

(this may be the Darwin linker being stricter than others, of course)

The zero-length objects are

./a-nbnbig.o
./s-vaispe.o
./s-valspe.o
./s-vauspe.o
./s-vs_int.o
./s-vs_lli.o
./s-vs_llu.o
./s-vs_uns.o
./s-vsllli.o
./s-vslllu.o

Sorry for the multiple issues in one report, I thought that raising separate issues might be unhelpful.

ArnaudCharlet commented 11 months ago

Thanks for the report. All the issues but the last ones look more like setup issues which can be solved by setting your PATH to find the right tools first, or by specifying Makefile variables when launching make to accomodate for darwin specific issues. So let's keep this issue for the last item. Unfortunately it will likely require someone with access to mac M1 and gnat llvm to investigate, which isn't the case for the GNAT LLVM main developers. You might want to look at the generated LLVM bit code as well as the generate assembly. However it looks like potentially a pure LLVM issue, in which case, outside the scope of GNAT LLVM.