Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • CMake CMake
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 4,106
    • Issues 4,106
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 15
    • Merge requests 15
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CMakeCMake
  • CMakeCMake
  • Issues
  • #22953
Closed
Open
Issue created Nov 26, 2021 by Yiting Wang@yiting16

cross compilation fails due to no "-rpath-link" linker flag generated by cmake

Use attached test case, and the following reproduce steps:

  1. download a cross-compile toolchain, for example, an aarch64 toolchain from here
  2. extract the toolchain to a directory and rename the directory name to aarch64-linux, for example, /tmp/aarch64-linux
  3. export CROSS_COMPILE=/tmp/aarch64-linux/bin/aarch64-linux-
  4. extract the test case, for example, to /tmp/cross_compile-link
  5. cd /tmp/cross_compile-link && ./test.sh
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /tmp/aarch64-linux/bin/aarch64-linux-gcc
-- Check for working C compiler: /tmp/aarch64-linux/bin/aarch64-linux-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /tmp/aarch64-linux/bin/aarch64-linux-g++
-- Check for working CXX compiler: /tmp/aarch64-linux/bin/aarch64-linux-g++ -- 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: /tmp/cross_compile-link/build
Scanning dependencies of target foo
[ 16%] Building C object CMakeFiles/foo.dir/foo.c.o
[ 33%] Linking C shared library libfoo/libfoo.so
[ 33%] Built target foo
Scanning dependencies of target bar
[ 50%] Building C object CMakeFiles/bar.dir/bar.c.o
[ 66%] Linking C shared library libbar/libbar.so
[ 66%] Built target bar
Scanning dependencies of target main
[ 83%] Building C object CMakeFiles/main.dir/main.c.o
[100%] Linking C executable main
/tmp/aarch64-linux/bin/../lib/gcc/aarch64-buildroot-linux-gnu/9.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: warning: libfoo.so, needed by libbar/libbar.so, not found (try using -rpath or -rpath-link)
/tmp/aarch64-linux/bin/../lib/gcc/aarch64-buildroot-linux-gnu/9.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: libbar/libbar.so: undefined reference to `foo'
collect2: error: ld returned 1 exit status
CMakeFiles/main.dir/build.make:95: recipe for target 'main' failed
make[2]: *** [main] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed
make[1]: *** [CMakeFiles/main.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

Check the linker command for "main":

> cat build/CMakeFiles/main.dir/link.txt
/tmp/aarch64-linux/bin/aarch64-linux-gcc   -rdynamic CMakeFiles/main.dir/main.c.o  -o main -Wl,-rpath,/tmp/cross_compile-link/build/libbar libbar/libbar.so

The warning says (try using -rpath or -rpath-link), but manually add "-Wl,-rpath,/tmp/cross_compile-link/build/libfoo" does not work:

> /tmp/aarch64-linux/bin/aarch64-linux-gcc   -rdynamic CMakeFiles/main.dir/main.c.o  -o main -Wl,-rpath,/tmp/cross_compile-link/build/libbar  -Wl,-rpath,/tmp/cross_compile-link/build/libfoo libbar/libbar.so
/tmp/aarch64-linux/bin/../lib/gcc/aarch64-buildroot-linux-gnu/9.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: warning: libfoo.so, needed by libbar/libbar.so, not found (try using -rpath or -rpath-link)
/tmp/aarch64-linux/bin/../lib/gcc/aarch64-buildroot-linux-gnu/9.3.0/../../../../aarch64-buildroot-linux-gnu/bin/ld: libbar/libbar.so: undefined reference to `foo'
collect2: error: ld returned 1 exit status

Adding "-Wl,-rpath-link,/tmp/cross_compile-link/build/libfoo" works.

> /tmp/aarch64-linux/bin/aarch64-linux-gcc -rdynamic CMakeFiles/main.dir/main.c.o -o main -Wl,-rpath,/tmp/cross_compile-link/build/libbar -Wl,-rpath-link,/tmp/cross_compile-link/build/libfoo libbar/libbar.so

But if I do a native build with the same test case, it succeeded:

  1. export CROSS_COMPILE=
  2. cd /tmp/cross_compile-link && ./test.sh
> ./test.sh
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/g++
-- Check for working CXX compiler: /usr/bin/g++ -- 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: /tmp/cross_compile-link/build
Scanning dependencies of target foo
[ 16%] Building C object CMakeFiles/foo.dir/foo.c.o
[ 33%] Linking C shared library libfoo/libfoo.so
[ 33%] Built target foo
Scanning dependencies of target bar
[ 50%] Building C object CMakeFiles/bar.dir/bar.c.o
[ 66%] Linking C shared library libbar/libbar.so
[ 66%] Built target bar
Scanning dependencies of target main
[ 83%] Building C object CMakeFiles/main.dir/main.c.o
[100%] Linking C executable main
[100%] Built target main

I googled on the internet and found the following 2 issues reported before seem to be similar to what I see:

  • https://cmake.org/pipermail/cmake/2015-August/061433.html
  • https://cmake.org/pipermail/cmake-developers/2018-July/030746.html

I found a workaround is to change the libbar dependency to libfoo from PRIVATE to PUBLIC, and the cross-compilation will succeed.

target_link_libraries(bar
    PUBLIC foo
)
> ./test.sh
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /tmp/aarch64-linux/bin/aarch64-linux-gcc
-- Check for working C compiler: /tmp/aarch64-linux/bin/aarch64-linux-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /tmp/aarch64-linux/bin/aarch64-linux-g++
-- Check for working CXX compiler: /tmp/aarch64-linux/bin/aarch64-linux-g++ -- 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: /tmp/cross_compile-link/build
Scanning dependencies of target foo
[ 16%] Building C object CMakeFiles/foo.dir/foo.c.o
[ 33%] Linking C shared library libfoo/libfoo.so
[ 33%] Built target foo
Scanning dependencies of target bar
[ 50%] Building C object CMakeFiles/bar.dir/bar.c.o
[ 66%] Linking C shared library libbar/libbar.so
[ 66%] Built target bar
Scanning dependencies of target main
[ 83%] Building C object CMakeFiles/main.dir/main.c.o
[100%] Linking C executable main
[100%] Built target main
> file build/main
build/main: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 4.9.0, not stripped
Edited Nov 26, 2021 by Yiting Wang
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking