Hatred's Log Place

DON'T PANIC!

Apr 23, 2024 - 3 minute read - Programming C++

Conan vs vcpkg, действие второе

И так, в продолжение темы Conan vs vcpkg. Как я там уже писал с vcpkg подружиться получилось.

Для начала тулчейн. У меня получилось запустить как с MXE, который был собран командой make cc . Сам конфиг для статической сборки получился такой (файл settings.mk, положить в корень копии MXE):

Для него нужен вот такой CMake toolchain файл:

Но с тем же успехом отработал и тулчейн из Manjaro/ArchLinux. Для него тулчён файл чуууточку поправленный:

Всё отличие:

--- toolchain-cross-mingw32-linux-w64-mxe.cmake 2024-04-15 11:42:29.423500871 +1000  
+++ toolchain-cross-mingw32-linux-w64-sys.cmake 2024-04-15 11:42:29.426834270 +1000  
@@ -1,9 +1,18 @@  
+# Tested with system MinGW compiler in the Manjaro Linux  
+#  
+# Just install it:  
+#  
+# sudo pacman -S mingw-w64-gcc mingw-w64-binutils mingw-w64-crt mingw-w64-headers mingw-w64-winpthreads  
+#  
+# Or just adjust PATH (prepend or append) with location of the installed MinGW  
+#  
+#  
+  
# the name of the target operating system  
set(CMAKE_SYSTEM_NAME Windows)  
set(CMAKE_CROSSCOMPILING TRUE)  
   
-set(MXE_PREFIX ${CMAKE_CURRENT_LIST_DIR}/mxe/usr)  
-set(COMPILER_PREFIX "x86_64-w64-mingw32.static")  
+set(COMPILER_PREFIX "x86_64-w64-mingw32")  
   
# for find_library()  
set(CMAKE_LIBRARY_ARCHITECTURE ${COMPILER_PREFIX})  
@@ -19,12 +28,12 @@  
endif()  
   
# which compilers to use for C and C++  
-find_program(CMAKE_RC_COMPILER NAMES ${MXE_PREFIX}/bin/${COMPILER_PREFIX}-windres)  
-find_program(CMAKE_C_COMPILER NAMES ${MXE_PREFIX}/bin/${COMPILER_PREFIX}-gcc)  
-find_program(CMAKE_CXX_COMPILER NAMES ${MXE_PREFIX}/bin/${COMPILER_PREFIX}-g++)  
+find_program(CMAKE_RC_COMPILER NAMES  ${COMPILER_PREFIX}-windres)  
+find_program(CMAKE_C_COMPILER NAMES   ${COMPILER_PREFIX}-gcc)  
+find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)  
   
if (NOT IS_VCPKG)  
-    find_program(PKG_CONFIG_EXECUTABLE NAMES ${MXE_PREFIX}/bin/${COMPILER_PREFIX}-pkg-config)  
+    find_program(PKG_CONFIG_EXECUTABLE NAMES ${COMPILER_PREFIX}-pkg-config)  
endif()  
   
set(CMAKE_C_COMPILER_WORKS On)  
@@ -45,7 +54,7 @@  
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)  
   
# We want to install alongside the compiler by default  
-set(CMAKE_INSTALL_PREFIX ${MXE_PREFIX})  
+set(CMAKE_INSTALL_PREFIX /usr/${COMPILER_PREFIX})  
   
if (VCPKG_INSTALLED_DIR)  
    # TBD: make more clean  
@@ -54,12 +63,6 @@  
    set(CMAKE_SHARED_LINKER_FLAGS "-L${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib")  
endif()  
   
-# WA for MXE  
-if (NOT IS_VCPKG)  
-    set(CMAKE_EXE_LINKER_FLAGS "-liconv")  
-    set(CMAKE_SHARED_LINKER_FLAGS "-liconv")  
-endif()  
-  
# DEBUG  
#get_cmake_property(_variableNames VARIABLES)  
#list (SORT _variableNames)

По сути, только префиксы и “костыль” с iconv убраны.

Далее, мы имели дело с этим:

/bin/sh: строка 1: powershell.exe: команда не найдена  
ninja: build stopped: subcommand failed.

Да, Microsoft решила свои проблемы радикальным способом: у нас есть свой шелл, ну давай его так пропихнём. Нужно отметить, что для сборки это не критично и ошибка вылазит на этапе cmake --install -B build. Вылечить можно двумя способами:

  1. В тулчейнах выше указано:
    # WA for vcpkg + mingw cross building  
    # - you can install powershell: `yay -S powershell`  
    # - or just skip unneeded in most cases step  
    # - note, Z_xxx vairalble are internal one  
    set(Z_VCPKG_POWERSHELL_PATH echo)
    
    оно заглушает вывод и не мешает сборке.
  2. Либо поставить пакет: yay -S powershell, в системе появится шелл pwsh, который ищется в первую очередь, а потом делается откат на powershell.exe

Собственно, в прошлой статье на этом и была загвоздка. И после этого всё строится нормально, ровно как и не сильно изменился сам тулчйн-файл. Добавилось только ещё:

set(CMAKE_SHARED_LINKER_FLAGS "-L${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib")

как часть WA для vcpkg.

Немного усложнился файл манифеста vcpkg.json - добилось платформенное условие для Linux:

{  
   "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",  
   "dependencies": [  
       "ffmpeg",  
       "zlib",  
       {  
           "name": "libusb",  
           "features": [  
               {  
                   "name": "udev",  
                   "platform": "linux"  
               }  
           ]  
       }  
   ],  
   "name": "usbctl",  
   "version-string": "1.11"  
}

А сборка и конфигурирование проходит так:

cmake -S . -B build-win64-sys -G Ninja \  
   -DCMAKE_TOOLCHAIN_FILE=$(pwd)/vcpkg/scripts/buildsystems/vcpkg.cmake \
   -DCMAKE_CROSSCOMPILING=On \ # возможно, можно не указывать, но не перепроверял
   -DENABLE_STATIC=On \ # это проектная опция
   -DVCPKG_TARGET_TRIPLET=x64-mingw-static \  
   -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$(pwd)/toolchain-cross-mingw32-linux-w64-sys.cmake  
  
cmake --build   $BUILD --target all  
cmake --install $BUILD --prefix build-cross-install/usr # будет работать только если поставлен powershell и убрана строка с установкой Z_VCPKG_POWERSHELL_PATH в тулчейне