From 5406b3022a4af8b2ff2c6dcd814b8a986dc720ad Mon Sep 17 00:00:00 2001 From: shenleban tongying Date: Fri, 22 Nov 2024 16:50:55 -0500 Subject: [PATCH] dev: generally improve cmake build script --- CMakeLists.txt | 243 ++++------------------------------- cmake/Deps_Unix.cmake | 18 +-- cmake/Package_Linux.cmake | 22 ++++ cmake/Package_Windows.cmake | 55 ++++++++ cmake/Package_macOS.cmake | 69 ++++++++++ src/config.cc | 4 +- src/config.hh | 4 +- src/dict/epwing.cc | 2 +- src/dict/epwing_book.cc | 2 +- src/dict/epwing_charmap.cc | 2 +- src/dict/hunspell.cc | 7 +- src/dict/loaddictionaries.cc | 8 +- src/dict/sources.cc | 6 +- src/dict/sources.hh | 4 +- src/dict/voiceengines.cc | 2 +- src/dict/voiceengines.hh | 2 +- src/main.cc | 2 +- src/speechclient.cc | 2 +- src/speechclient.hh | 2 +- src/texttospeechsource.cc | 2 +- src/texttospeechsource.hh | 2 +- src/ui/articleview.cc | 2 +- src/ui/editdictionaries.cc | 4 +- src/ui/mainwindow.cc | 6 +- src/ui/preferences.cc | 2 +- src/version.hh | 8 +- 26 files changed, 215 insertions(+), 267 deletions(-) create mode 100644 cmake/Package_Linux.cmake create mode 100644 cmake/Package_Windows.cmake create mode 100644 cmake/Package_macOS.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index dc1ed9dfa..94dc6166e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.25) # ubuntu 23.04 Fedora 36 +cmake_minimum_required(VERSION 3.25) # Debian 11 Ubuntu 24.04 Fedora 36 option(WITH_FFMPEG_PLAYER "Enable support for FFMPEG player" ON) option(WITH_EPWING_SUPPORT "Enable epwing support" ON) @@ -9,20 +9,12 @@ option(WITH_TTS "enable QTexttoSpeech support" OFF) option(USE_SYSTEM_FMT "use system fmt instead of bundled one" OFF) option(USE_SYSTEM_TOML "use system toml++ instead of bundled one" OFF) -option(WITH_VCPKG_BREAKPAD "build with Breakpad support for VCPKG build only" 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 -## 2. There are icon themes that assuming the icon name to be "goldendict" -> invalidate the GD icon when using a icon theme -## 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 - +## This should be avoided because of small regressions, as some scripts and icons themes assume the binary name and resources folder to be `goldendict` +option(USE_ALTERNATIVE_NAME "For Linux, change the binary name and resource folder to goldendict-ng to parallel install with the original GD" OFF) # vcpkg handling code, must be placed before project() if (WIN32) + option(WITH_VCPKG_BREAKPAD "build with Breakpad support for VCPKG build only" OFF) if (DEFINED CMAKE_TOOLCHAIN_FILE) message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}") else () @@ -37,11 +29,9 @@ if (WIN32) set(VCPKG_MANIFEST_MODE OFF CACHE BOOL "disable existing manifest mode caused by the existrance of vcpkg.json" FORCE) set(CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/_deps/vcpkg-export-src/scripts/buildsystems/vcpkg.cmake") endif () -endif () - - -if (WITH_VCPKG_BREAKPAD) - list(APPEND VCPKG_MANIFEST_FEATURES "breakpad") + if (WITH_VCPKG_BREAKPAD) + list(APPEND VCPKG_MANIFEST_FEATURES "breakpad") + endif () endif () include(FeatureSummary) @@ -49,7 +39,7 @@ include(FeatureSummary) project(goldendict-ng VERSION 24.11.0 LANGUAGES CXX C) - + if (APPLE) enable_language(OBJCXX) set(CMAKE_OBJCXX_STANDARD 17) @@ -60,13 +50,12 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(GOLDENDICT "goldendict") # binary/executable name -if (USE_ALTERNATIVE_NAME ) +if (USE_ALTERNATIVE_NAME) set(GOLDENDICT "goldendict-ng") endif () if (APPLE) set(GOLDENDICT "GoldenDict-ng") -endif() - +endif () #### Qt @@ -78,11 +67,10 @@ endif () find_package(Qt6 REQUIRED COMPONENTS ${GD_QT_COMPONENTS}) -qt_standard_project_setup() # availiable after find_package(Qt6 .... Core +qt_standard_project_setup() set(CMAKE_AUTORCC ON) # not included in the qt_standard_project_setup #### Things required during configuration - block() # generate version.txt string(TIMESTAMP build_time UTC) find_package(Git) @@ -163,11 +151,8 @@ target_link_libraries(${GOLDENDICT} PRIVATE Qt6::WebEngineWidgets Qt6::Widgets Qt6::Svg - ) - -if (WITH_TTS) - target_link_libraries(${GOLDENDICT} PRIVATE Qt6::TextToSpeech) -endif () + $<$:Qt6::TextToSpeech> +) target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/qtsingleapplication/src @@ -176,11 +161,7 @@ target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/src/dict ${PROJECT_SOURCE_DIR}/src/dict/utils ${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) @@ -199,45 +180,22 @@ target_compile_definitions(${GOLDENDICT} PRIVATE ) target_compile_definitions(${GOLDENDICT} PUBLIC - CMAKE_USED_HACK # temporal hack to avoid breaking qmake build MAKE_QTMULTIMEDIA_PLAYER 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 () - -if(NOT WITH_TTS) - target_compile_definitions(${GOLDENDICT} PUBLIC NO_TTS_SUPPORT) -endif() - - -if (NOT WITH_EPWING_SUPPORT) - target_compile_definitions(${GOLDENDICT} PUBLIC NO_EPWING_SUPPORT) -endif () - -if (WITH_ZIM) - target_compile_definitions(${GOLDENDICT} PUBLIC MAKE_ZIM_SUPPORT) -endif () - -if (WITH_VCPKG_BREAKPAD) - target_compile_definitions(${GOLDENDICT} PUBLIC USE_BREAKPAD) -endif () + $<$:__WIN32> + $<$:MAKE_FFMPEG_PLAYER> + $<$:TTS_SUPPORT> + $<$:EPWING_SUPPORT> + $<$:MAKE_ZIM_SUPPORT> + $<$:USE_BREAKPAD> +) #### libraries linking && includes for Win or Unix if (WIN32) - include(Deps_Vcpkg) + include(cmake/Deps_Vcpkg.cmake) else () - include(Deps_Unix) + include(cmake/Deps_Unix.cmake) endif () #### add translations @@ -261,156 +219,11 @@ add_dependencies(${GOLDENDICT} "release_translations") #### installation or assemble redistribution if (APPLE) - set(PLIST_FILE "${CMAKE_BINARY_DIR}/info_generated.plist") - configure_file("${CMAKE_SOURCE_DIR}/redist/mac_info_plist_template_cmake.plist" "${PLIST_FILE}" @ONLY) - - set_target_properties(${GOLDENDICT} PROPERTIES - MACOSX_BUNDLE TRUE - MACOSX_BUNDLE_INFO_PLIST "${PLIST_FILE}" - ) - - set(Assembling_Dir "${CMAKE_BINARY_DIR}/redist") - set(App_Name "${GOLDENDICT}.app") - set(Redistributable_APP "${Assembling_Dir}/${App_Name}") - - # if anything wrong, delete this and affect lines, and see what's Qt will generate by default. - set(QtConfPath "${Redistributable_APP}/Contents/Resources/qt.conf") - - qt_generate_deploy_script( - TARGET ${GOLDENDICT} - OUTPUT_SCRIPT deploy_script - CONTENT " - set(QT_DEPLOY_PREFIX \"${Redistributable_APP}\") - set(QT_DEPLOY_TRANSLATIONS_DIR \"Contents/Resources/translations\") - qt_deploy_runtime_dependencies( - EXECUTABLE \"${Redistributable_APP}\" - ADDITIONAL_LIBRARIES ${BREW_ICU_ADDITIONAL_DYLIBS} - GENERATE_QT_CONF - NO_APP_STORE_COMPLIANCE) - qt_deploy_translations() - qt_deploy_qt_conf(\"${QtConfPath}\" - PLUGINS_DIR PlugIns - TRANSLATIONS_DIR Resources/translations) - " - ) - - install(TARGETS ${GOLDENDICT} BUNDLE DESTINATION "${Assembling_Dir}") - install(FILES ${qm_files} DESTINATION "${Redistributable_APP}/Contents/MacOS/locale") - - if (IS_READABLE "/opt/homebrew/share/opencc/") - set(OPENCC_DATA_PATH "/opt/homebrew/share/opencc/" CACHE PATH "opencc's data path") - elseif (IS_READABLE "/usr/local/share/opencc/") - set(OPENCC_DATA_PATH "/usr/local/share/opencc/" CACHE PATH "opencc's data path") - else () - message(FATAL_ERROR "Cannot find opencc's data folder!") - endif () - - file(REAL_PATH "${OPENCC_DATA_PATH}" OPENCC_DATA_PATH_FOR_REAL) - - message(STATUS "OPENCC data is found -> ${OPENCC_DATA_PATH_FOR_REAL}") - install(DIRECTORY "${OPENCC_DATA_PATH_FOR_REAL}" DESTINATION "${Redistributable_APP}/Contents/MacOS") - - install(SCRIPT ${deploy_script}) - - install(CODE "execute_process(COMMAND codesign --force --deep -s - ${Redistributable_APP})") - - find_program(CREATE-DMG "create-dmg") - if (CREATE-DMG) - install(CODE " - execute_process(COMMAND ${CREATE-DMG} \ - --skip-jenkins \ - --format \"ULMO\" - --volname ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR} \ - --volicon ${CMAKE_SOURCE_DIR}/icons/macicon.icns \ - --icon \"${App_Name}\" 100 100 - --app-drop-link 300 100 \ - \"GoldenDict-ng-${CMAKE_PROJECT_VERSION}-Qt${Qt6_VERSION}-macOS-${CMAKE_SYSTEM_PROCESSOR}.dmg\" \ - \"${Assembling_Dir}\")" - ) - else () - message(WARNING "create-dmg not found. No .dmg will be created") - endif () - -endif () - -if (LINUX OR BSD) - install(TARGETS ${GOLDENDICT}) - install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop DESTINATION share/applications) - install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.metainfo.xml DESTINATION share/metainfo) - - if (NOT USE_ALTERNATIVE_NAME) - # see: config.cc -> getProgramDataDir - add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict") - install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps) - install(FILES ${qm_files} DESTINATION share/goldendict/locale) - else () - add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict-ng") - install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps - RENAME goldendict-ng.png) - install(FILES ${qm_files} DESTINATION share/goldendict-ng/locale) - - block() # patch the desktop file to adapt the binary & icon file's name change - file(READ "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" DESKTOP_FILE_CONTENT) - string(REGEX REPLACE "\nIcon=goldendict\n" "\nIcon=goldendict-ng\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}") - string(REGEX REPLACE "\nExec=goldendict %u\n" "\nExec=goldendict-ng %u\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}") - file(WRITE "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" "${DESKTOP_FILE_CONTENT}") - endblock() - endif () -endif () - -if (WIN32) - - set_target_properties(${GOLDENDICT} - PROPERTIES - WIN32_EXECUTABLE TRUE - RUNTIME_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}" - LIBRARY_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}" - ) - - 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) - - 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 .) - - # 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 "GoldenDict-ng-${PROJECT_VERSION}-Qt${Qt6Widgets_VERSION}") - set(CPACK_GENERATOR "7Z;NSIS64") - - # override the default install path, which is $PROGRAMFILES64\${project-name} ${project-version} in NSIS - set(CPACK_PACKAGE_INSTALL_DIRECTORY "GoldenDict-ng") - - # NSIS specificS - set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) - set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/icons/programicon.ico") - set(CPACK_NSIS_PACKAGE_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}") - set(CPACK_NSIS_DISPLAY_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}") - set(CPACK_NSIS_URL_INFO_ABOUT [=[https://xiaoyifang.github.io/goldendict-ng/]=]) - set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GoldenDict-ng.lnk' '$INSTDIR\\\\${GOLDENDICT}.exe'") - set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\GoldenDict-ng.lnk'") - - include(CPack) + include(cmake/Package_macOS.cmake) +elseif (LINUX OR BSD) + include(cmake/Package_Linux.cmake) +elseif (WIN32) + include(cmake/Package_Windows.cmake) endif () feature_summary(WHAT ALL DESCRIPTION "Build configuration:") diff --git a/cmake/Deps_Unix.cmake b/cmake/Deps_Unix.cmake index bf936fafc..f5a0ea193 100644 --- a/cmake/Deps_Unix.cmake +++ b/cmake/Deps_Unix.cmake @@ -1,5 +1,4 @@ #### Various workarounds - if (APPLE) # old & new homebrew's include paths target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include) @@ -29,25 +28,20 @@ endif () ##### Finding packages from package manager find_package(PkgConfig REQUIRED) -find_package(ZLIB REQUIRED) find_package(BZip2 REQUIRED) - -# Consider all PkgConfig dependencies as one -pkg_check_modules(PKGCONFIG_DEPS IMPORTED_TARGET +# Import all PkgConfig dependencies as one +pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET hunspell + liblzma lzo2 opencc vorbis # .ogg vorbisfile - liblzma xapian-core + zlib ) -target_link_libraries(${GOLDENDICT} PRIVATE - PkgConfig::PKGCONFIG_DEPS - BZip2::BZip2 - ZLIB::ZLIB -) +target_link_libraries(${GOLDENDICT} PRIVATE PkgConfig::DEPS BZip2::BZip2) # On FreeBSD, there are two iconv, libc iconv & GNU libiconv. # The system one is good enough, the following is a workaround to use libc iconv on freeBSD. @@ -88,7 +82,7 @@ if (WITH_ZIM) COMMAND_ERROR_IS_FATAL ANY) message(STATUS "Found correct homebrew icu path -> ${ICU_REQUIRED_BY_ZIM_PREFIX}") set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${ICU_REQUIRED_BY_ZIM_PREFIX}/lib/pkgconfig") - message(STATUS "Updated pkg_config_path -> $ENV{PKG_CONFIG_PATH}:${ICU_REQUIRED_BY_ZIM_PREFIX}/lib/pkgconfig") + message(STATUS "Updated pkg_config_path -> $ENV{PKG_CONFIG_PATH}") # icu4c as transitive dependency of libzim may not be automatically copied into app bundle # so we manually discover the icu4c from homebrew, then find the relevent dylibs diff --git a/cmake/Package_Linux.cmake b/cmake/Package_Linux.cmake new file mode 100644 index 000000000..0475eb88e --- /dev/null +++ b/cmake/Package_Linux.cmake @@ -0,0 +1,22 @@ +install(TARGETS ${GOLDENDICT}) +install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop DESTINATION share/applications) +install(FILES ${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.metainfo.xml DESTINATION share/metainfo) + +if (NOT USE_ALTERNATIVE_NAME) + # see: config.cc -> getProgramDataDir + add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict") + install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps) + install(FILES ${qm_files} DESTINATION share/goldendict/locale) +else () + add_compile_definitions(PROGRAM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/goldendict-ng") + install(FILES ${CMAKE_SOURCE_DIR}/redist/icons/goldendict.png DESTINATION share/pixmaps + RENAME goldendict-ng.png) + install(FILES ${qm_files} DESTINATION share/goldendict-ng/locale) + + block() # patch the desktop file to adapt the binary & icon file's name change + file(READ "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" DESKTOP_FILE_CONTENT) + string(REGEX REPLACE "\nIcon=goldendict\n" "\nIcon=goldendict-ng\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}") + string(REGEX REPLACE "\nExec=goldendict %u\n" "\nExec=goldendict-ng %u\n" DESKTOP_FILE_CONTENT "${DESKTOP_FILE_CONTENT}") + file(WRITE "${CMAKE_SOURCE_DIR}/redist/io.github.xiaoyifang.goldendict_ng.desktop" "${DESKTOP_FILE_CONTENT}") + endblock() +endif () diff --git a/cmake/Package_Windows.cmake b/cmake/Package_Windows.cmake new file mode 100644 index 000000000..3d4a7dee9 --- /dev/null +++ b/cmake/Package_Windows.cmake @@ -0,0 +1,55 @@ +set_target_properties(${GOLDENDICT} + PROPERTIES + WIN32_EXECUTABLE TRUE + RUNTIME_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${GD_WIN_OUTPUT_DIR}" +) + +# TODO: this breaks "Multi-Config" build systems like VisualStudio. +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) + +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 .) +# Note: This is runtime dependency that aren't copied automatically +# See Qt's network -> SSDL documentation https://doc.qt.io/qt-6/ssl.html#considerations-while-packaging-your-application +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 .) + +# 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 "GoldenDict-ng-${PROJECT_VERSION}-Qt${Qt6Widgets_VERSION}") +set(CPACK_GENERATOR "7Z;NSIS64") + +# override the default install path, which is $PROGRAMFILES64\${project-name} ${project-version} in NSIS +set(CPACK_PACKAGE_INSTALL_DIRECTORY "GoldenDict-ng") + +# NSIS specificS +set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) +set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/icons/programicon.ico") +set(CPACK_NSIS_PACKAGE_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}") +set(CPACK_NSIS_DISPLAY_NAME "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}") + +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") + +# Copied from https://crascit.com/2015/08/07/cmake_cpack_nsis_shortcuts_with_parameters/ +set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GoldenDict-ng.lnk' '$INSTDIR\\\\${GOLDENDICT}.exe'") +set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\GoldenDict-ng.lnk'") + +include(CPack) diff --git a/cmake/Package_macOS.cmake b/cmake/Package_macOS.cmake new file mode 100644 index 000000000..b8ef10891 --- /dev/null +++ b/cmake/Package_macOS.cmake @@ -0,0 +1,69 @@ +set(PLIST_FILE "${CMAKE_BINARY_DIR}/info_generated.plist") +configure_file("${CMAKE_SOURCE_DIR}/redist/mac_info_plist_template_cmake.plist" "${PLIST_FILE}" @ONLY) + +set_target_properties(${GOLDENDICT} PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${PLIST_FILE}" +) + +set(Assembling_Dir "${CMAKE_BINARY_DIR}/redist") +set(App_Name "${GOLDENDICT}.app") +set(Redistributable_APP "${Assembling_Dir}/${App_Name}") + +# if anything wrong, delete this and affect lines, and see what's Qt will generate by default. +set(QtConfPath "${Redistributable_APP}/Contents/Resources/qt.conf") + +qt_generate_deploy_script( + TARGET ${GOLDENDICT} + OUTPUT_SCRIPT deploy_script + CONTENT " + set(QT_DEPLOY_PREFIX \"${Redistributable_APP}\") + set(QT_DEPLOY_TRANSLATIONS_DIR \"Contents/Resources/translations\") + qt_deploy_runtime_dependencies( + EXECUTABLE \"${Redistributable_APP}\" + ADDITIONAL_LIBRARIES ${BREW_ICU_ADDITIONAL_DYLIBS} + GENERATE_QT_CONF + NO_APP_STORE_COMPLIANCE) + qt_deploy_translations() + qt_deploy_qt_conf(\"${QtConfPath}\" + PLUGINS_DIR PlugIns + TRANSLATIONS_DIR Resources/translations) + " +) + +install(TARGETS ${GOLDENDICT} BUNDLE DESTINATION "${Assembling_Dir}") +install(FILES ${qm_files} DESTINATION "${Redistributable_APP}/Contents/MacOS/locale") + +if (IS_READABLE "/opt/homebrew/share/opencc/") + set(OPENCC_DATA_PATH "/opt/homebrew/share/opencc/" CACHE PATH "opencc's data path") +elseif (IS_READABLE "/usr/local/share/opencc/") + set(OPENCC_DATA_PATH "/usr/local/share/opencc/" CACHE PATH "opencc's data path") +else () + message(FATAL_ERROR "Cannot find opencc's data folder!") +endif () + +file(REAL_PATH "${OPENCC_DATA_PATH}" OPENCC_DATA_PATH_FOR_REAL) + +message(STATUS "OPENCC data is found -> ${OPENCC_DATA_PATH_FOR_REAL}") +install(DIRECTORY "${OPENCC_DATA_PATH_FOR_REAL}" DESTINATION "${Redistributable_APP}/Contents/MacOS") + +install(SCRIPT ${deploy_script}) + +install(CODE "execute_process(COMMAND codesign --force --deep -s - ${Redistributable_APP})") + +find_program(CREATE-DMG "create-dmg") +if (CREATE-DMG) + install(CODE " + execute_process(COMMAND ${CREATE-DMG} \ + --skip-jenkins \ + --format \"ULMO\" + --volname ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_PROCESSOR} \ + --volicon ${CMAKE_SOURCE_DIR}/icons/macicon.icns \ + --icon \"${App_Name}\" 100 100 + --app-drop-link 300 100 \ + \"GoldenDict-ng-${CMAKE_PROJECT_VERSION}-Qt${Qt6_VERSION}-macOS-${CMAKE_SYSTEM_PROCESSOR}.dmg\" \ + \"${Assembling_Dir}\")" + ) +else () + message(WARNING "create-dmg not found. No .dmg will be created") +endif () diff --git a/src/config.cc b/src/config.cc index 6260e73b2..e2eaeee51 100644 --- a/src/config.cc +++ b/src/config.cc @@ -800,7 +800,7 @@ Class load() // Upgrading c.dictServers = makeDefaultDictServers(); } -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT QDomNode ves = root.namedItem( "voiceEngines" ); if ( !ves.isNull() ) { @@ -1684,7 +1684,7 @@ void save( Class const & c ) p.setAttributeNode( icon ); } } -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT { QDomNode ves = dd.createElement( "voiceEngines" ); root.appendChild( ves ); diff --git a/src/config.hh b/src/config.hh index cc9d4b756..3c6920852 100644 --- a/src/config.hh +++ b/src/config.hh @@ -725,7 +725,7 @@ struct Program using Programs = QList< Program >; -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT struct VoiceEngine { bool enabled; @@ -818,7 +818,7 @@ struct Class Lingua lingua; Forvo forvo; Programs programs; -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT VoiceEngines voiceEngines; #endif diff --git a/src/dict/epwing.cc b/src/dict/epwing.cc index 69b41df00..c6f020b01 100644 --- a/src/dict/epwing.cc +++ b/src/dict/epwing.cc @@ -1,7 +1,7 @@ /* This file is (c) 2014 Abs62 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ #include -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT #include "epwing_book.hh" #include "epwing.hh" diff --git a/src/dict/epwing_book.cc b/src/dict/epwing_book.cc index 9de62270b..159c42b7d 100644 --- a/src/dict/epwing_book.cc +++ b/src/dict/epwing_book.cc @@ -1,7 +1,7 @@ /* This file is (c) 2014 Abs62 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT #include "epwing_book.hh" diff --git a/src/dict/epwing_charmap.cc b/src/dict/epwing_charmap.cc index ffad9584d..2fb823208 100644 --- a/src/dict/epwing_charmap.cc +++ b/src/dict/epwing_charmap.cc @@ -1,7 +1,7 @@ /* This file is (c) 2014 Abs62 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT #include "epwing_charmap.hh" diff --git a/src/dict/hunspell.cc b/src/dict/hunspell.cc index 1e67f6dc5..8478eff11 100644 --- a/src/dict/hunspell.cc +++ b/src/dict/hunspell.cc @@ -15,12 +15,7 @@ #include #include "utils.hh" #include - -#ifndef INCLUDE_LIBRARY_PATH - #include -#else - #include -#endif +#include namespace HunspellMorpho { diff --git a/src/dict/loaddictionaries.cc b/src/dict/loaddictionaries.cc index 6ada3840a..fc94b1939 100644 --- a/src/dict/loaddictionaries.cc +++ b/src/dict/loaddictionaries.cc @@ -34,7 +34,7 @@ #include "dict/transliteration/romaji.hh" #include "dict/transliteration/russian.hh" -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT #include "dict/epwing.hh" #endif @@ -83,7 +83,7 @@ LoadDictionaries::LoadDictionaries( Config::Class const & cfg ): << "*.zim" << "*.zimaa" #endif -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT << "*catalogs" #endif ; @@ -181,7 +181,7 @@ void LoadDictionaries::handlePath( Config::Path const & path ) #ifdef MAKE_ZIM_SUPPORT addDicts( Zim::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) ); #endif -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT addDicts( Epwing::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) ); #endif } @@ -274,7 +274,7 @@ void loadDictionaries( QWidget * parent, addDicts( Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr ) ); addDicts( Lingua::makeDictionaries( loadDicts, cfg.lingua, dictNetMgr ) ); addDicts( Programs::makeDictionaries( cfg.programs ) ); -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT addDicts( VoiceEngines::makeDictionaries( cfg.voiceEngines ) ); #endif addDicts( DictServer::makeDictionaries( cfg.dictServers ) ); diff --git a/src/dict/sources.cc b/src/dict/sources.cc index 7c3a655a4..b7efcd34b 100644 --- a/src/dict/sources.cc +++ b/src/dict/sources.cc @@ -16,7 +16,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ): #ifdef MAKE_CHINESE_CONVERSION_SUPPORT chineseConversion( new ChineseConversion( this, cfg.transliteration.chinese ) ), #endif -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT textToSpeechSource( nullptr ), #endif itemDelegate( new QItemDelegate( this ) ), @@ -129,7 +129,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ): ui.forvoLanguageCodes->setText( forvo.languageCodes ); // Text to speech -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT if ( !cfg.notts ) { textToSpeechSource = new TextToSpeechSource( this, cfg.voiceEngines ); ui.tabWidget->addTab( textToSpeechSource, QIcon( ":/icons/text2speech.svg" ), tr( "Text to Speech" ) ); @@ -325,7 +325,7 @@ void Sources::on_removeProgram_clicked() } } -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT Config::VoiceEngines Sources::getVoiceEngines() const { if ( !textToSpeechSource ) diff --git a/src/dict/sources.hh b/src/dict/sources.hh index e72327503..7dab12941 100644 --- a/src/dict/sources.hh +++ b/src/dict/sources.hh @@ -295,7 +295,7 @@ public: { return programsModel.getCurrentPrograms(); } -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT Config::VoiceEngines getVoiceEngines() const; #endif Config::Hunspell getHunspell() const; @@ -317,7 +317,7 @@ private: #ifdef MAKE_CHINESE_CONVERSION_SUPPORT ChineseConversion * chineseConversion; #endif -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT TextToSpeechSource * textToSpeechSource; #endif QItemDelegate * itemDelegate; diff --git a/src/dict/voiceengines.cc b/src/dict/voiceengines.cc index 26c307d39..8e01138bb 100644 --- a/src/dict/voiceengines.cc +++ b/src/dict/voiceengines.cc @@ -1,6 +1,6 @@ /* This file is (c) 2013 Timon Wong * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include "voiceengines.hh" #include "audiolink.hh" diff --git a/src/dict/voiceengines.hh b/src/dict/voiceengines.hh index b535a1a5e..17e9a8e3d 100644 --- a/src/dict/voiceengines.hh +++ b/src/dict/voiceengines.hh @@ -1,7 +1,7 @@ /* This file is (c) 2013 Timon Wong * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ #pragma once -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include "dictionary.hh" #include "config.hh" diff --git a/src/main.cc b/src/main.cc index 480a877b0..7125cd582 100644 --- a/src/main.cc +++ b/src/main.cc @@ -510,7 +510,7 @@ int main( int argc, char ** argv ) if ( gdcl.notts ) { cfg.notts = true; -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT cfg.voiceEngines.clear(); #endif } diff --git a/src/speechclient.cc b/src/speechclient.cc index f66bea2c8..77955a0a8 100644 --- a/src/speechclient.cc +++ b/src/speechclient.cc @@ -1,4 +1,4 @@ -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include "speechclient.hh" diff --git a/src/speechclient.hh b/src/speechclient.hh index db2f368dc..629e1d578 100644 --- a/src/speechclient.hh +++ b/src/speechclient.hh @@ -1,5 +1,5 @@ #pragma once -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include #include "config.hh" diff --git a/src/texttospeechsource.cc b/src/texttospeechsource.cc index bb1c0773d..e96a2e8ff 100644 --- a/src/texttospeechsource.cc +++ b/src/texttospeechsource.cc @@ -1,6 +1,6 @@ /* This file is (c) 2013 Timon Wong * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include "texttospeechsource.hh" #include diff --git a/src/texttospeechsource.hh b/src/texttospeechsource.hh index c178d86f7..4d0b37928 100644 --- a/src/texttospeechsource.hh +++ b/src/texttospeechsource.hh @@ -3,7 +3,7 @@ #pragma once -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT #include "ui_texttospeechsource.h" #include "config.hh" diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index cda8d115c..9c633241a 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -1048,7 +1048,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const & QMessageBox::critical( this, "GoldenDict", tr( "The referenced audio program doesn't exist." ) ); } else if ( url.scheme() == "gdtts" ) { -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT // Text to speech QString md5Id = Utils::Url::queryItemValue( url, "engine" ); QString text( url.path().mid( 1 ) ); diff --git a/src/ui/editdictionaries.cc b/src/ui/editdictionaries.cc index 01af97e4c..e5357328b 100644 --- a/src/ui/editdictionaries.cc +++ b/src/ui/editdictionaries.cc @@ -173,7 +173,7 @@ bool EditDictionaries::isSourcesChanged() const || sources.getLingua() != cfg.lingua || sources.getForvo() != cfg.forvo || sources.getMediaWikis() != cfg.mediawikis || sources.getWebSites() != cfg.webSites || sources.getDictServers() != cfg.dictServers || sources.getPrograms() != cfg.programs -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT || sources.getVoiceEngines() != cfg.voiceEngines #endif ; @@ -197,7 +197,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups ) cfg.webSites = sources.getWebSites(); cfg.dictServers = sources.getDictServers(); cfg.programs = sources.getPrograms(); -#ifndef NO_TTS_SUPPORT +#ifdef TTS_SUPPORT cfg.voiceEngines = sources.getVoiceEngines(); #endif setUpdatesEnabled( false ); diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 3dec04536..35f8862d2 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -3,7 +3,7 @@ #include #include -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT #include "dict/epwing_book.hh" #endif @@ -209,7 +209,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): + " GoldenDict/WebEngine" ); } -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT Epwing::initialize(); #endif @@ -1173,7 +1173,7 @@ MainWindow::~MainWindow() scanPopup = nullptr; } -#ifndef NO_EPWING_SUPPORT +#ifdef EPWING_SUPPORT Epwing::finalize(); #endif } diff --git a/src/ui/preferences.cc b/src/ui/preferences.cc index becbe5b29..af949f809 100644 --- a/src/ui/preferences.cc +++ b/src/ui/preferences.cc @@ -390,7 +390,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): #ifndef MAKE_ZIM_SUPPORT ui.allowZim->hide(); #endif -#ifdef NO_EPWING_SUPPORT +#ifndef EPWING_SUPPORT ui.allowEpwing->hide(); #endif ui.maxDictionarySize->setValue( p.fts.maxDictionarySize ); diff --git a/src/version.hh b/src/version.hh index 1b3d181d8..b5e54add3 100644 --- a/src/version.hh +++ b/src/version.hh @@ -8,8 +8,8 @@ const QLatin1String flags = QLatin1String( #ifdef MAKE_ZIM_SUPPORT " MAKE_ZIM_SUPPORT" #endif -#ifdef NO_EPWING_SUPPORT - " NO_EPWING_SUPPORT" +#ifdef EPWING_SUPPORT + " EPWING_SUPPORT" #endif #ifdef USE_ICONV " USE_ICONV" @@ -17,8 +17,8 @@ const QLatin1String flags = QLatin1String( #ifdef MAKE_CHINESE_CONVERSION_SUPPORT " MAKE_CHINESE_CONVERSION_SUPPORT" #endif -#ifdef NO_TTS_SUPPORT - " NO_TTS_SUPPORT" +#ifdef TTS_SUPPORT + " TTS_SUPPORT" #endif #ifndef MAKE_FFMPEG_PLAYER " no_ffmpeg_player"