sony / flutter-elinux

Flutter tools for embedded Linux (eLinux)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why are we forced to use clang?

andreadaoud opened this issue · comments

Hi,

I'm trying to use this great project to run flutter application based on my buildroot toolchain. In this line:

environment: <String, String>{'CC': 'clang', 'CXX': 'clang++'},

you force the compiler to be clang. I could not get things working from clang if I want to use the linker built from buildroot, getting errors saying crtbegin.o and -lgcc not found.

However, from my testing, gcc will also build a runnable application. I changed this line to use aarch64-buildroot-linux-gnu-gcc (and g++), it worked, and the build result is runnable on target. So, I wonder if there's special reason to force the compiler to be clang, and if not, could we add the compiler name as a command line argument to let the user decide which toolchain to use?

Please share your thoughts, thank you very much!

getting errors saying crtbegin.o and -lgcc not found.

Did you use target-compiler-triple option? Also did you install clang/llvm?

. So, I wonder if there's special reason to force the compiler to be clang, and if not,

Because Flutter basically support only clang/llvm. Some source code will cause build errors with gcc.

could we add the compiler name as a command line argument to let the user decide which toolchain to use?

Technically possible.

getting errors saying crtbegin.o and -lgcc not found.

Did you use target-compiler-triple option? Also did you install clang/llvm?

Yes, the build command is as follows:

~/flutter-elinux/bin/flutter-elinux build elinux --target-arch=arm64 \
                                                   --target-compiler-triple=aarch64-buildroot-linux-gnu \
                                                   --target-sysroot=/home/dev/buildroot/output/staging --target-backend-type=wayland --release \
                                              --system-include-directories=/home/dev/buildroot/output/staging/usr/include

The fail log:

💪 Building with sound null safety 💪

Building an eLinux application with wayland backend in release mode for arm64 target...            ⣷
   541ms
Failed to cmake:
-- The CXX compiler identification is Clang 11.0.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - failed
-- Check for working CXX compiler: /usr/bin/clang++
-- Check for working CXX compiler: /usr/bin/clang++ - broken
-- Configuring incomplete, errors occurred!
See also "/home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeOutput.log".
See also "/home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeError.log".

CMake Error at /usr/share/cmake-3.18/Modules/CMakeTestCXXCompiler.cmake:59 (message):
  The C++ compiler

    "/usr/bin/clang++"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeTmp

    Run Build Command(s):/usr/bin/gmake cmTC_ad829/fast && /usr/bin/gmake  -f CMakeFiles/cmTC_ad829.dir/build.make CMakeFiles/cmTC_ad829.dir/build
    gmake[1]: Entering directory '/home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeTmp'
    Building CXX object CMakeFiles/cmTC_ad829.dir/testCXXCompiler.cxx.o
    /usr/bin/clang++ --target=aarch64-buildroot-linux-gnu    -o CMakeFiles/cmTC_ad829.dir/testCXXCompiler.cxx.o -c
    /home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
    Linking CXX executable cmTC_ad829
    /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_ad829.dir/link.txt --verbose=1
    /usr/bin/clang++ --target=aarch64-buildroot-linux-gnu --sysroot=/home/dev/buildroot/output/staging CMakeFiles/cmTC_ad829.dir/testCXXCompiler.cxx.o -o cmTC_ad829
    /home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld: cannot find crtbegin.o: No such file or directory
    /home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld: cannot find -lgcc
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    gmake[1]: *** [CMakeFiles/cmTC_ad829.dir/build.make:106: cmTC_ad829] Error 1
    gmake[1]: Leaving directory '/home/dev/gui/build/elinux/arm64/release/CMakeFiles/CMakeTmp'
    gmake: *** [Makefile:140: cmTC_ad829/fast] Error 2

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:18 (project)

It uses the host clang, with the buildroot-toolchain gcc as linker. The linker is not specified with corrent option by clang. If I try to run clang standalone:

$ /usr/bin/clang --target=aarch64-buildroot-linux-gnu --sysroot=/home/dev/buildroot/output/staging 1.c -v
Debian clang version 11.0.1-2
Target: aarch64-buildroot-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
 "/usr/lib/llvm-11/bin/clang" -cc1 -triple aarch64-buildroot-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name 1.c -mrelocation-model static -mframe-pointer=non-leaf -fmath-errno -fno-rounding-math -mconstructor-aliases -target-cpu generic -target-feature +neon -target-abi aapcs -fallow-half-arguments-and-returns -fno-split-dwarf-inlining -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm-11/lib/clang/11.0.1 -isysroot /home/dev/buildroot/output/staging -internal-isystem /home/dev/buildroot/output/staging/usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.1/include -internal-externc-isystem /home/dev/buildroot/output/staging/include -internal-externc-isystem /home/dev/buildroot/output/staging/usr/include -fdebug-compilation-dir /home/dev/gui -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fcolor-diagnostics -faddrsig -o /tmp/1-05db34.o -x c 1.c
clang -cc1 version 11.0.1 based upon LLVM 11.0.1 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/home/dev/buildroot/output/staging/usr/local/include"
ignoring nonexistent directory "/home/dev/buildroot/output/staging/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/llvm-11/lib/clang/11.0.1/include
 /home/dev/buildroot/output/staging/usr/include
End of search list.
 "/home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld" --sysroot=/home/dev/buildroot/output/staging -EL --hash-style=both --build-id --eh-frame-hdr -m aarch64linux -dynamic-linker /lib/ld-linux-aarch64.so.1 -o a.out /home/dev/buildroot/output/staging/lib/../lib64/crt1.o /home/dev/buildroot/output/staging/lib/../lib64/crti.o crtbegin.o -L/home/dev/buildroot/output/staging/lib/../lib64 -L/home/dev/buildroot/output/staging/usr/lib/../lib64 -L/home/dev/buildroot/output/staging/lib -L/home/dev/buildroot/output/staging/usr/lib /tmp/1-05db34.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed crtend.o /home/dev/buildroot/output/staging/lib/../lib64/crtn.o
/home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld: cannot find crtbegin.o: No such file or directory
/home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld: cannot find -lgcc
/home/dev/buildroot/output/host/bin/aarch64-buildroot-linux-gnu-ld: cannot find -lgcc
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is basically because the directory where crtbegin.o and libgcc.a resides (/home/dev/buildroot/output/host/lib/gcc/aarch64-buildroot-linux-gnu/10.4.0) is not passed to the linker as an option. The root cause is that clang is not trying to find gcc installation of my cross compile toolchain. If I try to run clang alone without cross compiling, it will try to find gcc installation and get the correct linker option passed (note the Selected GCC installation message):

clang 1.c -v
Debian clang version 11.0.1-2
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
 "/usr/lib/llvm-11/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name 1.c -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm-11/lib/clang/11.0.1 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/dev/gui -ferror-limit 19 -fgnuc-version=4.2.1 -fcolor-diagnostics -faddrsig -o /tmp/1-63b050.o -x c 1.c
clang -cc1 version 11.0.1 based upon LLVM 11.0.1 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/llvm-11/lib/clang/11.0.1/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../.. -L/usr/lib/llvm-11/bin/../lib -L/lib -L/usr/lib /tmp/1-63b050.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/10/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o

The current solution to me, as mentioned above, is to replace clang with my toolchain gcc.

. So, I wonder if there's special reason to force the compiler to be clang, and if not,

Because Flutter basically support only clang/llvm. Some source code will cause build errors with gcc.

OK, I understand. But at least gcc is working fine to me.

could we add the compiler name as a command line argument to let the user decide which toolchain to use?

Technically possible.

Update: after applying #105 , and add the following line to CMakeLists.txt:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --gcc-toolchain=/home/dev/buildroot/output/host")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --gcc-toolchain=/home/dev/buildroot/output/host")

The clang compiler now works.