dev: generally improve cmake build script
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run

This commit is contained in:
shenleban tongying 2024-11-22 16:50:55 -05:00 committed by GitHub
parent f446ad358f
commit 5406b3022a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 215 additions and 267 deletions

View file

@ -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_FFMPEG_PLAYER "Enable support for FFMPEG player" ON)
option(WITH_EPWING_SUPPORT "Enable epwing support" 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_FMT "use system fmt instead of bundled one" OFF)
option(USE_SYSTEM_TOML "use system toml++ 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) ## 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)
## 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
# vcpkg handling code, must be placed before project() # vcpkg handling code, must be placed before project()
if (WIN32) if (WIN32)
option(WITH_VCPKG_BREAKPAD "build with Breakpad support for VCPKG build only" OFF)
if (DEFINED CMAKE_TOOLCHAIN_FILE) if (DEFINED CMAKE_TOOLCHAIN_FILE)
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}") message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
else () 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(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") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/_deps/vcpkg-export-src/scripts/buildsystems/vcpkg.cmake")
endif () endif ()
endif () if (WITH_VCPKG_BREAKPAD)
if (WITH_VCPKG_BREAKPAD)
list(APPEND VCPKG_MANIFEST_FEATURES "breakpad") list(APPEND VCPKG_MANIFEST_FEATURES "breakpad")
endif ()
endif () endif ()
include(FeatureSummary) include(FeatureSummary)
@ -60,13 +50,12 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(GOLDENDICT "goldendict") # binary/executable name set(GOLDENDICT "goldendict") # binary/executable name
if (USE_ALTERNATIVE_NAME ) if (USE_ALTERNATIVE_NAME)
set(GOLDENDICT "goldendict-ng") set(GOLDENDICT "goldendict-ng")
endif () endif ()
if (APPLE) if (APPLE)
set(GOLDENDICT "GoldenDict-ng") set(GOLDENDICT "GoldenDict-ng")
endif() endif ()
#### Qt #### Qt
@ -78,11 +67,10 @@ endif ()
find_package(Qt6 REQUIRED COMPONENTS ${GD_QT_COMPONENTS}) 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 set(CMAKE_AUTORCC ON) # not included in the qt_standard_project_setup
#### Things required during configuration #### Things required during configuration
block() # generate version.txt block() # generate version.txt
string(TIMESTAMP build_time UTC) string(TIMESTAMP build_time UTC)
find_package(Git) find_package(Git)
@ -163,11 +151,8 @@ target_link_libraries(${GOLDENDICT} PRIVATE
Qt6::WebEngineWidgets Qt6::WebEngineWidgets
Qt6::Widgets Qt6::Widgets
Qt6::Svg Qt6::Svg
) $<$<BOOL:${WITH_TTS}>:Qt6::TextToSpeech>
)
if (WITH_TTS)
target_link_libraries(${GOLDENDICT} PRIVATE Qt6::TextToSpeech)
endif ()
target_include_directories(${GOLDENDICT} PRIVATE target_include_directories(${GOLDENDICT} PRIVATE
${PROJECT_SOURCE_DIR}/thirdparty/qtsingleapplication/src ${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
${PROJECT_SOURCE_DIR}/src/dict/utils ${PROJECT_SOURCE_DIR}/src/dict/utils
${PROJECT_SOURCE_DIR}/src/ui ${PROJECT_SOURCE_DIR}/src/ui
) )
if (WIN32)
target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/src/windows)
endif ()
if (NOT USE_SYSTEM_TOML) if (NOT USE_SYSTEM_TOML)
target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/tomlplusplus) target_include_directories(${GOLDENDICT} PRIVATE ${PROJECT_SOURCE_DIR}/thirdparty/tomlplusplus)
@ -199,45 +180,22 @@ target_compile_definitions(${GOLDENDICT} PRIVATE
) )
target_compile_definitions(${GOLDENDICT} PUBLIC target_compile_definitions(${GOLDENDICT} PUBLIC
CMAKE_USED_HACK # temporal hack to avoid breaking qmake build
MAKE_QTMULTIMEDIA_PLAYER MAKE_QTMULTIMEDIA_PLAYER
MAKE_CHINESE_CONVERSION_SUPPORT MAKE_CHINESE_CONVERSION_SUPPORT
) $<$<BOOL:${WIN32}>:__WIN32>
$<$<BOOL:${WITH_FFMPEG_PLAYER}>:MAKE_FFMPEG_PLAYER>
if (WIN32) $<$<BOOL:${WITH_TTS}>:TTS_SUPPORT>
target_compile_definitions(${GOLDENDICT} PUBLIC $<$<BOOL:${WITH_EPWING_SUPPORT}>:EPWING_SUPPORT>
__WIN32 $<$<BOOL:${WITH_ZIM}>:MAKE_ZIM_SUPPORT>
INCLUDE_LIBRARY_PATH $<$<BOOL:${WITH_VCPKG_BREAKPAD}>:USE_BREAKPAD>
) )
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 ()
#### libraries linking && includes for Win or Unix #### libraries linking && includes for Win or Unix
if (WIN32) if (WIN32)
include(Deps_Vcpkg) include(cmake/Deps_Vcpkg.cmake)
else () else ()
include(Deps_Unix) include(cmake/Deps_Unix.cmake)
endif () endif ()
#### add translations #### add translations
@ -261,156 +219,11 @@ add_dependencies(${GOLDENDICT} "release_translations")
#### installation or assemble redistribution #### installation or assemble redistribution
if (APPLE) if (APPLE)
set(PLIST_FILE "${CMAKE_BINARY_DIR}/info_generated.plist") include(cmake/Package_macOS.cmake)
configure_file("${CMAKE_SOURCE_DIR}/redist/mac_info_plist_template_cmake.plist" "${PLIST_FILE}" @ONLY) elseif (LINUX OR BSD)
include(cmake/Package_Linux.cmake)
set_target_properties(${GOLDENDICT} PROPERTIES elseif (WIN32)
MACOSX_BUNDLE TRUE include(cmake/Package_Windows.cmake)
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)
endif () endif ()
feature_summary(WHAT ALL DESCRIPTION "Build configuration:") feature_summary(WHAT ALL DESCRIPTION "Build configuration:")

View file

@ -1,5 +1,4 @@
#### Various workarounds #### Various workarounds
if (APPLE) if (APPLE)
# old & new homebrew's include paths # old & new homebrew's include paths
target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include) target_include_directories(${GOLDENDICT} PRIVATE /usr/local/include /opt/homebrew/include)
@ -29,25 +28,20 @@ endif ()
##### Finding packages from package manager ##### Finding packages from package manager
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
find_package(ZLIB REQUIRED)
find_package(BZip2 REQUIRED) find_package(BZip2 REQUIRED)
# Import all PkgConfig dependencies as one
# Consider all PkgConfig dependencies as one pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET
pkg_check_modules(PKGCONFIG_DEPS IMPORTED_TARGET
hunspell hunspell
liblzma
lzo2 lzo2
opencc opencc
vorbis # .ogg vorbis # .ogg
vorbisfile vorbisfile
liblzma
xapian-core xapian-core
zlib
) )
target_link_libraries(${GOLDENDICT} PRIVATE target_link_libraries(${GOLDENDICT} PRIVATE PkgConfig::DEPS BZip2::BZip2)
PkgConfig::PKGCONFIG_DEPS
BZip2::BZip2
ZLIB::ZLIB
)
# On FreeBSD, there are two iconv, libc iconv & GNU libiconv. # 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. # 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) COMMAND_ERROR_IS_FATAL ANY)
message(STATUS "Found correct homebrew icu path -> ${ICU_REQUIRED_BY_ZIM_PREFIX}") 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") 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 # 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 # so we manually discover the icu4c from homebrew, then find the relevent dylibs

22
cmake/Package_Linux.cmake Normal file
View file

