Exemplo de aplicação de patch: Corrigindo libpng para funcionar para x64-uwp
Logs de erros iniciais
Primeiro, tente criar:
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
Em seguida, observe os logs acima (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
Identificar o código problemático
Dar uma olhada no Microsoft Learn mostra que ExitProcess
está disponível apenas para aplicativos da área de trabalho. Além disso, é útil ver o contexto ao redor:
/* 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();
Uma busca recursiva por PNG_ABORT
revela a definição:
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()
Isso já nos dá ótimas pistas, mas a definição completa conta a história 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()
é uma chamada CRT padrão e certamente disponível na UWP, então só precisamos convencer o libpng a ser mais agnóstico em relação à plataforma. A maneira mais fácil e confiável de conseguir isso é corrigir o código; embora, neste caso específico, possamos passar um sinalizador de compilador para substituir PNG_ABORT
porque este é um cabeçalho privado, em geral é mais confiável evitar adicionar mais opções de compilador necessárias quando possível (especialmente quando ainda não está exposto como uma opção CMake).
Corrigindo o código para melhorar a compatibilidade
Recomendamos usar o git para criar o arquivo de patch, pois você já o terá instalado.
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(+)
...
Agora podemos modificar pngpriv.h
para usar abort()
em qualquer lugar.
/* buildtrees\libpng\src\v1.6.37-c993153cdf\pngpriv.h:459 */
#ifndef PNG_ABORT
# define PNG_ABORT() abort()
#endif
A saída de já está no formato de git diff
patch, então só precisamos salvar o patch no ports/libpng
diretório.
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
Finalmente, precisamos aplicar o patch após extrair a fonte.
# 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ção
Para ter certeza absoluta de que isso funciona do zero, precisamos remover o pacote e reconstruí-lo:
PS D:\src\vcpkg> vcpkg remove libpng:x64-uwp
Package libpng:x64-uwp was successfully removed
Agora tentamos uma nova instalação do 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)
Finalmente, para confirmar e publicar totalmente as alterações, precisamos aumentar a versão do port em vcpkg.json
, adicionar o arquivo de patch ao controle do código-fonte e, em seguida, fazer uma solicitação de pull!
{
"name": "libpng",
"version": "1.6.37",
"port-version": 1,
"dependencies": [
"zlib"
]
}