Как скомпилировать wxWidgets, используя пользовательскую версию необходимых сторонних библиотек

#cmake #wxwidgets

Вопрос:

Допустим, у меня есть libTiff, libpng, zlib и libjpeg. Как мне указать wxWidgets использовать их вместо встроенных или установленных в системе?

Я совсем новичок в wxWidgets и пытаюсь добавить его в качестве зависимости в свой проект CMake, который, в свою очередь, уже зависит и строит (использует ExternalProject ) вышеупомянутые библиотеки. Я не хочу смешивать версии (что неизбежно произойдет, если я использую встроенные или уже установленные в системе). Я также хочу, чтобы все зависимости были отделены от того, что уже присутствует в системе, для облегчения распространения.

Я проверил setup.h.in , где определены макросы препроцессора (здесь: wxUSE_ZLIB , wxUSE_LIBJPEG , wxUSE_LIBTIFF и wxUSE_LIBPNG ). Я также вижу, что внутри <root of wxWidgets git repo>/build/cmake/lib/ у меня есть различные *.cmake включаемые файлы, которые обрабатывают различные зависимости от сторонних производителей.

Однако я не понимаю, что мне нужно передать моей cmake команде, чтобы настроить wxWidgets для использования версий упомянутых выше библиотек из определенного места. Я определил PNG_LIBRARIES и JPEG_LIBRARIES т. Д. (указывает на то, где *.lib находятся файлы (в Windows) или *.so (в Linux). Кроме того, я определил ..._INCLUDE_DIRS соответственно.

В настоящее время это состояние моего внешнего описания проекта ( ... заполнители допустимых путей).

 ExternalProject_Add(wxWidgets
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps/wxwidgets
    
    INSTALL_DIR ...
    DOWNLOAD_DIR ""
    TMP_DIR ...
    STAMP_DIR ...
    LOG_DIR ...
    BINARY_DIR ...
    SOURCE_DIR ...

    INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "Skipping install step for dependency libzmq"
    INSTALL_PREFIX ...

    BUILD_ALWAYS OFF

    # For build configurations see https://wiki.wxwidgets.org/WxWidgets_Build_Configurations
    # Also setup.h.in and <wxWidgets_root>/build/cmake/libs
    CMAKE_ARGS
        "-DCMAKE_BUILD_TYPE=Release"
        "-DBUILD=release"
        "-DSHARED=1"
        "-DMONOLITHIC=1"
        "-DwxBUILD_TESTS=OFF"
        "-DwxBUILD_DEMOS=OFF"
        "-DwxBUILD_BENCHMARKS=OFF"
        "-DwxUSE_GUI=1"                               # <---- forces dependency requirement for PNG, ZLIB, JPEG, TIFF
        "-DwxUSE_OPENGL=1"
        "-DwxUSE_ZLIB=sys"
        "-DZLIB_LIBRARY=${ZLIB_LIBRARIES}"            # <---- from another ExternalProject
        "-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIRS}"    # <---- from another ExternalProject
        "-DwxUSE_LIBJPEG=sys"
        "-DJPEG_LIBRARY=${JPEG_LIBRARIES}"            # <---- from another ExternalProject
        "-DJPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIRS}"     # <---- from another ExternalProject
        "-DwxUSE_LIBPNG=sys"
        "-DPNG_LIBRARY=${PNG_LIBRARIES}"              # <---- from another ExternalProject
        "-DPNG_PNG_INCLUDE_DIR=${PNG_INCLUDE_DIRS}"   # <---- from another ExternalProject
        "-DwxUSE_LIBTIFF=builtin" # TODO Add libTiff to external project dependencies and use here
)
 

What I basically did is initially put stuff on OFF . wxWidgets’s configuration is smart enough to warn me that (since I included wxUSE_GUI , which requires those libs) the respective libraries are missing and it will use builtin instead. From there I found out which variables it is actually looking for and by setting wxUSE_... to sys for the respective library. For now I am getting closer to configuring the build:

 1>------ Rebuild All started: Project: ZERO_CHECK, Configuration: Debug x64 ------
1>Checking Build System
2>------ Rebuild All started: Project: wxWidgets, Configuration: Debug x64 ------
2>Creating directories for 'wxWidgets'
2>Building Custom Rule C:/Users/.../Documents/.../CMakeLists.txt
2>No download step for 'wxWidgets'
2>No update step for 'wxWidgets'
2>No patch step for 'wxWidgets'
2>Performing configure step for 'wxWidgets'
2>-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19042.
2>-- cotire 1.8.0 loaded.
2>-- Found ZLIB: C:/Users/.../CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/zlib/Debug/zlibd.lib (found version "1.2.11")
2>-- Found JPEG: C:/Users/rcr-aa/CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/jpeg/Debug/jpeg.lib (found version "90")
2>-- Found PNG: C:/Users/.../CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/png/Debug/libpng16d.lib (found version "1.6.38.git")
2>-- Which libraries should wxWidgets use?
2>    wxUSE_STL:      OFF      (use C   STL classes)
2>    wxUSE_REGEX:    builtin  (enable support for wxRegEx class)
2>    wxUSE_ZLIB:     sys      (use zlib for LZW compression)
2>    wxUSE_EXPAT:    builtin  (use expat for XML parsing)
2>    wxUSE_LIBJPEG:  sys      (use libjpeg (JPEG file format))
2>    wxUSE_LIBPNG:   sys      (use libpng (PNG image format))
2>    wxUSE_LIBTIFF:  builtin  (use libtiff (TIFF file format))
2>    wxUSE_LIBLZMA:  OFF      (use liblzma for LZMA compression)
2>
2>-- Configured wxWidgets 3.1.6 for Windows-10.0.19042
2>    Min OS Version required at runtime:                Windows Vista / Windows Server 2008 (x64 Edition)
2>    Which GUI toolkit should wxWidgets use?            msw
2>    Should wxWidgets be compiled into single library?  OFF
2>    Should wxWidgets be linked as a shared library?    ON
2>    Should wxWidgets support Unicode?                  ON
2>    What wxWidgets compatibility level should be used? 3.0
2>-- Configuring done
 

While looking around I also checked the *.cmake files for the libraries I want to use a custom version of to confirm what needs to be set. An example for zlib can be seen below:

 #############################################################################
# Name:        build/cmake/lib/zlib.cmake
# Purpose:     Use external or internal zlib
# Author:      Tobias Taschner
# Created:     2016-09-21
# Copyright:   (c) 2016 wxWidgets development team
# Licence:     wxWindows licence
#############################################################################

if(wxUSE_ZLIB STREQUAL "builtin")
    # TODO: implement building zlib via its CMake file, using
    # add_subdirectory or ExternalProject_Add
    wx_add_builtin_library(wxzlib
        src/zlib/adler32.c
        src/zlib/compress.c
        src/zlib/crc32.c
        src/zlib/deflate.c
        src/zlib/gzclose.c
        src/zlib/gzlib.c
        src/zlib/gzread.c
        src/zlib/gzwrite.c
        src/zlib/infback.c
        src/zlib/inffast.c
        src/zlib/inflate.c
        src/zlib/inftrees.c
        src/zlib/trees.c
        src/zlib/uncompr.c
        src/zlib/zutil.c
    )
    if(WIN32)
        # Define this to get rid of many warnings about using open(),
        # read() and other POSIX functions in zlib code. This is much
        # more convenient than having to modify it to avoid them.
        target_compile_definitions(wxzlib PRIVATE _CRT_NONSTDC_NO_WARNINGS)
    endif()
    set(ZLIB_LIBRARIES wxzlib)                           # <----------- set via -DZLIB_LIBRARIES in my ExternalProject 
    set(ZLIB_INCLUDE_DIRS ${wxSOURCE_DIR}/src/zlib)      # <----------- set via -DZLIB_INCLUDE_DIRS in my ExternalProject
elseif(wxUSE_ZLIB)
    find_package(ZLIB REQUIRED)
endif()
 

Моя самая большая проблема здесь заключается в том, что я, по-видимому, должен настроить конфигурацию для каждой сторонней зависимости (в моем случае установите для каждой другой зависимости значение builtin )

 2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  Cannot find source file:
2>
2>    C:/Users/.../Documents/.../deps/wxwidgets/3rdparty/pcre/src/pcre2_auto_possess.c
2>
2>  Tried extensions .c .C .c   .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2>  .hh .h   .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2>  build/cmake/lib/regex.cmake:13 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  Cannot find source file:
2>
2>    C:/Users/.../Documents/.../deps/wxwidgets/src/expat/expat/lib/xmlparse.c
2>
2>  Tried extensions .c .C .c   .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2>  .hh .h   .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2>  build/cmake/lib/expat.cmake:13 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  Cannot find source file:
2>
2>    C:/Users/.../Documents/.../deps/wxwidgets/src/tiff/libtiff/tif_win32.c
2>
2>  Tried extensions .c .C .c   .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2>  .hh .h   .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2>  build/cmake/lib/tiff.cmake:19 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  No SOURCES given to target: wxregex
2>Call Stack (most recent call first):
2>  build/cmake/lib/regex.cmake:13 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  No SOURCES given to target: wxexpat
2>Call Stack (most recent call first):
2>  build/cmake/lib/expat.cmake:13 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2>  No SOURCES given to target: wxtiff
2>Call Stack (most recent call first):
2>  build/cmake/lib/tiff.cmake:19 (wx_add_builtin_library)
2>  build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Generate step failed.  Build files cannot be regenerated correctly.
2>C:Program Files (x86)Microsoft Visual Studio2017ProfessionalCommon7IDEVCVCTargetsMicrosoft.CppCommon.targets(209,5): error MSB6006: "cmd.exe" exited with code 1.
2>Done building project "wxWidgets.vcxproj" -- FAILED.
 

Поскольку я не знаком с wxWidgets, я хотел бы спросить, могу ли я просто установить все остальные зависимости на builtin .

Комментарии:

1. наилучшим возможным решением было бы использовать системные библиотеки, и если их там нет (`Winblows1 возвращается к встроенной. В противном случае пользователь может получить 3 независимые и, возможно, несовместимые версии библиотеки. И вы закончите тем, что попытаетесь найти проблему надвигающейся катастрофы…

Ответ №1:

Прежде всего, вы должны настроить все так, чтобы существующие библиотеки можно было найти либо с помощью CMake (используя его find_package() ), либо настроить (который использует pkg-config ).

Во-вторых, с CMake я считаю, что вам нужно явно задать такие параметры, как wxUSE_LIBPNG sys . При сборке с использованием configure это уже значение по умолчанию, так как configure сначала будет искать системные библиотеки и вернется только к встроенным, если системные не найдены, но вы также можете использовать параметры командной строки, такие как --with-libpng=sys принудительное использование системных библиотек (и сбой конфигурации, если они не найдены).