diff --git a/CMakeLists.txt b/CMakeLists.txt index aa806973..93b49bdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.25) # ubuntu 23.04 Fedora 36 -# Qt6.4+ only - option(WITH_FFMPEG_PLAYER "Enable support for FFMPEG player" ON) option(WITH_EPWING_SUPPORT "Enable epwing support" ON) option(WITH_ZIM "enable zim support" ON) @@ -11,6 +9,9 @@ option(WITH_TTS "enable QTexttoSpeech support" ON) option(USE_SYSTEM_FMT "use system fmt instead of bundled one" OFF) option(USE_SYSTEM_TOML "use system toml++ instead of bundled one" OFF) +# vcpkg build - only tested on Windows, does not support FFMPEG +option(USE_VCPKG "uses VCPKG for providing dependencies" OFF) + ## Change binary & resources folder to parallel install with original GD. ## This flag should be avoided because it leads to small regressions: ## 1. There are personal scripts assuming the binary name to be "goldendict" -> require everyone to change the name in their script @@ -18,6 +19,8 @@ option(USE_SYSTEM_TOML "use system toml++ instead of bundled one" OFF) ## 3. There are dictionary packages that install files to "/usr/share/goldendict/content" -> nullify the auto dict discovery option(USE_ALTERNATIVE_NAME "Force the name goldendict-ng " OFF) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") # to put staff in the ./cmake folder + include(FeatureSummary) project(goldendict-ng @@ -144,6 +147,10 @@ target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/src/ui ) +if (WIN32) + target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/src/windows) +endif () + if (NOT USE_SYSTEM_TOML) target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/tomlplusplus) endif () @@ -161,6 +168,13 @@ target_compile_definitions(${GOLDENDICT} PUBLIC MAKE_CHINESE_CONVERSION_SUPPORT ) +if (WIN32) + target_compile_definitions(${GOLDENDICT} PUBLIC + __WIN32 + INCLUDE_LIBRARY_PATH + ) +endif () + if (WITH_FFMPEG_PLAYER) target_compile_definitions(${GOLDENDICT} PUBLIC MAKE_FFMPEG_PLAYER) endif () @@ -180,10 +194,12 @@ endif () #### libraries linking && includes for Win or Unix -if (WIN32) - include(CMake_Win.cmake) +if (USE_VCPKG) + include(Deps_Vcpkg) +elseif (WIN32) + include(Deps_Win) else () - include(CMake_Unix.cmake) + include(Deps_Unix) endif () #### add translations @@ -197,9 +213,12 @@ if (WIN32) else () set_source_files_properties(${TRANS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/locale") endif () -# a wrapper over qt_add_lupdate and qt_add_lrelease + qt_add_translations(${GOLDENDICT} TS_FILES ${TRANS_FILES} QM_FILES_OUTPUT_VARIABLE qm_files) +if (WIN32) # TODO: check other OS + add_dependencies(${GOLDENDICT} "goldendict-ng_lrelease") +endif () #### installation or assemble redistribution @@ -279,6 +298,7 @@ if (LINUX OR BSD) endif () if (WIN32) + set_target_properties(${GOLDENDICT} PROPERTIES WIN32_EXECUTABLE TRUE @@ -286,27 +306,52 @@ if (WIN32) LIBRARY_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}" ) - add_custom_target(windeploy - COMMENT "Deploy everything to the output dir" - DEPENDS ${GOLDENDICT} # build this target will check if Goldendict.exe is already built - COMMAND ${WINDEPLOYQT_EXECUTABLE} --no-quick-import "${GD_WIN_OUTPUT_DIR}/${GOLDENDICT}.exe" --plugindir "${GD_WIN_OUTPUT_DIR}/plugins" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/opencc" "${GD_WIN_OUTPUT_DIR}/opencc" - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/LICENSE.txt" "${GD_WIN_OUTPUT_DIR}/LICENSE.txt" - COMMAND ${CMAKE_COMMAND} -E rm -f "${GD_WIN_OUTPUT_DIR}/goldendict.exe.manifest" "${GD_WIN_OUTPUT_DIR}/eb.dll.manifest" - WORKING_DIRECTORY ${GD_WIN_OUTPUT_DIR} - ) + if (NOT USE_VCPKG) + add_custom_target(windeploy + COMMENT "Deploy everything to the output dir" + DEPENDS ${GOLDENDICT} # build this target will check if Goldendict.exe is already built + COMMAND ${WINDEPLOYQT_EXECUTABLE} --no-quick-import "${GD_WIN_OUTPUT_DIR}/${GOLDENDICT}.exe" --plugindir "${GD_WIN_OUTPUT_DIR}/plugins" + COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/opencc" "${GD_WIN_OUTPUT_DIR}/opencc" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/LICENSE.txt" "${GD_WIN_OUTPUT_DIR}/LICENSE.txt" + COMMAND ${CMAKE_COMMAND} -E rm -f "${GD_WIN_OUTPUT_DIR}/goldendict.exe.manifest" "${GD_WIN_OUTPUT_DIR}/eb.dll.manifest" + WORKING_DIRECTORY ${GD_WIN_OUTPUT_DIR} + ) - # use CPack to make the output folder as NSIS installer - install( - DIRECTORY "${GD_WIN_OUTPUT_DIR}/" - DESTINATION . - ) + else () # VCPKG deploy + set(CMAKE_INSTALL_PREFIX "${GD_WIN_OUTPUT_DIR}" CACHE PATH "If you see this message, don't change this unless you want look into CMake build script. If you are an expert, yes, this is wrong. Help welcomed." FORCE) - set(CPACK_PACKAGE_FILE_NAME "${Qt6Widgets_VERSION}-${PROJECT_NAME}-${PROJECT_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") + qt_generate_deploy_script( + TARGET ${GOLDENDICT} + OUTPUT_SCRIPT deploy_script + CONTENT "qt_deploy_runtime_dependencies( + EXECUTABLE \"${CMAKE_INSTALL_PREFIX}/goldendict.exe\" + BIN_DIR . + LIB_DIR . + )" + ) + + install(SCRIPT ${deploy_script}) + install(DIRECTORY "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/opencc" DESTINATION .) + # TODO: do we really need to carry a copy of openSSL? + install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libssl-3-x64.dll" DESTINATION .) + install(FILES "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/libcrypto-3-x64.dll" DESTINATION .) + endif () + + # trick CPack to make the output folder as NSIS installer + install(DIRECTORY "${GD_WIN_OUTPUT_DIR}/" + DESTINATION . + FILES_MATCHING + PATTERN "*" + PATTERN "*.pdb" EXCLUDE + PATTERN "*.ilk" EXCLUDE) + + + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-Qt${Qt6Widgets_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") set(CPACK_GENERATOR "7Z;NSIS") set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") include(CPack) + endif () feature_summary(WHAT ALL DESCRIPTION "Build configuration:") diff --git a/CMake_Unix.cmake b/cmake/Deps_Unix.cmake similarity index 100% rename from CMake_Unix.cmake rename to cmake/Deps_Unix.cmake diff --git a/cmake/Deps_Vcpkg.cmake b/cmake/Deps_Vcpkg.cmake new file mode 100644 index 00000000..c189c23d --- /dev/null +++ b/cmake/Deps_Vcpkg.cmake @@ -0,0 +1,35 @@ +find_package(BZip2 REQUIRED) +find_package(Iconv REQUIRED) +find_package(LibLZMA REQUIRED) +find_package(Vorbis CONFIG REQUIRED) +find_package(ZLIB REQUIRED) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(PKGCONFIG_DEPS IMPORTED_TARGET + hunspell + libzim + lzo2 + opencc + xapian-core +) + +target_link_libraries(${GOLDENDICT} + PRIVATE + PkgConfig::PKGCONFIG_DEPS + BZip2::BZip2 + Iconv::Iconv + LibLZMA::LibLZMA + Vorbis::vorbis + Vorbis::vorbisfile + ZLIB::ZLIB +) + +if (WITH_EPWING_SUPPORT) + add_subdirectory(thirdparty/eb EXCLUDE_FROM_ALL) + target_include_directories(${GOLDENDICT} PRIVATE + thirdparty + ) + target_link_libraries(${GOLDENDICT} PRIVATE eb) + + set_target_properties(eb PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${GD_WIN_OUTPUT_DIR}) +endif () diff --git a/CMake_Win.cmake b/cmake/Deps_Win.cmake similarity index 94% rename from CMake_Win.cmake rename to cmake/Deps_Win.cmake index 354edd89..d0f33353 100644 --- a/CMake_Win.cmake +++ b/cmake/Deps_Win.cmake @@ -1,8 +1,3 @@ -target_compile_definitions(${GOLDENDICT} PUBLIC - __WIN32 - INCLUDE_LIBRARY_PATH # temporal hack to let singleapplication compile - ) - target_include_directories(${GOLDENDICT} PUBLIC ${CMAKE_SOURCE_DIR}/winlibs/include/ ) diff --git a/goldendict.pro b/goldendict.pro index bde67ec0..a095e477 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -166,7 +166,7 @@ win32 { } RC_ICONS += icons/programicon.ico icons/programicon_old.ico - INCLUDEPATH += winlibs/include + INCLUDEPATH += winlibs/include src/windows # Enable console in Debug mode on Windows, with useful logging messages Debug:CONFIG += console diff --git a/winlibs/include/stub_msvc.h b/src/windows/stub_msvc.h similarity index 93% rename from winlibs/include/stub_msvc.h rename to src/windows/stub_msvc.h index 6209dd21..34b8b684 100644 --- a/winlibs/include/stub_msvc.h +++ b/src/windows/stub_msvc.h @@ -1,15 +1,15 @@ -#include -#ifdef _MSC_VER -#if !defined(strcasecmp) -# define strcasecmp _strcmpi -#endif -#if !defined(strncasecmp) -# define strncasecmp _strnicmp -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -#define ssize_t long -#endif -#endif - +#include +#ifdef _MSC_VER +#if !defined(strcasecmp) +# define strcasecmp _strcmpi +#endif +#if !defined(strncasecmp) +# define strncasecmp _strnicmp +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +#define ssize_t long +#endif +#endif + diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 00000000..b09d8b94 --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,14 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "a1212c93cabaa9c5c36c1ffdb4bddd59fdf31e43", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ] +} diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 00000000..a471199d --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,17 @@ +{ + "name": "goldendict-ng", + "version": "24.5.5", + "dependencies": [ + "bzip2", + "hunspell", + "libiconv", + "liblzma", + "libvorbis", + "libzim", + "lzo", + "opencc", + "xapian", + "zlib", + "openssl" + ] +} diff --git a/website/docs/howto/build_from_source.md b/website/docs/howto/build_from_source.md index 33194ec0..2439ca44 100644 --- a/website/docs/howto/build_from_source.md +++ b/website/docs/howto/build_from_source.md @@ -64,21 +64,36 @@ Install Qt6(msvc) through the standard installer and pass Qt's path to CMake ``` -DCMAKE_PREFIX_PATH=F:\Qt\6.4.1\msvc2019_64 ``` - The built artifacts will end up in `build_dir/goldendict` -To run the built `goldendict.exe` directly, you have to add `F:\Qt\6.5.2\msvc2019_64\bin` to your PATH environment variable +#### Using pre-built winlibs -To have a redistributable goldendict (runable on someone else's computer by just copying the folder), you can build the deployment target which will copy necessary files to the folder +Use `windeploy` target to copy necessary runtime files. ``` cmake --build . --target windeploy ``` -The `build_dir/goldendict` will be ready to share with others. +Or you can also manually run `windeployqt.exe {your_build_dir}/goldendict.exe` which will copy the qt related things to `build_dir`. -Use`windeployqt.exe {your_build_dir}/goldendict.exe` which will copy the qt related `.dll` and other necessary files automatically. +#### Using Vcpkg +The dependencies can be built via Vcpkg instead of using the pre-built ones. + +Vcpkg CMake build utilize the "manifest mode", all you need to do is basically +set `CMAKE_TOOLCHAIN_FILE` as described [here](https://learn.microsoft.com/en-us/vcpkg/consume/manifest-mode?tabs=cmake%2Cbuild-MSBuild#2---integrate-vcpkg-with-your-build-system). + +Add this to cmake command: +```sh +-DUSE_VCPKG=ON +``` + +Most `.dll` built by vcpkg will be automatically copied, but the Qt ones won't. + +You can +* run `cmake --install .` (recommended) +* manually run windeployqt +* add `${Qt's install path}\Qt\6.5.2\msvc2019_64\bin` to your PATH environment variable ### macOS