Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-compiler support #87

Open
melshuber opened this issue Oct 10, 2019 · 4 comments
Open

Cross-compiler support #87

melshuber opened this issue Oct 10, 2019 · 4 comments

Comments

@melshuber
Copy link

Hi,

I'd like to use Rust QT bindings for an embedded target. The build host is an x86, the target is an aarch64 architecture. However I can't figure out how to cross compile the qt bindings crate.

I suppose it has something to with the c_lib part which is part of each crate generated by ritual.
From my build logs I see that the host compiler instead of the target is used for c_lib. I think this is because cmake does not get setup for cross-compiling during this build step.

Further, it might be necessecary to re-generate my own crates to match the qt-version used on the cross target and not the host (https://github.com/rust-qt/ritual#generating-qt-crates).

What is the preferred way to select the sysroot/cross toolchain in ritual?

By the way, I am using buildroot.

The missing include file (see log below) is present int the sysroot of the target (but not on the host).

Thanks for your help

$> PATH="<path-to-dev-dir>/devel/build/br2/host/bin:<path-to-dev-dir>/devel/build/br2/host/sbin:<path-to-home>/.cargo/bin:<path-to-home>/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" \
SYSROOT=<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot \
PKG_CONFIG_ALLOW_CROSS=1 \
CARGO_HOME=<path-to-dev-dir>/devel/build/br2/host/share/cargo \
cargo build --release --target=aarch64-unknown-linux-gnu --manifest-path=<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/Cargo.toml --verbose -j1

[...]

error: failed to run custom build command for `qt_gui v0.3.0`

Caused by:
  process didn't exit successfully: `<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/release/build/qt_gui-2731c6cc43cc56ed/build-script-build` (exit code: 1)
--- stdout
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- 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/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done

[...]

-- RITUAL_âINCLUDE_PATH=<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5;<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux\
-gnu/sysroot/usr/include/qt5/QtGui;<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore
-- RITUAL_LIBRARY_PATH=<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/lib
-- RITUAL_LIBRARY_TYPE=STATIC
-- RITUAL_LINKED_LIBS=Qt5Gui;Qt5Core
-- RITUAL_CPP_LIB_VERSION=51202
-- RITUAL_COMPILER_FLAGS=-std=gnu++11 -fPIC
-- Configuring done
-- Generating done
-- Build files have been written to: <path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/aarch64-unknown-linux-gnu/release/build/qt_gui-15ef8cd72196cd53/out/c_lib_build
/usr/bin/make -f CMakeFiles/Makefile2 clean

[...]

/usr/bin/c++  -DQT_GUI_C_LIBRARY -DQT_NO_VERSION_TAGGING -DRITUAL_CPP_LIB_VERSION=51202 -I<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/aarch64-unknown-linux-gnu/releas
e/build/qt_gui-15ef8cd72196cd53/out/c_lib_build/sized_types_autogen/include -I<path-to-dev-dir>/devel/build/br2/host/share/cargo/registry/src/github.com-1ecc6299db9ec823/qt_gui-0.3.0/c_lib
 -I<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/aarch64-unknown-linux-gnu/release/build/qt_gui-15ef8cd72196cd53/out/c_lib_build -I<path-to-dev-dir>/devel/bu
ild/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5 -I<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui -I<path-to-home>/cherry
/cobra/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtCore  -Wall -Wextra -Wno-deprecated-declarations -Werror=return-type -std=gnu++11 -fPIC -O3 -DNDEBUG   -o CMakeFiles/
sized_types.dir/sized_types.cxx.o -c <path-to-dev-dir>/devel/build/br2/host/share/cargo/registry/src/github.com-1ecc6299db9ec823/qt_gui-0.3.0/c_lib/sized_types.cxx
make[2]: Leaving directory '<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/aarch64-unknown-linux-gnu/release/build/qt_gui-15ef8cd72196cd53/out/c_lib_build'
make[1]: Leaving directory '<path-to-dev-dir>/devel/build/br2/build/qt-examples-custom/target/aarch64-unknown-linux-gnu/release/build/qt_gui-15ef8cd72196cd53/out/c_lib_build'
--- stderr
In file included from <path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui/QtGui:45,
                 from <path-to-dev-dir>/devel/build/br2/host/share/cargo/registry/src/github.com-1ecc6299db9ec823/qt_gui-0.3.0/c_lib/sized_types.cxx:1:
<path-to-dev-dir>/devel/build/br2/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/qt5/QtGui/qopengl.h:105:13: fatal error: GLES3/gl32.h: No such file or directory
 #   include <GLES3/gl32.h>
             ^~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/sized_types.dir/build.make:66: CMakeFiles/sized_types.dir/sized_types.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:71: CMakeFiles/sized_types.dir/all] Error 2
make: *** [Makefile:133: all] Error 2
Error:
   command failed with exit code: 2: "cmake" "--build" "." "--" "-j1" "install"
@Riateche
Copy link
Member

Hi,

Ritual doesn't currently support any kind of cross-compilation. It seems that you need to configure the cmake project properly to do a cross-compilation of the c_lib glue library. I didn't try that, but google says you should pass -DCMAKE_TOOLCHAIN_FILE=... option to cmake and make sure your toolchain file specifies the compilers correctly.

There is no option to do this through ritual's API, but you can hack around it. The relevant code executed by the build script is here. You can clone the repository and add your cmake variable (CMAKE_TOOLCHAIN_FILE) to the actual_cmake_vars vector. Then, tell cargo to use the patched version of ritual_common by specifying the local path to it in the Cargo.toml file of your project:

[patch.crates-io.ritual_common]
path = "..."

If this turns out to be working, we'll make a more convenient way to pass this variable.

Further, it might be necessecary to re-generate my own crates to match the qt-version used on the cross target and not the host

The generated crates are able to use various Qt versions, as long as they are not too old (currently, 5.9 is the oldest supported version). Hopefully you'll be able to use the published crates.

The compiler error indicates that Qt tries to use GLES (GL for Embedded Systems) which is not available on desktops. This is correct, and the error should be fixed when cross-compilation is properly configured for c_lib.

@melshuber
Copy link
Author

Look as very valuable input to me, I will try this on the weekend.

@melshuber
Copy link
Author

melshuber commented Oct 13, 2019

Hi,

after adopting your suggestion into ritual_common, I managed to build a cross c_lib (aarch64 in my case).

However, the executable sized_types is also included in the same CMakelists.txt, therefore I get a cross compiled version of this binary as well and the build fails when executing the file.

--- stderr
Error:
 failed to run command: "<path-to-dev-dir>/examples/target/aarch64-unknown-linux-gnu/debug/build/qt_core-d0b4448b3452fb09/out/c_lib_install/sized_types"
   Exec format error (os error 8)

I also checked sized_types.cxx in the cargo registry. It looks like, those are only c++ files with an empty main() that include Qt header.

Whats up with this binary and why are the executing?
Where is the rule that executes it?

thx

@Riateche
Copy link
Member

sized_types is a mechanism to request size and alignment of stack-allocated types on the current platform. Stack-allocated types turned out to be problematic in multiple ways, so they are turned off now. That's why the main() function is empty. It's not decided yet if we remove the functionality completely or leave it as an opt-in mechanism for bindings developers.

The build script calls this binary here. You can patch ritual_build to remove the get_command_output call, but create_file should be kept so that the crate still compiles.

The proper fix for that issue would be either not to call sized_types if it's empty or simply remove the feature entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants