Leggere in inglese

Condividi tramite


Esempio di applicazione di patch: Applicazione di patch libpng per funzionare per x64-uwp

Log degli errori iniziali

Prima di tutto, provare a creare:

PS D:\src\vcpkg> vcpkg install libpng:x64-uwp --editable
Computing installation plan...
The following packages will be built and installed:
    libpng[core]:x64-uwp
Starting package 1/1: libpng:x64-uwp
Building package libpng[core]:x64-uwp...
-- Using cached D:/src/vcpkg/downloads/glennrp-libpng-v1.6.37.tar.gz
-- Extracting source D:/src/vcpkg/downloads/glennrp-libpng-v1.6.37.tar.gz
-- Using source at D:/src/vcpkg/buildtrees/libpng/src/v1.6.37-c993153cdf
-- Configuring x64-uwp
-- Building x64-uwp-rel
CMake Error at scripts/cmake/execute_required_process.cmake:14 (message):
  Command failed: C:/Program Files/CMake/bin/cmake.exe;--build;.;--config;Release

  Working Directory: D:/src/vcpkg/buildtrees/libpng/x64-uwp-rel

  See logs for more information:

      D:\src\vcpkg\buildtrees\libpng\build-x64-uwp-rel-out.log
      D:\src\vcpkg\buildtrees\libpng\build-x64-uwp-rel-err.log

Call Stack (most recent call first):
  scripts/cmake/vcpkg_build_cmake.cmake:3 (execute_required_process)
  ports/libpng/portfile.cmake:22 (vcpkg_build_cmake)
  scripts/ports.cmake:84 (include)


Error: build command failed

Esaminare quindi i log precedenti (build-xxx-out.log e build-xxx-err.log).

// build-x64-uwp-rel-out.log
...
"D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\ALL_BUILD.vcxproj" (default target) (1) ->
"D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\png.vcxproj" (default target) (3) ->
(ClCompile target) -> 
  D:\src\vcpkg\buildtrees\libpng\src\v1.6.37-c993153cdf\pngerror.c(775): warning C4013: 'ExitProcess' undefined; assuming extern returning int [D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\png.vcxproj]


"D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\ALL_BUILD.vcxproj" (default target) (1) ->
"D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\png.vcxproj" (default target) (3) ->
(Link target) -> 
  pngerror.obj : error LNK2019: unresolved external symbol _ExitProcess referenced in function _png_longjmp [D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\png.vcxproj]
  D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\Release\libpng16.dll : fatal error LNK1120: 1 unresolved externals [D:\src\vcpkg\buildtrees\libpng\x64-uwp-rel\png.vcxproj]

    1 Warning(s)
    2 Error(s)

Time Elapsed 00:00:04.19

Identificare il codice problematico

Esaminando Microsoft Learn viene mostrato che ExitProcess è disponibile solo per le app desktop. Inoltre, è utile vedere il contesto circostante:

/* buildtrees\libpng\src\v1.6.37-c993153cdf\pngerror.c:769 */
    /* If control reaches this point, png_longjmp() must not return. The only
    * choice is to terminate the whole process (or maybe the thread); to do
    * this the ANSI-C abort() function is used unless a different method is
    * implemented by overriding the default configuration setting for
    * PNG_ABORT().
    */
    PNG_ABORT();

Una ricerca ricorsiva per PNG_ABORT rivela la definizione:

PS D:\src\vcpkg\buildtrees\libpng\src\v1.6.37-c993153cdf> findstr /snipl "PNG_ABORT" *
CHANGES:701:  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
libpng-manual.txt:432:errors will result in a call to PNG_ABORT() which defaults to abort().
libpng-manual.txt:434:You can #define PNG_ABORT() to a function that does something
libpng-manual.txt:2753:errors will result in a call to PNG_ABORT() which defaults to abort().
libpng-manual.txt:2755:You can #define PNG_ABORT() to a function that does something
libpng-manual.txt:4226:PNG_NO_SETJMP, in which case it is handled via PNG_ABORT()),
libpng.3:942:errors will result in a call to PNG_ABORT() which defaults to abort().
libpng.3:944:You can #define PNG_ABORT() to a function that does something
libpng.3:3263:errors will result in a call to PNG_ABORT() which defaults to abort().
libpng.3:3265:You can #define PNG_ABORT() to a function that does something
libpng.3:4736:PNG_NO_SETJMP, in which case it is handled via PNG_ABORT()),
png.h:994: * will use it; otherwise it will call PNG_ABORT().  This function was
pngerror.c:773:    * PNG_ABORT().
pngerror.c:775:   PNG_ABORT();
pngpriv.h:459:#ifndef PNG_ABORT
pngpriv.h:461:#    define PNG_ABORT() ExitProcess(0)
pngpriv.h:463:#    define PNG_ABORT() abort()

Questo ci offre già alcuni ottimi indizi, ma la definizione completa racconta la storia completa.

/* buildtrees\libpng\src\v1.6.37-c993153cdf\pngpriv.h:459 */
#ifndef PNG_ABORT
#  ifdef _WINDOWS_
#    define PNG_ABORT() ExitProcess(0)
#  else
#    define PNG_ABORT() abort()
#  endif
#endif

abort() è una chiamata CRT standard e certamente disponibile in UWP, quindi dobbiamo solo convincere libpng ad essere più indipendente dalla piattaforma. Il modo più semplice e affidabile per ottenere questo risultato consiste nell'applicare patch al codice; anche se in questo caso specifico è possibile passare un flag del compilatore per eseguire l'override perché si tratta di un'intestazione PNG_ABORT privata, in generale è più affidabile evitare di aggiungere altre opzioni del compilatore necessarie quando possibile (soprattutto quando non è già esposto come opzione CMake).

Applicazione di patch al codice per migliorare la compatibilità

È consigliabile usare Git per creare il file patch, perché è già installato.

PS D:\src\vcpkg\buildtrees\libpng\src\v1.6.37-c993153cdf> git init .
Initialized empty Git repository in D:/src/vcpkg/buildtrees/libpng/src/v1.6.37-c993153cdf/.git/

PS D:\src\vcpkg\buildtrees\libpng\src\v1.6.37-c993153cdf> git add .
warning: LF will be replaced by CRLF in ANNOUNCE.
The file will have its original line endings in your working directory.
...

PS D:\src\vcpkg\buildtrees\libpng\src\v1.6.37-c993153cdf> git commit -m "temp"
[master (root-commit) 68f253f] temp
 422 files changed, 167717 insertions(+)
...

Ora è possibile modificare pngpriv.h in modo da usare abort() ovunque.

/* buildtrees\libpng\src\v1.6.37-c993153cdf\pngpriv.h:459 */
#ifndef PNG_ABORT
#  define PNG_ABORT() abort()
#endif

L'output di git diff è già in formato patch, quindi è sufficiente salvare la patch nella ports/libpng directory.

PS buildtrees\libpng\src\v1.6.37-c993153cdf> git diff --ignore-space-at-eol | out-file -enc ascii ..\..\..\..\ports\libpng\use-abort-on-all-platforms.patch

Infine, è necessario applicare la patch dopo l'estrazione dell'origine.

# ports\libpng\portfile.cmake
...
vcpkg_extract_source_archive_ex(
  OUT_SOURCE_PATH SOURCE_PATH
  ARCHIVE ${ARCHIVE}
  PATCHES 
    "use-abort-on-all-platforms.patch"
)

vcpkg_cmake_configure(
...

Verifica

Per essere completamente sicuri che funzioni da zero, è necessario rimuovere il pacchetto e ricompilarlo:

PS D:\src\vcpkg> vcpkg remove libpng:x64-uwp
Package libpng:x64-uwp was successfully removed

Ora proviamo una nuova installazione, da zero.

PS D:\src\vcpkg> vcpkg install libpng:x64-uwp
Computing installation plan...
The following packages will be built and installed:
    libpng[core]:x64-uwp
Starting package 1/1: libpng:x64-uwp
Building package libpng[core]:x64-uwp...
Could not locate cached archive: C:\Users\me\AppData\Local\vcpkg/archives\f4\f44b54f818f78b9a4ccd34b3666f566f94286850.zip
-- Using cached D:/src/vcpkg/downloads/glennrp-libpng-v1.6.37.tar.gz
-- Extracting source D:/src/vcpkg/downloads/glennrp-libpng-v1.6.37.tar.gz
-- Applying patch use_abort.patch
-- Applying patch cmake.patch
-- Applying patch pkgconfig.patch
-- Applying patch pkgconfig.2.patch
-- Using source at D:/src/vcpkg/buildtrees/libpng/src/v1.6.37-10db9f58e4.clean
-- Configuring x64-uwp
-- Building x64-uwp-dbg
-- Building x64-uwp-rel
-- Fixing pkgconfig file: D:/src/vcpkg/packages/libpng_x64-uwp/lib/pkgconfig/libpng.pc
-- Fixing pkgconfig file: D:/src/vcpkg/packages/libpng_x64-uwp/lib/pkgconfig/libpng16.pc
-- Fixing pkgconfig file: D:/src/vcpkg/packages/libpng_x64-uwp/debug/lib/pkgconfig/libpng.pc
-- Fixing pkgconfig file: D:/src/vcpkg/packages/libpng_x64-uwp/debug/lib/pkgconfig/libpng16.pc
-- Installing: D:/src/vcpkg/packages/libpng_x64-uwp/share/libpng/copyright
-- Performing post-build validation
-- Performing post-build validation done
Stored binary cache: C:\Users\me\AppData\Local\vcpkg/archives\f4\f44b54f818f78b9a4ccd34b3666f566f94286850.zip
Building package libpng[core]:x64-uwp... done
Installing package libpng[core]:x64-uwp...
Installing package libpng[core]:x64-uwp... done
Elapsed time for package libpng:x64-uwp: 11.94 s

Total elapsed time: 11.95 s

The package libpng:x64-uwp provides CMake targets:

    find_package(libpng CONFIG REQUIRED)
    target_link_libraries(main PRIVATE png)

Infine, per eseguire il commit completo e pubblicare le modifiche, è necessario aggiornare la versione della porta in vcpkg.jsone aggiungere il file patch al controllo del codice sorgente, quindi effettuare una richiesta pull.

{
  "name": "libpng",
  "version": "1.6.37",
  "port-version": 1,
  "dependencies": [
    "zlib"
  ]
}