Files
docview/CMakeLists.txt
T
2026-09-21 13:41:40 +09:00

196 lines
12 KiB
CMake

cmake_minimum_required(VERSION 3.24)
project(DocView VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
include(CTest)
if(MSVC)
add_compile_options(/utf-8 /permissive- /Zc:__cplusplus)
endif()
if(WIN32 AND (NOT MSVC OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8))
message(FATAL_ERROR "DocView on Windows requires a 64-bit MSVC-compatible toolchain and matching Qt WebEngine.")
endif()
find_package(Qt6 6.11.2 EXACT REQUIRED COMPONENTS Core Gui Network Qml Quick QuickControls2 WebEngineQuick Xml LinguistTools)
if(WIN32)
find_package(libzip 1.11 CONFIG REQUIRED)
find_package(tomlplusplus 3.4 CONFIG REQUIRED)
set(DOCVIEW_ZIP_TARGET libzip::zip)
set(DOCVIEW_TOML_TARGET tomlplusplus::tomlplusplus)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBZIP REQUIRED IMPORTED_TARGET libzip>=1.11)
pkg_check_modules(TOML REQUIRED IMPORTED_TARGET tomlplusplus>=3.4)
pkg_check_modules(SECCOMP REQUIRED IMPORTED_TARGET libseccomp>=2.5)
pkg_check_modules(FONTCONFIG REQUIRED IMPORTED_TARGET fontconfig>=2.13)
set(DOCVIEW_ZIP_TARGET PkgConfig::LIBZIP)
set(DOCVIEW_TOML_TARGET PkgConfig::TOML)
endif()
include(cmake/Pdfium.cmake)
find_package(qpdf 12.4.1 EXACT CONFIG REQUIRED)
add_library(docview_common
src/common/ipc.cpp src/common/contracts.cpp src/common/sandbox.cpp
src/common/worker_process.cpp src/common/session_storage.cpp src/common/single_instance.cpp
src/common/windows_sandbox.cpp src/common/windows_pipe.cpp src/common/windows_runtime_staging.cpp
src/common/worker_runtime.cpp
src/common/font_contract.cpp src/common/worker_font_client.cpp
src/web/resource_policy.cpp src/web/renderer_watchdog.cpp)
target_include_directories(docview_common PUBLIC src)
target_link_libraries(docview_common PUBLIC Qt6::Core Qt6::Network)
if(WIN32)
target_compile_definitions(docview_common PUBLIC _WIN32_WINNT=0x0A00 NOMINMAX WIN32_LEAN_AND_MEAN)
target_link_libraries(docview_common PRIVATE userenv advapi32 kernel32 shell32 ole32 psapi)
else()
target_link_libraries(docview_common PRIVATE PkgConfig::SECCOMP)
endif()
add_library(docview_core src/core/config.cpp src/core/input.cpp src/core/state.cpp src/core/types.cpp
src/common/memory_pressure.cpp)
target_include_directories(docview_core PUBLIC src)
target_link_libraries(docview_core PUBLIC Qt6::Core ${DOCVIEW_TOML_TARGET})
if(WIN32)
target_compile_definitions(docview_core PRIVATE _WIN32_WINNT=0x0A00 NOMINMAX WIN32_LEAN_AND_MEAN)
target_link_libraries(docview_core PRIVATE shell32 ole32)
endif()
add_library(docview_pdf src/pdf/pdf_document.cpp src/pdf/link_border_reader.cpp src/pdf/pdf_metadata_context.cpp src/pdf/structure_reader.cpp)
target_sources(docview_pdf PRIVATE src/pdf/system_font_adapter.cpp)
target_include_directories(docview_pdf PUBLIC src)
target_link_libraries(docview_pdf PUBLIC Qt6::Core PDFium::PDFium docview_common)
target_link_libraries(docview_pdf PRIVATE qpdf::libqpdf)
add_library(docview_font_broker src/broker/font_broker.cpp src/broker/font_backend.cpp)
target_include_directories(docview_font_broker PUBLIC src)
target_link_libraries(docview_font_broker PUBLIC docview_common Qt6::Core)
if(WIN32)
target_sources(docview_font_broker PRIVATE src/broker/font_backend_win.cpp)
target_link_libraries(docview_font_broker PRIVATE gdi32)
else()
target_sources(docview_font_broker PRIVATE src/broker/font_backend_linux.cpp)
target_link_libraries(docview_font_broker PRIVATE PkgConfig::FONTCONFIG)
endif()
add_executable(docview-pdf-worker src/pdf/main.cpp)
target_link_libraries(docview-pdf-worker PRIVATE docview_pdf docview_common)
add_library(docview_archive src/archive/archive.cpp)
target_include_directories(docview_archive PUBLIC src)
target_link_libraries(docview_archive PUBLIC Qt6::Core Qt6::Xml ${DOCVIEW_ZIP_TARGET})
add_executable(docview-archive-worker src/archive/main.cpp)
target_link_libraries(docview-archive-worker PRIVATE docview_archive docview_common)
set(DOCVIEW_SHELL_SOURCES src/app/controller.cpp src/app/pdf_canvas.cpp src/web/web_profile.cpp resources.qrc)
qt_add_executable(docview src/app/main.cpp src/app/benchmark.cpp src/app/translations.cpp ${DOCVIEW_SHELL_SOURCES})
target_link_libraries(docview PRIVATE docview_core docview_common docview_font_broker Qt6::Gui Qt6::Quick Qt6::Qml Qt6::QuickControls2 Qt6::WebEngineQuick)
add_dependencies(docview docview-pdf-worker docview-archive-worker)
qt_add_translations(TARGETS docview
SOURCE_TARGETS docview docview_core docview_common docview_pdf docview_archive
docview_font_broker docview-pdf-worker docview-archive-worker
SOURCES qml/Main.qml qml/WebPane.qml
TS_FILES resources/i18n/docview_ja.ts
LUPDATE_OPTIONS -locations relative -no-obsolete
LUPDATE_TARGET docview_lupdate
LRELEASE_TARGET docview_lrelease
RESOURCE_PREFIX "/i18n")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Register candidate revalidation before any install rule copies a binary.
include(cmake/PdfiumSupplementalNotices.cmake)
endif()
if(UNIX)
set_target_properties(docview-pdf-worker PROPERTIES INSTALL_RPATH "$ORIGIN/../lib")
install(FILES "${DOCVIEW_PDFIUM_LIBRARY}" DESTINATION lib)
endif()
install(TARGETS docview docview-pdf-worker docview-archive-worker RUNTIME DESTINATION bin)
install(FILES resources/config.example.toml DESTINATION share/doc/docview)
install(DIRECTORY resources/licenses/qpdf DESTINATION share/doc/docview/licenses)
install(FILES "${DOCVIEW_PDFIUM_ROOT}/LICENSE" DESTINATION share/doc/docview/pdfium)
install(DIRECTORY "${DOCVIEW_PDFIUM_ROOT}/licenses/" DESTINATION share/doc/docview/pdfium/licenses)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
install(FILES docs/LINUX-DEVELOPMENT-PACKAGE.md DESTINATION share/doc/docview)
install(FILES resources/licenses/README.md DESTINATION share/doc/docview RENAME THIRD-PARTY-SCOPE.md)
include(cmake/LinuxDevelopmentPackage.cmake)
endif()
if(WIN32)
include(cmake/WindowsDeployment.cmake)
foreach(worker docview-pdf-worker docview-archive-worker)
docview_configure_windows_worker(${worker})
docview_install_windows_worker(${worker})
endforeach()
docview_install_windows_gui(docview)
endif()
if(BUILD_TESTING)
find_package(Qt6 REQUIRED COMPONENTS Test QuickTest)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
qt_add_executable(test_translations tests/test_translations.cpp src/app/translations.cpp)
target_link_libraries(test_translations PRIVATE docview_core Qt6::Test Qt6::Quick Qt6::Qml Qt6::QuickControls2)
qt_add_resources(test_translations test_translations_catalog
PREFIX "/i18n" BASE "${CMAKE_CURRENT_BINARY_DIR}"
FILES "${CMAKE_CURRENT_BINARY_DIR}/docview_ja.qm")
add_dependencies(test_translations docview_lrelease)
add_test(NAME translations COMMAND test_translations)
set_tests_properties(translations PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen;QT_QUICK_BACKEND=software;LANG=C.UTF-8")
add_test(NAME runtime_manifest COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_runtime_manifest.py" -v)
add_test(NAME benchmark_runner COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_benchmark_runner.py" -v)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_test(NAME linux_package COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_linux_package.py" -v)
add_test(NAME dependency_provenance COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_dependency_provenance_qt.py" -v)
add_test(NAME ubuntu_runtime_inventory COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_ubuntu_validation_runtime.py" -v)
add_test(NAME pdfium_candidate_staging COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_stage_pdfium_candidate.py" -v)
add_test(NAME pdfium_candidate_integration COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_pdfium_candidate_integration.py" -v)
endif()
foreach(name core archive pdf security instance renderer_watchdog worker_process runtime_staging font_contract font_broker system_font_adapter memory_pressure)
add_executable(test_${name} tests/test_${name}.cpp)
target_link_libraries(test_${name} PRIVATE docview_common Qt6::Test)
if(TARGET docview_${name})
target_link_libraries(test_${name} PRIVATE docview_${name})
endif()
add_test(NAME ${name} COMMAND test_${name})
endforeach()
target_link_libraries(test_memory_pressure PRIVATE docview_core)
target_link_libraries(test_pdf PRIVATE docview_font_broker qpdf::libqpdf)
target_link_libraries(test_system_font_adapter PRIVATE docview_pdf)
add_executable(pdf-worker-evidence tests/render_pdf_worker.cpp)
target_link_libraries(pdf-worker-evidence PRIVATE docview_common docview_font_broker Qt6::Gui)
add_dependencies(pdf-worker-evidence docview-pdf-worker)
if(WIN32)
foreach(name windows_pipe windows_resources windows_worker)
add_executable(test_${name} tests/test_${name}.cpp)
target_link_libraries(test_${name} PRIVATE docview_common Qt6::Test)
add_test(NAME ${name} COMMAND test_${name})
endforeach()
add_executable(docview-windows-worker-probe tests/windows_worker_probe.cpp)
target_link_libraries(docview-windows-worker-probe PRIVATE docview_common ws2_32 userenv advapi32 ole32)
docview_configure_windows_worker(docview-windows-worker-probe)
add_dependencies(test_windows_worker docview-windows-worker-probe)
set_tests_properties(windows_worker PROPERTIES TIMEOUT 120)
endif()
add_dependencies(test_pdf docview-pdf-worker)
add_dependencies(test_archive docview-archive-worker)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Exercises the actual 10/30/120-second timers without shortening the
# production budgets. Run explicitly, or opt in to the long CTest case.
add_executable(test_worker_deadlines tests/test_worker_deadlines.cpp)
target_link_libraries(test_worker_deadlines PRIVATE docview_common Qt6::Test)
option(DOCVIEW_ENABLE_LONG_TESTS "Register real-time worker watchdog tests" OFF)
if(DOCVIEW_ENABLE_LONG_TESTS)
add_test(NAME worker_deadlines COMMAND test_worker_deadlines)
set_tests_properties(worker_deadlines PROPERTIES TIMEOUT 150 LABELS "long")
endif()
endif()
add_executable(test_pdf_canvas tests/test_pdf_canvas.cpp src/app/pdf_canvas.cpp)
target_link_libraries(test_pdf_canvas PRIVATE docview_pdf docview_common docview_font_broker Qt6::Test Qt6::Quick Qt6::Gui)
add_dependencies(test_pdf_canvas docview-pdf-worker)
add_test(NAME pdf_canvas COMMAND test_pdf_canvas)
set_tests_properties(pdf_canvas PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
add_test(NAME pdf_canvas_hidpi COMMAND test_pdf_canvas annotationFlagsHitTargetsMatchRenderedPixels sceneGraphPresentsPdfPixelsAndReplacesOldPage)
set_tests_properties(pdf_canvas_hidpi PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen;QT_SCALE_FACTOR=2")
qt_add_executable(test_app tests/test_app.cpp ${DOCVIEW_SHELL_SOURCES})
target_link_libraries(test_app PRIVATE docview_core docview_common docview_font_broker Qt6::Gui Qt6::Quick Qt6::Qml Qt6::QuickControls2 Qt6::WebEngineQuick Qt6::Test ${DOCVIEW_ZIP_TARGET})
target_compile_definitions(test_app PRIVATE DOCVIEW_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_dependencies(test_app docview-pdf-worker docview-archive-worker)
add_test(NAME app COMMAND test_app)
qt_add_executable(test_web_qml tests/test_web_qml.cpp src/web/web_profile.cpp resources.qrc)
target_link_libraries(test_web_qml PRIVATE docview_common Qt6::Gui Qt6::Quick Qt6::Qml Qt6::WebEngineQuick Qt6::QuickTest Qt6::Test)
add_test(NAME web COMMAND test_web_qml)
set_tests_properties(app web PROPERTIES TIMEOUT 90)
endif()