diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index c13f92201..3d1093344 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -129,3 +129,44 @@ jobs: ./windows/x64/Debug-Full/ccextractorwinfull.exe ./windows/x64/Debug-Full/ccextractorwinfull.pdb ./windows/x64/Debug-Full/*.dll + + build_cmake: + runs-on: windows-2022 + steps: + - name: Check out repository + uses: actions/checkout@v4 + - name: Setup MSBuild.exe + uses: microsoft/setup-msbuild@v2.0.0 + with: + msbuild-architecture: x64 + - name: Setup vcpkg + run: mkdir C:\vcpkg\.cache + - name: Cache vcpkg + id: cache + uses: actions/cache@v4 + with: + path: | + C:\vcpkg\.cache + key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }} + - name: Build vcpkg + run: | + git clone https://github.com/microsoft/vcpkg + ./vcpkg/bootstrap-vcpkg.bat + - name: Install dependencies + run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/ + working-directory: windows + - name: Configure CMake + env: + VCPKG_ROOT: ${{ github.workspace }}/vcpkg + run: | + cmake -S src -B cmake-build -A x64 -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake + - name: Build with CMake + run: cmake --build cmake-build --config Release --target ccextractor + - name: Display version information + run: .\cmake-build\Release\ccextractor.exe --version + - uses: actions/upload-artifact@v4 + with: + name: CCExtractor Windows CMake build + path: | + ./cmake-build/Release/ccextractor.exe + ./cmake-build/Release/*.dll diff --git a/docs/CHANGES.TXT b/docs/CHANGES.TXT index 10c4a8708..6c649336d 100644 --- a/docs/CHANGES.TXT +++ b/docs/CHANGES.TXT @@ -1,13 +1,6 @@ 0.95 (2025-09-15) ----------------- -- Fix: DVB subtitle extraction improvements for Chinese broadcasts (#224): - - Fix crash in parse_PMT() due to missing bounds checks - - Fix negative timestamps in DVB subtitle output - - Fix crash in ignore_alpha_at_edge() OCR cropping - - Improve DVB subtitle OCR accuracy with image inversion - - Fix --ocrlang to accept Tesseract language names (chi_tra, chi_sim, etc.) - - Add case-insensitive matching for --dvblang parameter -- FIX: Add HEVC/H.265 stream type recognition to prevent crashes on ATSC 3.0 streams +- Fix: Windows CMake build - create static zlib library to avoid LNK1104 error (issue #1352) - Fix: ARM64/aarch64 build failure due to c_char type mismatch in nal.rs - Fix: HardSubX OCR on Rust - Removed the Share Module diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1896b3492..3ad8e2cc0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,24 @@ cmake_minimum_required (VERSION 3.24.0) -project (CCExtractor) + +# On Windows, use static C runtime library to avoid UCRT symbol import issues +# MUST be set before project() to take effect +if (WIN32) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() + +project (CCExtractor C) + +# Enable parallel compilation for faster builds +if(MSVC) + add_compile_options(/MP) +endif() + +# Use ccache if available for faster recompilation +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + message(STATUS "Using ccache for faster builds") +endif() include (CTest) @@ -69,7 +88,25 @@ include_directories(${PROJECT_SOURCE_DIR}/thirdparty/zlib) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/freetype/include) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash/ SOURCEFILE) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/ SOURCEFILE) -aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/zlib/ SOURCEFILE) + +# Gather zlib sources; on Windows build a static library and link it to +# avoid depending on an external `zlib.lib` (which causes LNK1104 when +# it's not available). On other platforms keep the old behavior of +# compiling the sources directly into the main executable. + +if (WIN32) + file(GLOB ZLIB_SOURCES "${PROJECT_SOURCE_DIR}/thirdparty/zlib/*.c") + add_library(zlib_static STATIC ${ZLIB_SOURCES}) + target_include_directories(zlib_static PUBLIC ${PROJECT_SOURCE_DIR}/thirdparty/zlib) + # Suppress warnings in third-party code + if(MSVC) + target_compile_options(zlib_static PRIVATE /W0) + endif() + set (EXTRA_LIBS ${EXTRA_LIBS} zlib_static) +else() + aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/zlib/ SOURCEFILE) +endif() + aux_source_directory(${PROJECT_SOURCE_DIR}/lib_ccx/zvbi/ SOURCEFILE) set(UTF8PROC_SOURCE ${PROJECT_SOURCE_DIR}/thirdparty/utf8proc/utf8proc.c) @@ -242,6 +279,19 @@ endif (PKG_CONFIG_FOUND AND WITH_HARDSUBX) add_executable (ccextractor ${SOURCEFILE} ${FREETYPE_SOURCE} ${UTF8PROC_SOURCE}) +# Optimize compilation +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + if(MSVC) + target_compile_options(ccextractor PRIVATE /O2) + else() + target_compile_options(ccextractor PRIVATE -O3) + endif() +endif() + ######################################################## # Build with Rust library ######################################################## @@ -251,8 +301,7 @@ if (PKG_CONFIG_FOUND) set (EXTRA_LIBS ${EXTRA_LIBS} ccx_rust) endif (PKG_CONFIG_FOUND) - -target_link_libraries (ccextractor ${EXTRA_LIBS}) +target_link_libraries (ccextractor PRIVATE ${EXTRA_LIBS}) target_include_directories (ccextractor PUBLIC ${EXTRA_INCLUDES}) install (TARGETS ccextractor DESTINATION bin) diff --git a/src/lib_ccx/CMakeLists.txt b/src/lib_ccx/CMakeLists.txt index befb4f18b..1c23b4ad2 100644 --- a/src/lib_ccx/CMakeLists.txt +++ b/src/lib_ccx/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_policy (SET CMP0037 NEW) if(MSVC) set (CMAKE_C_FLAGS "-W3 /wd4005 /wd4996") + # Optimize for speed in release builds + if(CMAKE_BUILD_TYPE STREQUAL "Release") + add_compile_options(/O2 /GL) + add_link_options(/LTCG) + endif() else (MSVC) set (CMAKE_C_FLAGS "-Wall -Wno-pointer-sign -g -std=gnu99") endif(MSVC) @@ -10,11 +15,21 @@ if(WIN32) add_definitions(-DWIN32) endif(WIN32) -find_package(PkgConfig) -pkg_check_modules (GPAC REQUIRED gpac) - -set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${GPAC_INCLUDE_DIRS}) -set (EXTRA_LIBS ${EXTRA_LIBS} ${GPAC_LIBRARIES}) +# Try to find GPAC via pkg-config, or use manually specified variables +if(NOT DEFINED GPAC_INCLUDE_DIRS OR NOT DEFINED GPAC_LIBRARIES) + find_package(PkgConfig) + pkg_check_modules (GPAC gpac) +endif() + +# Add GPAC include dirs and libraries if available +if(GPAC_INCLUDE_DIRS AND GPAC_LIBRARIES) + set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${GPAC_INCLUDE_DIRS}) + set (EXTRA_LIBS ${EXTRA_LIBS} ${GPAC_LIBRARIES}) + message(STATUS "GPAC enabled") +else() + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_GPAC") + message(WARNING "GPAC not found - MP4 support will be disabled") +endif() if (WITH_FFMPEG) find_package(PkgConfig) @@ -53,6 +68,18 @@ if (WITH_OCR) set (EXTRA_LIBS ${EXTRA_LIBS} ${TESSERACT_LIBRARIES}) set (EXTRA_LIBS ${EXTRA_LIBS} ${LEPTONICA_LIBRARIES}) + # Some pkg-config files for leptonica report the include dir as + # .../include/leptonica which causes to + # expand incorrectly. Add the parent include directory as well. + # Handle multiple include paths by iterating over each one. + foreach(LEPT_INC ${LEPTONICA_INCLUDE_DIRS}) + get_filename_component(LEPT_PARENT "${LEPT_INC}" DIRECTORY) + if(LEPT_PARENT) + list(APPEND EXTRA_INCLUDES ${LEPT_PARENT}) + endif() + endforeach() + list(REMOVE_DUPLICATES EXTRA_INCLUDES) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_OCR") endif (WITH_OCR) diff --git a/src/lib_ccx/mp4.c b/src/lib_ccx/mp4.c index e832c170b..f2802150b 100644 --- a/src/lib_ccx/mp4.c +++ b/src/lib_ccx/mp4.c @@ -2,6 +2,7 @@ #include #include +#ifndef DISABLE_GPAC #include #include "lib_ccx.h" #include "utility.h" @@ -865,3 +866,22 @@ int dumpchapters(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file) gf_fclose(t); return mp4_ret; } + +#else // DISABLE_GPAC + +// Stub functions when GPAC is not available +#include "lib_ccx.h" +#include "ccx_common_option.h" +#include "ccx_mp4.h" + +int processmp4(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file) +{ + return -1; // MP4 processing not available without GPAC +} + +int dumpchapters(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file) +{ + return -1; // Chapter dumping not available without GPAC +} + +#endif // !DISABLE_GPAC diff --git a/src/lib_ccx/params.c b/src/lib_ccx/params.c index 38bfb4cf9..49bc2727f 100644 --- a/src/lib_ccx/params.c +++ b/src/lib_ccx/params.c @@ -1,7 +1,9 @@ #include #include "zlib.h" +#ifndef DISABLE_GPAC #include "gpac/setup.h" #include "gpac/version.h" +#endif #include "lib_ccx.h" #include "ccx_common_option.h" #include "utility.h" @@ -765,7 +767,9 @@ void version(char *location) mprint(" Leptonica Version: %s\n", leptversion); lept_free(leptversion); #endif // ENABLE_OCR - mprint(" libGPAC Version: %s\n", GPAC_VERSION); +#ifndef DISABLE_GPAC + mprint("\tlibGPAC Version: %s\n", GPAC_VERSION); +#endif mprint(" zlib: %s\n", ZLIB_VERSION); mprint(" utf8proc Version: %s\n", (const char *)utf8proc_version()); mprint(" libpng Version: %s\n", PNG_LIBPNG_VER_STRING); diff --git a/windows/vcpkg.json b/windows/vcpkg.json index 81392c146..3948b1b91 100644 --- a/windows/vcpkg.json +++ b/windows/vcpkg.json @@ -2,8 +2,6 @@ "name": "ccextractor", "version": "1.0.0", "dependencies": [ - "leptonica", - "tesseract", "ffmpeg" ], "builtin-baseline": "189fcdcb953b871d206ffada6db047496fc3f496"