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

Error cross-compiling with C++ from Linux to Windows #2508

Closed
GuillaumeSavin opened this issue Apr 8, 2023 · 11 comments · Fixed by #4363
Closed

Error cross-compiling with C++ from Linux to Windows #2508

GuillaumeSavin opened this issue Apr 8, 2023 · 11 comments · Fixed by #4363
Assignees
Labels
a:language-c++ C++ API, codegen, CMake build system (mS,mO) bug Something isn't working upstream Needs a fix upstream

Comments

@GuillaumeSavin
Copy link

Hello Slint team,

Today i try to cross compile (i built on linux targetting windows) a program using slint ui and built in the same time slint compiler (https://slint-ui.com/releases/1.0.0/docs/cpp/cmake.html#building-from-sources).
But during the step cmake --build ., My theory is that cmake think that slint compiler should be a windows binary as well as the program I try to build. But as I built on linux, slint compiler is built as linux binary so when copying the slint-compiler, cmake use the wrong extension:

Copying byproducts slint-compiler.exe to /app/build/_deps/slint-build
Error copying file (if different) from "/app/build/./cargo/build/x86_64-unknown-linux-gnu/debug/slint-compiler.exe" to "/app/build/_deps/slint-build".

Here is the list of command i executed in /app/build:

cmake -DRust_CARGO_TARGET=x86_64-pc-windows-gnu ../src
cmake --build .

I will send you the files i used during the process in attachment
slint_hello.zip
And my files is located as in the capture
slint directory

Thanks you in advance !

@tronical tronical self-assigned this Apr 11, 2023
@tronical
Copy link
Member

Hi Guilllaume! I suspect that this may be related to Corrosion, how it invokes cargo/rustc, and whether it's aware of the cross-compilation situation. Are you using a cmake toolchain file by chance with your cmake build? Or how do you instruct CMake to use a cross-compiler for C++ code to compile for windows?

A quick search on Google suggests that setting CMAKE_SYSTEM_NAME may be relevant, in order for CMake to set CMAKE_CROSSCOMPILING, which in turn is a variable that corrosion uses. (based on https://www.taricorp.net/2021/cmake-windows-cross/ that has an example command line)

Could you describe your setup a little, maybe I can reproduce this issue myself.

@GuillaumeSavin
Copy link
Author

GuillaumeSavin commented Apr 11, 2023

Here are some info about the host :

  • Host : Debian GNU/Linux 11 (bullseye) x86_64,
  • Target : Windows x86_64
  • (cross-)compiler : gcc version 10-win32 20210110 (GCC) -> target x86_64-w64-mingw32 (target triplet for windows using mingw-w64-gcc)
  • rustc : 1.68.2
  • cmake : 3.26.3

rust info:

Default host: x86_64-unknown-linux-gnu
rustup home: /root/.rustup

installed targets for active toolchain:

  • x86_64-pc-windows-gnu
  • x86_64-unknown-linux-gnu

active toolchain:

  • stable-x86_64-unknown-linux-gnu (default)
  • rustc 1.68.2 (9eb3afe9e 2023-03-27)

My folders architecture:

/app contains two folders (src and build)
src contains three files CMakeLists.txt, slint_hello.cpp and slint_hello_ui.slint (you can find them in this archive slint_hello.zip)
build is empty before configure and build using cmake commands


Commands used

I execute theses commands in this order (in build folder):

  • cmake -DRust_CARGO_TARGET=x86_64-pc-windows-gnu ../src
  • cmake --build .

CMakeLists.txt:

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

cmake_minimum_required(VERSION 3.21)
project(slint_hello LANGUAGES CXX)


include(FetchContent)
FetchContent_Declare(
    Slint
    GIT_REPOSITORY https://github.com/slint-ui/slint.git
    # `release/1` will auto-upgrade to the latest Slint >= 1.0.0 and < 2.0.0
    # `release/1.0` will auto-upgrade to the latest Slint >= 1.0.0 and < 1.1.0
    GIT_TAG release/1
    SOURCE_SUBDIR api/cpp
)
FetchContent_MakeAvailable(Slint)

add_executable(slint_hello slint_hello.cpp)
slint_target_sources(slint_hello slint_hello_ui.slint)
target_link_libraries(slint_hello PRIVATE Slint::Slint)
# On Windows, copy the Slint DLL next to the application binary so that it's found.
if (WIN32)
    add_custom_command(TARGET slint_hello POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:slint_hello> $<TARGET_FILE_DIR:slint_hello> COMMAND_EXPAND_LISTS)
endif()

slint_hello.cpp

#include "slint_hello_ui.h"

int main(int argc, char **argv)
{
    auto hello_world = HelloWorld::create();
    hello_world->set_my_label("Hello from C++");
    // Show the window and spin the event loop until the window is closed.
    hello_world->run();
    return 0;
}

slint_hello_ui.slint:

export component HelloWorld inherits Window {
    width: 400px;
    height: 400px;

    // Declare an alias that exposes the label's text property to C++
    property my_label <=> label.text;

    label := Text {
       y: parent.width / 2;
       x: parent.x + 200px;
       text: "Hello, world";
       color: blue;
    }
}

The context, i use debian to compile a windows program (cross-compilation).
Like the tutorial said, we can build slint from source (the library) in the same time that the program that will use it
The problem is, during the build of slint, cmake think that slint-compiler should be a windows executable (but i think and corrosion as well that the library should be host based not target based so debian can use the command to finally built the program, surely i am mistaken about this part...).

Thanks in advance for your help !

@GuillaumeSavin
Copy link
Author

Hello @tronical , do you need any more info or do you want me to try something ?

@GuillaumeSavin
Copy link
Author

GuillaumeSavin commented May 9, 2023

I try to add set(CMAKE_CROSSCOMPILING true) but it don't change the result the system host name let cmake know we are cross compiling it seems. Do you succeed to reproduce the same problem @tronical ?

@tronical
Copy link
Member

tronical commented May 9, 2023

Thanks for the info (and thanks for your patience:). The cmake project looks good to me. So not entirely sure what's causing this. @jschwe , do you know if this kind of cross-build from Linux host to mingw should work with Corrosion?

@jschwe
Copy link
Contributor

jschwe commented May 9, 2023

@tronical The corrosion hostbuild option is not as well tested as I'd like and this is probably one of the issues I'm aware of, and isn't easy to fix. The main problem here is that the hostbuild option is a target property, and is thus only really known at build time. But we have to tell CMake already at configure time what the filenames of our artifacts are (so that they can be copied to the output directory).
We could probably also solve this again with the delayed function call mechanism which delays the execution of the relevant CMake function until the end of the CMake file, but it's not exactly a quick fix to do.

@tronical
Copy link
Member

Thanks for the quick response. I see, this is why cross-compilation between linux host and target works - almost by chance, because there's no such difference (executable suffix).

@tronical
Copy link
Member

@GuillaumeSavin I'm afraid the consequence is that currently cross-compiling the C++ build of Slint from Linux to Windows isn't supported :-(

@GuillaumeSavin
Copy link
Author

@tronical @jschwe No problem, I can hardly imagine how difficult it can be to manage cross compilation when some tools don't let enough control to do as we want. Thanks anyway for your time !

@tronical tronical changed the title Error during cross-compilation including the build of slint compiler (C++ integration) Error cross-compiling with C++ from Linux to Windows May 17, 2023
@ogoffart ogoffart added the a:language-c++ C++ API, codegen, CMake build system (mS,mO) label Jun 28, 2023
@ogoffart
Copy link
Member

corrosion-rs/corrosion#437 fixes the other way around (windows to non-windows)
But the condition in https://github.com/corrosion-rs/corrosion/blob/8d8ff67e506cdee4a69123f3bea31b0465a48fe2/cmake/Corrosion.cmake#L81 doesn't cover the target windows but host not windows.

@ogoffart ogoffart added bug Something isn't working upstream Needs a fix upstream labels Jan 16, 2024
tronical added a commit that referenced this issue Jan 17, 2024
tronical added a commit that referenced this issue Jan 17, 2024
@GuillaumeSavin
Copy link
Author

I just tested it with slint 1.9.1 and I confirm it works ! @tronical @jschwe @ogoffart thanks you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:language-c++ C++ API, codegen, CMake build system (mS,mO) bug Something isn't working upstream Needs a fix upstream
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants