windows: add clang cross-compile support on Linux

This commit is contained in:
Selim Sandal 2026-02-17 22:17:35 +03:00
parent 278e04ebd6
commit 7a2ea1376e
3 changed files with 108 additions and 14 deletions

View File

@ -113,18 +113,42 @@ function(setup_libftdi_windows)
message(STATUS "Building libftdi for Windows...") message(STATUS "Building libftdi for Windows...")
file(MAKE_DIRECTORY ${LIBFTDI_BUILD_DIR}) file(MAKE_DIRECTORY ${LIBFTDI_BUILD_DIR})
set(LIBFTDI_CMAKE_ARGS
-DCMAKE_SYSTEM_NAME=Windows
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_INSTALL_PREFIX=${CROSS_DEPS_INSTALL_DIR}
-DCMAKE_PREFIX_PATH=${CROSS_DEPS_INSTALL_DIR}
-DLIBUSB_INCLUDE_DIRS=${CROSS_DEPS_INSTALL_DIR}/include/libusb-1.0
-DLIBUSB_LIBRARIES=${CROSS_DEPS_INSTALL_DIR}/lib/libusb-1.0.a
-DFTDIPP=OFF -DBUILD_TESTS=OFF -DDOCUMENTATION=OFF
-DEXAMPLES=OFF -DFTDI_EEPROM=OFF -DPYTHON_BINDINGS=OFF
-DSTATICLIBS=ON
)
if(CMAKE_RC_COMPILER)
list(APPEND LIBFTDI_CMAKE_ARGS -DCMAKE_RC_COMPILER=${CMAKE_RC_COMPILER})
endif()
foreach(_lang C CXX RC)
if(DEFINED CMAKE_${_lang}_COMPILER_TARGET AND NOT "${CMAKE_${_lang}_COMPILER_TARGET}" STREQUAL "")
list(APPEND LIBFTDI_CMAKE_ARGS "-DCMAKE_${_lang}_COMPILER_TARGET=${CMAKE_${_lang}_COMPILER_TARGET}")
endif()
endforeach()
foreach(_flags_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
if(DEFINED ${_flags_var} AND NOT "${${_flags_var}}" STREQUAL "")
list(APPEND LIBFTDI_CMAKE_ARGS "-D${_flags_var}=${${_flags_var}}")
endif()
endforeach()
if(DEFINED CMAKE_SYSROOT AND NOT "${CMAKE_SYSROOT}" STREQUAL "")
list(APPEND LIBFTDI_CMAKE_ARGS -DCMAKE_SYSROOT=${CMAKE_SYSROOT})
endif()
execute_process( execute_process(
COMMAND ${CMAKE_COMMAND} COMMAND ${CMAKE_COMMAND}
-DCMAKE_SYSTEM_NAME=Windows ${LIBFTDI_CMAKE_ARGS}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_INSTALL_PREFIX=${CROSS_DEPS_INSTALL_DIR}
-DCMAKE_PREFIX_PATH=${CROSS_DEPS_INSTALL_DIR}
-DLIBUSB_INCLUDE_DIRS=${CROSS_DEPS_INSTALL_DIR}/include/libusb-1.0
-DLIBUSB_LIBRARIES=${CROSS_DEPS_INSTALL_DIR}/lib/libusb-1.0.a
-DFTDIPP=OFF -DBUILD_TESTS=OFF -DDOCUMENTATION=OFF
-DEXAMPLES=OFF -DFTDI_EEPROM=OFF -DPYTHON_BINDINGS=OFF
-DSTATICLIBS=ON
${LIBFTDI_SRC_DIR} ${LIBFTDI_SRC_DIR}
WORKING_DIRECTORY ${LIBFTDI_BUILD_DIR} WORKING_DIRECTORY ${LIBFTDI_BUILD_DIR}
RESULT_VARIABLE CONFIG_RESULT RESULT_VARIABLE CONFIG_RESULT

View File

@ -0,0 +1,52 @@
# CMake Toolchain file for cross-compiling to Windows x64 using Clang + MinGW-w64
# Usage: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-x86_64-w64-mingw32-clang.cmake ..
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(WINDOWS_TARGET_TRIPLE "x86_64-w64-mingw32")
find_program(CMAKE_C_COMPILER NAMES clang)
find_program(CMAKE_CXX_COMPILER NAMES clang++)
find_program(CMAKE_RC_COMPILER NAMES llvm-rc x86_64-w64-mingw32-windres)
if(NOT CMAKE_C_COMPILER OR NOT CMAKE_CXX_COMPILER)
message(FATAL_ERROR "clang/clang++ not found. Please install clang.")
endif()
set(CMAKE_C_COMPILER_TARGET ${WINDOWS_TARGET_TRIPLE})
set(CMAKE_CXX_COMPILER_TARGET ${WINDOWS_TARGET_TRIPLE})
if(CMAKE_RC_COMPILER AND CMAKE_RC_COMPILER MATCHES "llvm-rc$")
set(CMAKE_RC_COMPILER_TARGET ${WINDOWS_TARGET_TRIPLE})
endif()
# Keep target selection compatible with older CMake versions.
set(CMAKE_C_FLAGS_INIT "--target=${WINDOWS_TARGET_TRIPLE}")
set(CMAKE_CXX_FLAGS_INIT "--target=${WINDOWS_TARGET_TRIPLE}")
option(CROSS_COMPILE_DEPS "Download and build Windows dependencies for cross-compilation" ON)
set(CROSS_DEPS_DIR "${CMAKE_BINARY_DIR}/cross-deps" CACHE PATH "Directory for cross-compiled dependencies")
if(EXISTS "/usr/x86_64-w64-mingw32/sys-root/mingw")
set(MINGW_SYSROOT "/usr/x86_64-w64-mingw32/sys-root/mingw")
elseif(EXISTS "/usr/x86_64-w64-mingw32")
set(MINGW_SYSROOT "/usr/x86_64-w64-mingw32")
else()
set(MINGW_SYSROOT "")
endif()
set(CMAKE_FIND_ROOT_PATH ${CROSS_DEPS_DIR} ${MINGW_SYSROOT})
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)
set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -static-libgcc -static-libstdc++")
set(ENABLE_UDEV OFF CACHE BOOL "" FORCE)
set(ENABLE_LIBGPIOD OFF CACHE BOOL "" FORCE)
set(ENABLE_REMOTEBITBANG OFF CACHE BOOL "" FORCE)
set(ENABLE_XILINX_VIRTUAL_CABLE OFF CACHE BOOL "" FORCE)
set(BUILD_STATIC ON CACHE BOOL "" FORCE)

View File

@ -206,9 +206,9 @@ openFPGALoader can be installed via MSYS2:
Cross-compilation from Linux Cross-compilation from Linux
---------------------------- ----------------------------
openFPGALoader can be cross-compiled for Windows from Linux using MinGW-w64. openFPGALoader can be cross-compiled for Windows from Linux using MinGW-w64
The build system will automatically download and build the required dependencies toolchains (GCC or Clang). The build system will automatically download and
(libusb, libftdi). build the required dependencies (libusb, libftdi).
**Prerequisites (Debian/Ubuntu):** **Prerequisites (Debian/Ubuntu):**
@ -217,6 +217,8 @@ The build system will automatically download and build the required dependencies
sudo apt install \ sudo apt install \
mingw-w64 \ mingw-w64 \
libz-mingw-w64-dev \ libz-mingw-w64-dev \
clang \
lld \
cmake \ cmake \
pkg-config \ pkg-config \
p7zip-full p7zip-full
@ -230,11 +232,13 @@ The build system will automatically download and build the required dependencies
mingw64-gcc-c++ \ mingw64-gcc-c++ \
mingw64-zlib \ mingw64-zlib \
mingw64-zlib-static \ mingw64-zlib-static \
clang \
lld \
cmake \ cmake \
p7zip \ p7zip \
p7zip-plugins p7zip-plugins
**Build:** **Build (shared steps):**
.. code-block:: bash .. code-block:: bash
@ -242,9 +246,21 @@ The build system will automatically download and build the required dependencies
cd openFPGALoader cd openFPGALoader
mkdir build-win64 mkdir build-win64
cd build-win64 cd build-win64
**Configure + build with GCC (MinGW-w64):**
.. code-block:: bash
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-x86_64-w64-mingw32.cmake .. cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-x86_64-w64-mingw32.cmake ..
cmake --build . --parallel cmake --build . --parallel
**Configure + build with Clang (MinGW-w64 target):**
.. code-block:: bash
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-x86_64-w64-mingw32-clang.cmake ..
cmake --build . --parallel
The resulting ``openFPGALoader.exe`` will be a statically-linked executable The resulting ``openFPGALoader.exe`` will be a statically-linked executable
that only depends on standard Windows system DLLs (KERNEL32, msvcrt, WS2_32). that only depends on standard Windows system DLLs (KERNEL32, msvcrt, WS2_32).
@ -260,6 +276,8 @@ that only depends on standard Windows system DLLs (KERNEL32, msvcrt, WS2_32).
.. code-block:: bash .. code-block:: bash
x86_64-w64-mingw32-strip openFPGALoader.exe x86_64-w64-mingw32-strip openFPGALoader.exe
# or
llvm-strip openFPGALoader.exe
**Cross-compilation options:** **Cross-compilation options:**