@ -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 ()

View file

@ -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)

69
cmake/Package_macOS.cmake Normal file
View file

@ -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 ()

View file

@ -800,7 +800,7 @@ Class load()
// Upgrading // Upgrading
c.dictServers = makeDefaultDictServers(); c.dictServers = makeDefaultDictServers();
} }
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
QDomNode ves = root.namedItem( "voiceEngines" ); QDomNode ves = root.namedItem( "voiceEngines" );
if ( !ves.isNull() ) { if ( !ves.isNull() ) {
@ -1684,7 +1684,7 @@ void save( Class const & c )
p.setAttributeNode( icon ); p.setAttributeNode( icon );
} }
} }
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
{ {
QDomNode ves = dd.createElement( "voiceEngines" ); QDomNode ves = dd.createElement( "voiceEngines" );
root.appendChild( ves ); root.appendChild( ves );

View file

@ -725,7 +725,7 @@ struct Program
using Programs = QList< Program >; using Programs = QList< Program >;
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
struct VoiceEngine struct VoiceEngine
{ {
bool enabled; bool enabled;
@ -818,7 +818,7 @@ struct Class
Lingua lingua; Lingua lingua;
Forvo forvo; Forvo forvo;
Programs programs; Programs programs;
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
VoiceEngines voiceEngines; VoiceEngines voiceEngines;
#endif #endif

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62 /* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include <QDir> #include <QDir>
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
#include "epwing_book.hh" #include "epwing_book.hh"
#include "epwing.hh" #include "epwing.hh"

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62 /* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
#include "epwing_book.hh" #include "epwing_book.hh"

View file

@ -1,7 +1,7 @@
/* This file is (c) 2014 Abs62 /* This file is (c) 2014 Abs62
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
#include "epwing_charmap.hh" #include "epwing_charmap.hh"

View file

@ -15,12 +15,7 @@
#include <set> #include <set>
#include "utils.hh" #include "utils.hh"
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <hunspell/hunspell.hxx>
#ifndef INCLUDE_LIBRARY_PATH
#include <hunspell.hxx>
#else
#include <hunspell/hunspell.hxx>
#endif
namespace HunspellMorpho { namespace HunspellMorpho {

View file

@ -34,7 +34,7 @@
#include "dict/transliteration/romaji.hh" #include "dict/transliteration/romaji.hh"
#include "dict/transliteration/russian.hh" #include "dict/transliteration/russian.hh"
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
#include "dict/epwing.hh" #include "dict/epwing.hh"
#endif #endif
@ -83,7 +83,7 @@ LoadDictionaries::LoadDictionaries( Config::Class const & cfg ):
<< "*.zim" << "*.zim"
<< "*.zimaa" << "*.zimaa"
#endif #endif
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
<< "*catalogs" << "*catalogs"
#endif #endif
; ;
@ -181,7 +181,7 @@ void LoadDictionaries::handlePath( Config::Path const & path )
#ifdef MAKE_ZIM_SUPPORT #ifdef MAKE_ZIM_SUPPORT
addDicts( Zim::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) ); addDicts( Zim::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
#endif #endif
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
addDicts( Epwing::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) ); addDicts( Epwing::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
#endif #endif
} }
@ -274,7 +274,7 @@ void loadDictionaries( QWidget * parent,
addDicts( Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr ) ); addDicts( Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr ) );
addDicts( Lingua::makeDictionaries( loadDicts, cfg.lingua, dictNetMgr ) ); addDicts( Lingua::makeDictionaries( loadDicts, cfg.lingua, dictNetMgr ) );
addDicts( Programs::makeDictionaries( cfg.programs ) ); addDicts( Programs::makeDictionaries( cfg.programs ) );
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
addDicts( VoiceEngines::makeDictionaries( cfg.voiceEngines ) ); addDicts( VoiceEngines::makeDictionaries( cfg.voiceEngines ) );
#endif #endif
addDicts( DictServer::makeDictionaries( cfg.dictServers ) ); addDicts( DictServer::makeDictionaries( cfg.dictServers ) );

View file

@ -16,7 +16,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ):
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT #ifdef MAKE_CHINESE_CONVERSION_SUPPORT
chineseConversion( new ChineseConversion( this, cfg.transliteration.chinese ) ), chineseConversion( new ChineseConversion( this, cfg.transliteration.chinese ) ),
#endif #endif
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
textToSpeechSource( nullptr ), textToSpeechSource( nullptr ),
#endif #endif
itemDelegate( new QItemDelegate( this ) ), itemDelegate( new QItemDelegate( this ) ),
@ -129,7 +129,7 @@ Sources::Sources( QWidget * parent, Config::Class const & cfg ):
ui.forvoLanguageCodes->setText( forvo.languageCodes ); ui.forvoLanguageCodes->setText( forvo.languageCodes );
// Text to speech // Text to speech
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
if ( !cfg.notts ) { if ( !cfg.notts ) {
textToSpeechSource = new TextToSpeechSource( this, cfg.voiceEngines ); textToSpeechSource = new TextToSpeechSource( this, cfg.voiceEngines );
ui.tabWidget->addTab( textToSpeechSource, QIcon( ":/icons/text2speech.svg" ), tr( "Text to Speech" ) ); 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 Config::VoiceEngines Sources::getVoiceEngines() const
{ {
if ( !textToSpeechSource ) if ( !textToSpeechSource )

View file

@ -295,7 +295,7 @@ public:
{ {
return programsModel.getCurrentPrograms(); return programsModel.getCurrentPrograms();
} }
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
Config::VoiceEngines getVoiceEngines() const; Config::VoiceEngines getVoiceEngines() const;
#endif #endif
Config::Hunspell getHunspell() const; Config::Hunspell getHunspell() const;
@ -317,7 +317,7 @@ private:
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT #ifdef MAKE_CHINESE_CONVERSION_SUPPORT
ChineseConversion * chineseConversion; ChineseConversion * chineseConversion;
#endif #endif
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
TextToSpeechSource * textToSpeechSource; TextToSpeechSource * textToSpeechSource;
#endif #endif
QItemDelegate * itemDelegate; QItemDelegate * itemDelegate;

View file

@ -1,6 +1,6 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com> /* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include "voiceengines.hh" #include "voiceengines.hh"
#include "audiolink.hh" #include "audiolink.hh"

View file

@ -1,7 +1,7 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com> /* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#pragma once #pragma once
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include "dictionary.hh" #include "dictionary.hh"
#include "config.hh" #include "config.hh"

View file

@ -510,7 +510,7 @@ int main( int argc, char ** argv )
if ( gdcl.notts ) { if ( gdcl.notts ) {
cfg.notts = true; cfg.notts = true;
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
cfg.voiceEngines.clear(); cfg.voiceEngines.clear();
#endif #endif
} }

View file

@ -1,4 +1,4 @@
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include "speechclient.hh" #include "speechclient.hh"

View file

@ -1,5 +1,5 @@
#pragma once #pragma once
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include <QObject> #include <QObject>
#include "config.hh" #include "config.hh"

View file

@ -1,6 +1,6 @@
/* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com> /* This file is (c) 2013 Timon Wong <timon86.wang@gmail.com>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include "texttospeechsource.hh" #include "texttospeechsource.hh"
#include <QVariant> #include <QVariant>

View file

@ -3,7 +3,7 @@
#pragma once #pragma once
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
#include "ui_texttospeechsource.h" #include "ui_texttospeechsource.h"
#include "config.hh" #include "config.hh"

View file

@ -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." ) ); QMessageBox::critical( this, "GoldenDict", tr( "The referenced audio program doesn't exist." ) );
} }
else if ( url.scheme() == "gdtts" ) { else if ( url.scheme() == "gdtts" ) {
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
// Text to speech // Text to speech
QString md5Id = Utils::Url::queryItemValue( url, "engine" ); QString md5Id = Utils::Url::queryItemValue( url, "engine" );
QString text( url.path().mid( 1 ) ); QString text( url.path().mid( 1 ) );

View file

@ -173,7 +173,7 @@ bool EditDictionaries::isSourcesChanged() const
|| sources.getLingua() != cfg.lingua || sources.getForvo() != cfg.forvo || sources.getMediaWikis() != cfg.mediawikis || sources.getLingua() != cfg.lingua || sources.getForvo() != cfg.forvo || sources.getMediaWikis() != cfg.mediawikis
|| sources.getWebSites() != cfg.webSites || sources.getDictServers() != cfg.dictServers || sources.getWebSites() != cfg.webSites || sources.getDictServers() != cfg.dictServers
|| sources.getPrograms() != cfg.programs || sources.getPrograms() != cfg.programs
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
|| sources.getVoiceEngines() != cfg.voiceEngines || sources.getVoiceEngines() != cfg.voiceEngines
#endif #endif
; ;
@ -197,7 +197,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
cfg.webSites = sources.getWebSites(); cfg.webSites = sources.getWebSites();
cfg.dictServers = sources.getDictServers(); cfg.dictServers = sources.getDictServers();
cfg.programs = sources.getPrograms(); cfg.programs = sources.getPrograms();
#ifndef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
cfg.voiceEngines = sources.getVoiceEngines(); cfg.voiceEngines = sources.getVoiceEngines();
#endif #endif
setUpdatesEnabled( false ); setUpdatesEnabled( false );

View file

@ -3,7 +3,7 @@
#include <Qt> #include <Qt>
#include <QScopeGuard> #include <QScopeGuard>
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
#include "dict/epwing_book.hh" #include "dict/epwing_book.hh"
#endif #endif
@ -209,7 +209,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
+ " GoldenDict/WebEngine" ); + " GoldenDict/WebEngine" );
} }
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
Epwing::initialize(); Epwing::initialize();
#endif #endif
@ -1173,7 +1173,7 @@ MainWindow::~MainWindow()
scanPopup = nullptr; scanPopup = nullptr;
} }
#ifndef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
Epwing::finalize(); Epwing::finalize();
#endif #endif
} }

View file

@ -390,7 +390,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
#ifndef MAKE_ZIM_SUPPORT #ifndef MAKE_ZIM_SUPPORT
ui.allowZim->hide(); ui.allowZim->hide();
#endif #endif
#ifdef NO_EPWING_SUPPORT #ifndef EPWING_SUPPORT
ui.allowEpwing->hide(); ui.allowEpwing->hide();
#endif #endif
ui.maxDictionarySize->setValue( p.fts.maxDictionarySize ); ui.maxDictionarySize->setValue( p.fts.maxDictionarySize );

View file

@ -8,8 +8,8 @@ const QLatin1String flags = QLatin1String(
#ifdef MAKE_ZIM_SUPPORT #ifdef MAKE_ZIM_SUPPORT
" MAKE_ZIM_SUPPORT" " MAKE_ZIM_SUPPORT"
#endif #endif
#ifdef NO_EPWING_SUPPORT #ifdef EPWING_SUPPORT
" NO_EPWING_SUPPORT" " EPWING_SUPPORT"
#endif #endif
#ifdef USE_ICONV #ifdef USE_ICONV
" USE_ICONV" " USE_ICONV"
@ -17,8 +17,8 @@ const QLatin1String flags = QLatin1String(
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT #ifdef MAKE_CHINESE_CONVERSION_SUPPORT
" MAKE_CHINESE_CONVERSION_SUPPORT" " MAKE_CHINESE_CONVERSION_SUPPORT"
#endif #endif
#ifdef NO_TTS_SUPPORT #ifdef TTS_SUPPORT
" NO_TTS_SUPPORT" " TTS_SUPPORT"
#endif #endif
#ifndef MAKE_FFMPEG_PLAYER #ifndef MAKE_FFMPEG_PLAYER
" no_ffmpeg_player" " no_ffmpeg_player"