slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
16.18k stars 536 forks source link

C++ binaries incompatible with MinGW #5052

Open ikocs opened 3 months ago

ikocs commented 3 months ago

Hello!

I wanted to get acquainted with Slint with the slint-cpp-template example. I tried to build a project using MinGW. I installed it using msys. However, I received an error when building:

====================[ Build | my_application | Debug-MinGW GCC ]================
C:\Users\Elf\AppData\Local\Programs\CLion\bin\cmake\win\x64\bin\cmake.exe --build F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc --target my_application -j 10
[1/3] Generating appwindow.h
[2/3] Building CXX object CMakeFiles/my_application.dir/src/main.cpp.obj
FAILED: CMakeFiles/my_application.dir/src/main.cpp.obj 
C:\msys64\mingw64\bin\g++.exe  -IF:/tests/slint-cpp-template/cmake-build-debug-mingw-gcc -isystem "C:/Program Files/Slint-cpp 1.5.1/include/slint" -g -std=gnu++20 -fdiagnostics-color=always /bigobj -MD -MT CMakeFiles/my_application.dir/src/main.cpp.obj -MF CMakeFiles\my_application.dir\src\main.cpp.obj.d -o CMakeFiles/my_application.dir/src/main.cpp.obj -c F:/tests/slint-cpp-template/src/main.cpp
g++.exe: warning: /bigobj: linker input file unused because linking not done
g++.exe: error: /bigobj: linker input file not found: No such file or directory
ninja: build stopped: subcommand failed.

After that I changed the compiler to MSVC. In this case, the build went without problems and the test application launched. I would like to understand why the example did not work with GCC.

This is probably important too. The CMAke console also displays a warning related to /bigobj:

C:\Users\Elf\AppData\Local\Programs\CLion\bin\cmake\win\x64\bin\cmake.exe -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=C:/Users/Elf/AppData/Local/Programs/CLion/bin/ninja/win/x64/ninja.exe -DCMAKE_C_COMPILER=C:/msys64/mingw64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/msys64/mingw64/bin/g++.exe -G Ninja -S F:\tests\slint-cpp-template -B F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc
-- Configuring done (0.1s)
-- Generating done (0.0s)
-- Build files have been written to: F:/tests/slint-cpp-template/cmake-build-debug-mingw-gcc

Problems were encountered while collecting compiler information:
    cc1plus.exe: fatal error: /bigobj: No such file or directory

[Finished]
tronical commented 3 months ago

We add /bigobj to the link line only if CMake believes that it's building with MSVC. How did you invoke cmake when this failed?

ikocs commented 3 months ago

We add /bigobj to the link line only if CMake believes that it's building with MSVC. How did you invoke cmake when this failed?

I use clion for build project. But as I understand it, the following command was executed:

====================[ Build | my_application | Debug-MinGW GCC ]================
C:\Users\Elf\AppData\Local\Programs\CLion\bin\cmake\win\x64\bin\cmake.exe --build F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc --target my_application -j 10

I tried using the system CMAKE. The result is the same. Path to cmake IDE changes:

====================[ Build | my_application | Debug-MinGW GCC ]================
"C:\Program Files\CMake\bin\cmake.exe" --build F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc --target my_application -j 10
[1/3] Generating appwindow.h
[2/3] Building CXX object CMakeFiles/my_application.dir/src/main.cpp.obj
FAILED: CMakeFiles/my_application.dir/src/main.cpp.obj 
C:\msys64\mingw64\bin\g++.exe  -IF:/tests/slint-cpp-template/cmake-build-debug-mingw-gcc -isystem "C:/Program Files/Slint-cpp 1.5.1/include/slint" -g -std=gnu++20 -fdiagnostics-color=always /bigobj -MD -MT CMakeFiles/my_application.dir/src/main.cpp.obj -MF CMakeFiles\my_application.dir\src\main.cpp.obj.d -o CMakeFiles/my_application.dir/src/main.cpp.obj -c F:/tests/slint-cpp-template/src/main.cpp
g++.exe: warning: /bigobj: linker input file unused because linking not done
g++.exe: error: /bigobj: linker input file not found: No such file or directory
ninja: build stopped: subcommand failed.
tronical commented 3 months ago

Hm, could it be that your build directory was initially configured for MSVC?

If you remove F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc entirely once and then re-build (re-configure), does the problem still exist?

ikocs commented 3 months ago

Two more possibly important points:

  1. I installed Slint from .exe for Win11.
  2. My CMakeLists.txt looks like this:
    
    cmake_minimum_required(VERSION 3.21)
    project(my_application LANGUAGES CXX)

set(CMAKE_PREFIX_PATH "C:/Program Files/Slint-cpp 1.5.1")

find_package(Slint QUIET)

if (NOT Slint_FOUND) message("Slint could not be located in the CMake module search path. Downloading it from Git and building it locally") 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) endif (NOT Slint_FOUND)

add_executable(my_application src/main.cpp) target_link_libraries(my_application PRIVATE Slint::Slint) slint_target_sources(my_application ui/appwindow.slint)

On Windows, copy the Slint DLL next to the application binary so that it's found.

if (WIN32) add_custom_command(TARGET my_application POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ $ COMMAND_EXPAND_LISTS) endif()


3. First start CMake:
> Hm, could it be that your build directory was initially configured for MSVC?
> 
> If you remove `F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc` entirely once and then re-build (re-configure), does the problem still exist?
```bash
"C:\Program Files\CMake\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=C:/Users/Elf/AppData/Local/Programs/CLion/bin/ninja/win/x64/ninja.exe -DCMAKE_C_COMPILER=C:/msys64/mingw64/bin/gcc.exe -DCMAKE_CXX_COMPILER=C:/msys64/mingw64/bin/g++.exe -G Ninja -S F:\tests\slint-cpp-template -B F:\tests\slint-cpp-template\cmake-build-debug-mingw-gcc
-- The CXX compiler identification is GNU 13.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.5s)
-- Generating done (0.0s)
CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_C_COMPILER

-- Build files have been written to: F:/tests/slint-cpp-template/cmake-build-debug-mingw-gcc

Problems were encountered while collecting compiler information:
    cc1plus.exe: fatal error: /bigobj: No such file or directory

[Finished]

The compiler is detected correctly. Then the problem repeated during the assembly stage.

ikocs commented 3 months ago

I found the following piece of code in the file "C:\Program Files\Slint-cpp 1.5.1\lib\cmake\Slint\SlintTargets.cmake":

# Create imported target Slint::Slint
add_library(Slint::Slint INTERFACE IMPORTED)

set_target_properties(Slint::Slint PROPERTIES
  INTERFACE_COMPILE_FEATURES "cxx_std_20"
  INTERFACE_COMPILE_OPTIONS "/bigobj"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/slint"
  INTERFACE_LINK_LIBRARIES "Slint::slint-cpp"
)

Could this be causing the problem? I don't know cmake very well, unfortunately(

ogoffart commented 3 months ago

The problem is that our binaries are built for the msvc target, and they are incompatible with mingw.

This /bigobj flag is probably only the tip of the iceberg of incompatibilities.

@tronical: Should we perhaps build both msvc and mingw binaries and have two packages? Or would it be possible to merge the two in a single package?

tronical commented 3 months ago

Right. I suspect that a unified binary package might be possible - but it would require stitching two independent builds together. I think for now the best course of action is to rename our binary package to have a -MSVC suffix and add a -MinGW package separately.