SNSystems / llvm-project-prepo

Fork of LLVM with modifications to support a program repository
26 stars 0 forks source link

Cannot use CMake with a compiler built with the default triple using -repo #162

Closed paulhuggett closed 2 years ago

paulhuggett commented 3 years ago

Running cmake to create the build for a project when using a compiler built so that it defaults to repo output will currently fail. I’m trying to build libunwind for distribution, but this doesn’t currently work. Changing the compiler’s default triple involves setting the LLVM_DEFAULT_TARGET_TRIPLE variable to x86_64-pc-linux-gnu-repo before building it.

Once you’ve got a suitable compiler, here is the sequence of commands that shows the problem. Adjust the three variables ($ROOT, $BUILD, and $OUT) to suit your setup.

#!/bin/bash
# Let's see the commands as they are executed.
set -o xtrace
# Directory containing a checkout of llvm-project-prepo.
ROOT=$HOME/prepo

# Directory containing llvm-project-prepo tools built with 
# LLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-gnu-repo
BUILD=$ROOT/build_linux/bin

# Directory in which we will build libunwind.
OUT=/tmp/libunwind

# Prepare the libunwind build directory.
rm -r $OUT
mkdir -p $OUT

# Write repo.json to tell the wrap utility where the tools are found.
cat > $OUT/repo.json <<END
{
  "ar"      : "/usr/bin/ar",
  "link"    : "$BUILD/clang",
  "link++"  : "$BUILD/clang++",
  "repo2obj": "$BUILD/repo2obj"
}
END

# Run cmake to create the libunwind build.
REPOFILE=$OUT/cmake.db cmake                              \
  -S $ROOT/libunwind                                       \
  -B $OUT                                                  \
  -D CMAKE_BUILD_TYPE=Debug                                \
  -D CMAKE_CXX_COMPILER=$BUILD/clang++                     \
  -D CMAKE_C_COMPILER=$BUILD/clang                         \
  -D CMAKE_TOOLCHAIN_FILE=$ROOT/llvm/utils/repo/repo.cmake \
  -D LIBUNWIND_ENABLE_SHARED=No                            \
  -D LIBUNWIND_ENABLE_STATIC=Yes                           \
  -D LLVM_ENABLE_UNWIND_TABLES=No                          \
  -D LLVM_PATH=$ROOT/llvm                                  \
  -D musl=No                                               \
  -D musl_install=/tmp/muslinstall                         \
  -D utils_dir=$ROOT/llvm/utils/repo

A couple of things to note:

When running CMake, you’ll see output that includes messages such as:

-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
[snip]
-- Linker detection: GNU ld
CMake Error at /home/paul/prepo/llvm/cmake/modules/CheckCompilerVersion.cmake:56 (if):
  if given arguments:

    "(" "STREQUAL" "MSVC" ")" "AND" "(" "19.24" "VERSION_LESS_EQUAL" ")" "AND" "(" "VERSION_LESS" "19.25" ")"

  Unknown arguments specified
Call Stack (most recent call first):
  /home/paul/prepo/llvm/cmake/modules/HandleLLVMOptions.cmake:9 (include)
  CMakeLists.txt:80 (include)

-- Configuring incomplete, errors occurred!
See also "/tmp/libunwind/CMakeFiles/CMakeOutput.log".
See also "/tmp/libunwind/CMakeFiles/CMakeError.log".

The error from CheckCompilerVersion.cmake is caused by the CMAKE_CXX_COMPILER_ID variable being empty. This is in turn a result of CMake being unable to identify the compilers, as evidenced by the message “The C compiler identification is unknown”.

Why is CMake unable to identify the C and C++ compilers?

paulhuggett commented 3 years ago

Instrumenting the CMake module CMakeDetermineCompilerId.cmake

The function CMAKE_DETERMINE_COMPILER_ID_BUILD() builds the compiler ID source code and looks for output files.

We can see that the compiler is run several times. Most of these runs fail for one reason or another, but two succeed:

-- spawn: /home/paul/prepo/build_linux/bin/clang  ;-fno-exceptions;-fno-rtti;-fno-unwind-tables   CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang  ;-fno-exceptions;-fno-rtti;-fno-unwind-tables -c  CMakeCCompilerId.c
-- compilation succeeded
-- compiler produced: CMakeCCompilerId.o
-- spawn: /home/paul/prepo/build_linux/bin/clang  ;-fno-exceptions;-fno-rtti;-fno-unwind-tables -Aa  CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang  ;-fno-exceptions;-fno-rtti;-fno-unwind-tables -D__CLASSIC_C__  CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang  ;-fno-exceptions;-fno-rtti;-fno-unwind-tables --target=arm-arm-none-eabi;-mcpu=cortex-m3  CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang     CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang   -c  CMakeCCompilerId.c
-- compilation succeeded
-- compiler produced: CMakeCCompilerId.o
-- spawn: /home/paul/prepo/build_linux/bin/clang   -Aa  CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang   -D__CLASSIC_C__  CMakeCCompilerId.c
-- spawn: /home/paul/prepo/build_linux/bin/clang   --target=arm-arm-none-eabi;-mcpu=cortex-m3  CMakeCCompilerId.c

CMAKE_DETERMINE_COMPILER_ID_CHECK() examines the file(s) produced by the compiler. To do this it uses the file(STRINGS…) command to extract ASCII strings from the file.

Here is our problem.

The two builds that succeed above are those that simply compile to produce a ticket file. Unlike a traditional object file, this file does not contain any of the compiler’s actual output but is instead a link (a “ticket”) used to retrieve it from the database. This database is not necessarily created by this one compilation: it’s likely to be present when the compiler was run.

paulhuggett commented 3 years ago

The solution is probably found in PR#158 (“Add Repo toolchain support for the musl-repo target in the clang Driver”).

The first test compile that CMake performs should result in an executable from the linker. Even in the repo model, this is a traditional executable and will contain the complete output from the compiler.

paulhuggett commented 3 years ago

FTR, I’ve removed the “default triple” docker image pending a fix to this bug.

MaggieYingYi commented 2 years ago

The solution is probably found in PR#158 (“Add Repo toolchain support for the musl-repo target in the clang Driver”).

The PR#158 (“Add Repo toolchain support for the musl-repo target in the clang Driver”) has been merged back to the master branch.

I tried to generate the solution for the llvm-project (clang;compiler-rt;libcxx;libcxxabi) using cmake:

Command line: cmake -G Ninja -DCMAKE_C_COMPILER=repo-clang -DCMAKE_CXX_COMPILER=repo-clang++ -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-musl-repo -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_VERSION_SUFFIX= -DLLVM_BUILD_RUNTIME=ON -DLLVM_LIT_ARGS=--verbose --no-progress-bar -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=ON -DLLVM_ENABLE_PROJECTS=" "clang;compiler-rt;libcxx;libcxxabi;" ../llvm

Please note: repo-clang and repo-clang++ are repo compilers which are used on my Linux machine.

The cmake generated the ninja solution successfully.

If I generated solution for libunwind project, I got the following cmake error:

  Compiler doesn't support generation of unwind tables if exception support
  is disabled.  Building libunwind DSO with runtime dependency on C++ ABI
  library is not supported.

I think this error makes sense since repo compiler hasn't support EH yet.

In summary, the PR#158 solved this bug.

paulhuggett commented 2 years ago

Hi Maggie,

Can I quickly double check that your “repo-clang” compiler was built to default to the musl-repo triple and that it isn’t using the wrap tools during the cmake stage?

Paul

On 26 Jan 2022, at 13:38, MaggieYingYi @.***> wrote:

 The solution is probably found in PR#158 (“Add Repo toolchain support for the musl-repo target in the clang Driver”).

The PR#158 (“Add Repo toolchain support for the musl-repo target in the clang Driver”) has been merged back to the master branch.

I tried to generate the solution for the llvm-project (clang;compiler-rt;libcxx;libcxxabi) using cmake:

Command line: cmake -G Ninja -DCMAKE_C_COMPILER=repo-clang -DCMAKE_CXX_COMPILER=repo-clang++ -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-musl-repo -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_VERSION_SUFFIX= -DLLVM_BUILD_RUNTIME=ON -DLLVM_LIT_ARGS=--verbose --no-progress-bar -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=ON -DLLVM_ENABLE_PROJECTS=" "clang;compiler-rt;libcxx;libcxxabi;" ../llvm Please note: repo-clang and repo-clang++ are repo compilers which are used on my Linux machine.

The cmake generated the ninja solution successfully.

If I generated solution for libunwind project, I got the following cmake error:

Compiler doesn't support generation of unwind tables if exception support is disabled. Building libunwind DSO with runtime dependency on C++ ABI library is not supported. I think this error makes sense since repo compiler hasn't support EH yet.

In summary, the PR#158 solved this bug.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were assigned.

MaggieYingYi commented 2 years ago

Hi Paul,

I tried to build the repo-clang/repo-clang++ with default to the musl-repo triple.

I tested using a simple example and the upstream llvm project.

For a simple example, the cmake works fine.

Run the following commands:

  1. check repo-clang version.

    $ repo-clang --version
    clang version 11.0.0 (https://github.com/SNSystems/llvm-project-prepo.git 4b09eb0faf6607f15be8c5d296e2d7834f3f73fc)
    Target: x86_64-pc-linux-musl-repo
    Thread model: posix
    InstalledDir: /usr/bin
  2. cp stdlib to the my home folder:

    $ cd /home/maggie
    $ cp /usr/local/llvm/lib/stdlib.repo clang.db
  3. Set the REPOFILE to this clang.db $ export REPOFILE=/home/maggie/clang.db

  4. Run the cmake for a simple example

    $ cd  ~/simple-project/build
    $ cmake -G Ninja -DCMAKE_C_COMPILER=repo-clang -DCMAKE_CXX_COMPILER=repo-clang++ ../
    -- The CXX compiler identification is Clang 11.0.0
    -- Check for working CXX compiler: /usr/bin/repo-clang++
    -- Check for working CXX compiler: /usr/bin/repo-clang++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/maggie/github/modern-cmake/examples/simple-project/build

For the upstream llvm project, we got a missing libatomic issue shown below:

  1. Run cmake for the upstream llvm-project.
    $ cmake -G Ninja -DCMAKE_C_COMPILER=repo-clang -DCMAKE_CXX_COMPILER=repo-clang++ -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_VERSION_SUFFIX= -DLLVM_BUILD_RUNTIME=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_TESTS=ON -DLLVM_ENABLE_PROJECTS="clang;compiler-rt;libcxx;libcxxabi;" ../llvm
    :   
    CMake Error at cmake/modules/CheckAtomic.cmake:59 (message):
    Host compiler appears to require libatomic, but cannot find it.
    Call Stack (most recent call first):
    cmake/config-ix.cmake:377 (include)
    CMakeLists.txt:727 (include)
    :

As you suggested, we probably need to open a bug for porting libatomic on Repo.

I will create a new issue for porting the libatomic on Repo.

Thanks,