패치 예제: x64-uwp에 작동하도록 libpng 패치
초기 오류 로그
먼저 다음을 빌드해 봅니다.
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
다음으로, 위의 로그(build-xxx-out.log 및 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
문제가 있는 코드 식별
Microsoft Learn을 살펴보면 데스크톱 앱에서만 사용할 수 있는 것이 ExitProcess
표시됩니다. 또한 주변 컨텍스트를 확인하는 것이 유용합니다.
/* 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();
재귀 검색은 PNG_ABORT
정의를 표시합니다.
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()
이것은 이미 우리에게 몇 가지 훌륭한 단서를 제공하지만, 전체 정의는 전체 이야기를 알려줍니다.
/* 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()
는 표준 CRT 호출이며 UWP에서 확실히 사용할 수 있으므로 libpng가 더 플랫폼에 구애받지 않도록 설득해야 합니다. 이 작업을 수행하는 가장 쉽고 신뢰할 수 있는 방법은 코드를 패치하는 것입니다. 이 특정 경우에는 프라이빗 헤더이므로 재정 PNG_ABORT
의할 컴파일러 플래그를 전달할 수 있지만, 일반적으로 가능한 경우 필요한 컴파일러 스위치를 더 이상 추가하지 않도록 하는 것이 더 안정적입니다(특히 CMake 옵션으로 아직 노출되지 않은 경우).
호환성을 개선하기 위해 코드 패치
이미 설치되어 있으므로 git을 사용하여 패치 파일을 만드는 것이 좋습니다.
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(+)
...
이제 모든 곳에서 사용하도록 abort()
수정 pngpriv.h
할 수 있습니다.
/* buildtrees\libpng\src\v1.6.37-c993153cdf\pngpriv.h:459 */
#ifndef PNG_ABORT
# define PNG_ABORT() abort()
#endif
출력 git diff
은 이미 패치 형식이므로 패치를 ports/libpng
디렉터리에 저장하기만 하면됩니다.
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
마지막으로 원본을 추출한 후 패치를 적용해야 합니다.
# 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(
...
확인
처음부터 완전히 작동하도록 하려면 패키지를 제거하고 다시 빌드해야 합니다.
PS D:\src\vcpkg> vcpkg remove libpng:x64-uwp
Package libpng:x64-uwp was successfully removed
이제 처음부터 새로 설치해 봅니다.
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)
마지막으로, 변경 내용을 완전히 커밋하고 게시하려면 포트 버전을 범프하고 소스 제어에 vcpkg.json
패치 파일을 추가한 다음 끌어오기 요청을 만들어야 합니다.
{
"name": "libpng",
"version": "1.6.37",
"port-version": 1,
"dependencies": [
"zlib"
]
}
vcpkg