From 1ecd19336f4bb1a70381ba29b5c7109134d61d55 Mon Sep 17 00:00:00 2001 From: Nulano Date: Tue, 12 Dec 2023 20:22:29 +0100 Subject: [PATCH] cross-complie fribidi for windows arm64 --- .github/workflows/wheels.yml | 7 +---- winbuild/build_prepare.py | 31 +++++++++++--------- winbuild/fribidi.cmake | 56 ++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 76d42b470..5c73a5273 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -116,10 +116,7 @@ jobs: & python.exe -m pip install -r .ci/requirements-cibw.txt - # Cannot cross-compile FriBiDi (only used for tests) - $FLAGS = ("--no-imagequant", "--architecture=${{ matrix.arch }}") - if ('${{ matrix.arch }}' -eq 'ARM64') { $FLAGS += "--no-fribidi" } - & python.exe winbuild\build_prepare.py -v @FLAGS + & python.exe winbuild\build_prepare.py -v --no-imagequant --architecture=${{ matrix.arch }} shell: pwsh - name: Build wheels @@ -163,14 +160,12 @@ jobs: path: ./wheelhouse/*.whl - name: Prepare to upload FriBiDi - if: "matrix.arch != 'ARM64'" run: | mkdir fribidi\${{ matrix.arch }} copy winbuild\build\bin\fribidi* fribidi\${{ matrix.arch }} shell: cmd - name: Upload fribidi.dll - if: "matrix.arch != 'ARM64'" uses: actions/upload-artifact@v3 with: name: fribidi diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index f7e145fb9..67e603d0d 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -56,7 +56,9 @@ def cmd_nmake( ) -def cmds_cmake(target: str | tuple[str, ...] | list[str], *params) -> list[str]: +def cmds_cmake( + target: str | tuple[str, ...] | list[str], *params, build_dir: str = "." +) -> list[str]: if not isinstance(target, str): target = " ".join(target) @@ -73,10 +75,11 @@ def cmds_cmake(target: str | tuple[str, ...] | list[str], *params) -> list[str]: "-DCMAKE_CXX_FLAGS=-nologo", *params, '-G "{cmake_generator}"', - ".", + f'-B "{build_dir}"', + f"-S .", ] ), - f"{{cmake}} --build . --clean-first --parallel --target {target}", + f'{{cmake}} --build "{build_dir}" --clean-first --parallel --target {target}', ] @@ -367,7 +370,14 @@ DEPS = { "build": [ cmd_copy(r"COPYING", r"{bin_dir}\fribidi-1.0.13-COPYING"), cmd_copy(r"{winbuild_dir}\fribidi.cmake", r"CMakeLists.txt"), - *cmds_cmake("fribidi"), + # generated tab.i files cannot be cross-compiled + " ^&^& ".join( + [ + "if {architecture}==ARM64 cmd /c call {vcvarsall} x86", + *cmds_cmake("fribidi-gen", "-DARCH=x86", build_dir="build_x86"), + ] + ), + *cmds_cmake("fribidi", "-DARCH={architecture}"), ], "bins": [r"*.dll"], }, @@ -381,10 +391,9 @@ def find_msvs(architecture: str) -> dict[str, str] | None: print("Program Files not found") return None + requires = ["-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64"] if architecture == "ARM64": - tools = "Microsoft.VisualStudio.Component.VC.Tools.ARM64" - else: - tools = "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" + requires += ["-requires", "Microsoft.VisualStudio.Component.VC.Tools.ARM64"] try: vspath = ( @@ -395,8 +404,7 @@ def find_msvs(architecture: str) -> dict[str, str] | None: ), "-latest", "-prerelease", - "-requires", - tools, + *requires, "-property", "installationPath", "-products", @@ -707,11 +715,6 @@ if __name__ == "__main__": disabled += ["libimagequant"] if args.no_fribidi: disabled += ["fribidi"] - elif args.architecture == "ARM64" and platform.machine() != "ARM64": - import warnings - - warnings.warn("Cross-compiling FriBiDi is currently not supported, disabling") - disabled += ["fribidi"] prefs = { "architecture": args.architecture, diff --git a/winbuild/fribidi.cmake b/winbuild/fribidi.cmake index 27b8d17a8..b16e0784c 100644 --- a/winbuild/fribidi.cmake +++ b/winbuild/fribidi.cmake @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.12) project(fribidi) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(lib) function(extract_regex_1 var text regex) @@ -27,12 +27,20 @@ function(fribidi_conf) set(PACKAGE_BUGREPORT "https://github.com/fribidi/fribidi/issues/new") set(SIZEOF_INT 4) set(FRIBIDI_MSVC_BUILD_PLACEHOLDER "#define FRIBIDI_BUILT_WITH_MSVC") - message("detected ${PACKAGE_NAME} version ${FRIBIDI_VERSION}") - configure_file(lib/fribidi-config.h.in lib/fribidi-config.h @ONLY) + message("Detected ${PACKAGE_NAME} version ${FRIBIDI_VERSION}") + configure_file(lib/fribidi-config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/lib/fribidi-config.h @ONLY) endfunction() fribidi_conf() +option(ARCH "Target architecture") +if(${ARCH} STREQUAL ARM64) + set(GEN FALSE) +else() + set(GEN TRUE) +endif() +message("Generate tab.i files: " ${GEN}) + function(prepend var prefix) set(out "") foreach(f ${ARGN}) @@ -56,18 +64,20 @@ macro(fribidi_definitions _TGT) endmacro() function(fribidi_gen _NAME _OUTNAME _PARAM) - set(_OUT lib/${_OUTNAME}) - prepend(_DEP "${CMAKE_CURRENT_SOURCE_DIR}/gen.tab/" ${ARGN}) - add_executable(gen-${_NAME} - gen.tab/gen-${_NAME}.c - gen.tab/packtab.c) - fribidi_definitions(gen-${_NAME}) - target_compile_definitions(gen-${_NAME} - PUBLIC DONT_HAVE_FRIBIDI_CONFIG_H) - add_custom_command( - COMMAND gen-${_NAME} ${_PARAM} ${_DEP} > ${_OUT} - DEPENDS ${_DEP} - OUTPUT ${_OUT}) + set(_OUT ${CMAKE_CURRENT_SOURCE_DIR}/lib/${_OUTNAME}) + if(GEN) + prepend(_DEP "${CMAKE_CURRENT_SOURCE_DIR}/gen.tab/" ${ARGN}) + add_executable(gen-${_NAME} + gen.tab/gen-${_NAME}.c + gen.tab/packtab.c) + fribidi_definitions(gen-${_NAME}) + target_compile_definitions(gen-${_NAME} + PUBLIC DONT_HAVE_FRIBIDI_CONFIG_H) + add_custom_command( + COMMAND gen-${_NAME} ${_PARAM} ${_DEP} > ${_OUT} + DEPENDS ${_DEP} + OUTPUT ${_OUT}) + endif(GEN) list(APPEND FRIBIDI_SOURCES_GENERATED "${_OUT}") set(FRIBIDI_SOURCES_GENERATED ${FRIBIDI_SOURCES_GENERATED} PARENT_SCOPE) endfunction() @@ -78,8 +88,10 @@ fribidi_gen(unicode-version fribidi-unicode-version.h "" macro(fribidi_tab _NAME) fribidi_gen(${_NAME}-tab ${_NAME}.tab.i 2 ${ARGN}) - target_sources(gen-${_NAME}-tab - PRIVATE lib/fribidi-unicode-version.h) + if(GEN) + target_sources(gen-${_NAME}-tab + PRIVATE lib/fribidi-unicode-version.h) + endif(GEN) endmacro() fribidi_tab(bidi-type unidata/UnicodeData.txt) @@ -89,14 +101,16 @@ fribidi_tab(mirroring unidata/BidiMirroring.txt) fribidi_tab(brackets unidata/BidiBrackets.txt unidata/UnicodeData.txt) fribidi_tab(brackets-type unidata/BidiBrackets.txt) +add_custom_target(fribidi-gen DEPENDS ${FRIBIDI_SOURCES_GENERATED}) + file(GLOB FRIBIDI_SOURCES lib/*.c) file(GLOB FRIBIDI_HEADERS lib/*.h) add_library(fribidi SHARED - ${FRIBIDI_SOURCES} - ${FRIBIDI_HEADERS} - ${FRIBIDI_SOURCES_GENERATED}) + ${FRIBIDI_SOURCES} + ${FRIBIDI_HEADERS} + ${FRIBIDI_SOURCES_GENERATED}) fribidi_definitions(fribidi) target_compile_definitions(fribidi - PUBLIC "-DFRIBIDI_BUILD") + PUBLIC "-DFRIBIDI_BUILD")