From c853ffb5b2f75f5a889ed2e3ef89b818a736e87a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:50:49 +0200 Subject: Adding upstream version 1.3+ds. Signed-off-by: Daniel Baumann --- CMakeScripts/COPYING-CMAKE-SCRIPTS | 22 ++ CMakeScripts/CPack.cmake | 21 ++ CMakeScripts/CleanAll.cmake | 17 + CMakeScripts/ConfigCPack.cmake | 228 +++++++++++ CMakeScripts/ConfigChecks.cmake | 27 ++ CMakeScripts/ConfigEnv.cmake | 38 ++ CMakeScripts/ConfigEnvMinGW.cmake | 98 +++++ CMakeScripts/ConfigPaths.cmake | 23 ++ CMakeScripts/DefineDependsandFlags.cmake | 478 ++++++++++++++++++++++++ CMakeScripts/Dist.cmake | 82 ++++ CMakeScripts/HelperFunctions.cmake | 244 ++++++++++++ CMakeScripts/HelperMacros.cmake | 130 +++++++ CMakeScripts/InstallMSYS2.cmake | 403 ++++++++++++++++++++ CMakeScripts/Modules/FindDoubleConversion.cmake | 27 ++ CMakeScripts/Modules/FindJeMalloc.cmake | 70 ++++ CMakeScripts/Modules/FindNSIS.cmake | 55 +++ CMakeScripts/Modules/FindPopplerCairo.cmake | 47 +++ CMakeScripts/Modules/FindPotrace.cmake | 62 +++ CMakeScripts/Pod2man.cmake | 83 ++++ CMakeScripts/UseGlibMarshal.cmake | 40 ++ CMakeScripts/UsePkgConfig.cmake | 103 +++++ CMakeScripts/cmake_consistency_check.py | 331 ++++++++++++++++ CMakeScripts/cmake_consistency_check_config.py | 55 +++ CMakeScripts/cmake_uninstall.cmake.in | 21 ++ CMakeScripts/inkscape-version.cmake | 52 +++ 25 files changed, 2757 insertions(+) create mode 100644 CMakeScripts/COPYING-CMAKE-SCRIPTS create mode 100644 CMakeScripts/CPack.cmake create mode 100644 CMakeScripts/CleanAll.cmake create mode 100644 CMakeScripts/ConfigCPack.cmake create mode 100644 CMakeScripts/ConfigChecks.cmake create mode 100644 CMakeScripts/ConfigEnv.cmake create mode 100644 CMakeScripts/ConfigEnvMinGW.cmake create mode 100644 CMakeScripts/ConfigPaths.cmake create mode 100644 CMakeScripts/DefineDependsandFlags.cmake create mode 100644 CMakeScripts/Dist.cmake create mode 100644 CMakeScripts/HelperFunctions.cmake create mode 100644 CMakeScripts/HelperMacros.cmake create mode 100644 CMakeScripts/InstallMSYS2.cmake create mode 100644 CMakeScripts/Modules/FindDoubleConversion.cmake create mode 100644 CMakeScripts/Modules/FindJeMalloc.cmake create mode 100644 CMakeScripts/Modules/FindNSIS.cmake create mode 100644 CMakeScripts/Modules/FindPopplerCairo.cmake create mode 100644 CMakeScripts/Modules/FindPotrace.cmake create mode 100644 CMakeScripts/Pod2man.cmake create mode 100644 CMakeScripts/UseGlibMarshal.cmake create mode 100644 CMakeScripts/UsePkgConfig.cmake create mode 100755 CMakeScripts/cmake_consistency_check.py create mode 100644 CMakeScripts/cmake_consistency_check_config.py create mode 100644 CMakeScripts/cmake_uninstall.cmake.in create mode 100644 CMakeScripts/inkscape-version.cmake (limited to 'CMakeScripts') diff --git a/CMakeScripts/COPYING-CMAKE-SCRIPTS b/CMakeScripts/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..4b41776 --- /dev/null +++ b/CMakeScripts/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/CMakeScripts/CPack.cmake b/CMakeScripts/CPack.cmake new file mode 100644 index 0000000..081a3f1 --- /dev/null +++ b/CMakeScripts/CPack.cmake @@ -0,0 +1,21 @@ +# This file reconfigures variables at CPack time. +# +# It is called by +# https://cmake.org/cmake/help/latest/module/CPack.html#variable:CPACK_PROJECT_CONFIG_FILE +# + +#used to get cmake-time variables at cpack-time +set(INKSCAPE_VERSION_SUFFIX @INKSCAPE_VERSION_SUFFIX@) +set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@) + +if(CPACK_GENERATOR STREQUAL "NSIS") + # NSIS doesn't always like forward slashes + file(TO_NATIVE_PATH "${CPACK_NSIS_MUI_HEADERIMAGE}" CPACK_NSIS_MUI_HEADERIMAGE_NATIVE) + set(CPACK_NSIS_MUI_HEADERIMAGE "${CPACK_NSIS_MUI_HEADERIMAGE_NATIVE}") + file(TO_NATIVE_PATH "${CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP}" CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP_NATIVE) + set(CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP "${CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP_NATIVE}") + +elseif(CPACK_GENERATOR STREQUAL "WIX") + # for wix version values need to look like 'x.x.x.x' where x is an integer from 0 to 65534. + set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") +endif() diff --git a/CMakeScripts/CleanAll.cmake b/CMakeScripts/CleanAll.cmake new file mode 100644 index 0000000..0b04d18 --- /dev/null +++ b/CMakeScripts/CleanAll.cmake @@ -0,0 +1,17 @@ +set(_generated + ${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake + ${CMAKE_CURRENT_BINARY_DIR}/po/cmake_install.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Makefile + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles +) + +message("${_generated}") + +foreach(file ${_generated}) + if(EXISTS ${file}) + message("Removing ${file}") + file(REMOVE_RECURSE ${file}) + endif() +endforeach(file) diff --git a/CMakeScripts/ConfigCPack.cmake b/CMakeScripts/ConfigCPack.cmake new file mode 100644 index 0000000..6a82baa --- /dev/null +++ b/CMakeScripts/ConfigCPack.cmake @@ -0,0 +1,228 @@ +############################ +# CPack configuration file # +############################ + + +## General ## + +set(CPACK_PACKAGE_NAME "Inkscape") +set(CPACK_PACKAGE_VENDOR "Inkscape") +set(CPACK_PACKAGE_VERSION_MAJOR ${INKSCAPE_VERSION_MAJOR}) # TODO: Can be set via project(), see CMAKE_PROJECT_VERSION_PATCH +set(CPACK_PACKAGE_VERSION_MINOR ${INKSCAPE_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${INKSCAPE_VERSION_PATCH}) +set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}${INKSCAPE_VERSION_SUFFIX}") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") # TODO: Where is this used? Do we need a better source? +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open-source vector graphics editor") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://inkscape.org") +set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/share/branding/inkscape.svg") # TODO: Can any generator make use of this? +set(CPACK_PACKAGE_CONTACT "Inkscape developers ") + +set(CPACK_PACKAGE_FILE_NAME ${INKSCAPE_DIST_PREFIX}) +set(CPACK_PACKAGE_CHECKSUM "SHA256") + +set(CPACK_PACKAGE_EXECUTABLES "inkscape;Inkscape;inkview;Inkview") +set(CPACK_CREATE_DESKTOP_LINKS "inkscape") + +if(WIN32) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "Inkscape") + set(CPACK_STRIP_FILES FALSE) +else() + set(CPACK_PACKAGE_INSTALL_DIRECTORY "inkscape") + set(CPACK_STRIP_FILES TRUE) +endif() + +# This creates a screen in the windows installers asking users to "Agree" to the GPL which is incorrect. +# set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSES/GPL-3.0.txt") +set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md") +# set( CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/README.md") # TODO: can we use this? + +set(CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION TRUE) + +# specific config for source packaging (note this is used by the 'dist' target) +set(CPACK_SOURCE_GENERATOR "TXZ") +set(CPACK_SOURCE_PACKAGE_FILE_NAME ${INKSCAPE_DIST_PREFIX}) +set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj*/;cscope.*;.gitlab*;.coveragerc;*.md;") + + + + +# this allows to override above configuration per cpack generator at CPack-time +set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_BINARY_DIR}/CMakeScripts/CPack.cmake") +configure_file("${CMAKE_SOURCE_DIR}/CMakeScripts/CPack.cmake" "${CMAKE_BINARY_DIR}/CMakeScripts/CPack.cmake" @ONLY) + + + + +## Generator-specific configuration ## + +# NSIS (Windows .exe installer) +set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/share/branding/inkscape.ico") +set(CPACK_NSIS_MUI_HEADERIMAGE "${CMAKE_SOURCE_DIR}/packaging/nsis/header.bmp") +set(CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP "${CMAKE_SOURCE_DIR}/packaging/nsis/welcomefinish.bmp") +set(CPACK_NSIS_IGNORE_LICENSE_PAGE 1) +set(CPACK_NSIS_INSTALLED_ICON_NAME "bin/inkscape.exe") +set(CPACK_NSIS_HELP_LINK "${CPACK_PACKAGE_HOMEPAGE_URL}") +set(CPACK_NSIS_URL_INFO_ABOUT "${CPACK_PACKAGE_HOMEPAGE_URL}") +set(CPACK_NSIS_MENU_LINKS "${CPACK_PACKAGE_HOMEPAGE_URL}" "Inkscape Homepage") +set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") # zlib|bzip2|lzma +set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") +set(CPACK_NSIS_MODIFY_PATH "ON") # while the name does not suggest it, this also provides the possibility to add desktop icons +set(CPACK_NSIS_MUI_FINISHPAGE_RUN "inkscape") # TODO: this results in instance with administrative privileges! +set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) # Make the text not blurry in installer + +set(CPACK_NSIS_COMPRESSOR "${CPACK_NSIS_COMPRESSOR}\n SetCompressorDictSize 64") # hack (improve compression) +set(CPACK_NSIS_COMPRESSOR "${CPACK_NSIS_COMPRESSOR}\n BrandingText '${CPACK_PACKAGE_DESCRIPTION_SUMMARY}'") # hack (overwrite BrandingText) +set(CPACK_NSIS_COMPRESSOR "${CPACK_NSIS_COMPRESSOR}\n !define MUI_COMPONENTSPAGE_SMALLDESC") # hack (better components page layout) + +file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}/packaging/nsis/fileassoc.nsh" native_path) +string(REPLACE "\\" "\\\\" native_path "${native_path}") +set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS "!include '${native_path}'") +set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "\ + WriteRegStr SHCTX 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\App Paths\\\\inkscape.exe' '' '$INSTDIR\\\\bin\\\\inkscape.exe'\n\ + WriteRegStr SHCTX 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\App Paths\\\\inkscape.exe' 'Path' '$INSTDIR\\\\bin'\n\ + !insertmacro APP_ASSOCIATE 'svg' 'Inkscape.SVG' 'Scalable Vector Graphics' '$INSTDIR\\\\bin\\\\inkscape.exe,0' 'Open with Inkscape' '$INSTDIR\\\\bin\\\\inkscape.exe \\\"%1\\\"'\n\ + !insertmacro APP_ASSOCIATE 'svgz' 'Inkscape.SVGZ' 'Compressed Scalable Vector Graphics' '$INSTDIR\\\\bin\\\\inkscape.exe,0' 'Open with Inkscape' '$INSTDIR\\\\bin\\\\inkscape.exe \\\"%1\\\"'\n\ + !insertmacro UPDATEFILEASSOC") +set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "\ + DeleteRegKey SHCTX 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\App Paths\\\\inkscape.exe'\n\ + !insertmacro APP_UNASSOCIATE 'svg' 'Inkscape.SVG'\n\ + !insertmacro APP_UNASSOCIATE 'svgz' 'Inkscape.SVGZ'\n\ + !insertmacro UPDATEFILEASSOC") + +# WIX (Windows .msi installer) +set(CPACK_WIX_UPGRADE_GUID "4d5fedaa-84a0-48be-bd2a-08246398361a") +set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/share/branding/inkscape.ico") +set(CPACK_WIX_UI_BANNER "${CMAKE_SOURCE_DIR}/packaging/wix/Bitmaps/banner.bmp") +set(CPACK_WIX_UI_DIALOG "${CMAKE_SOURCE_DIR}/packaging/wix/Bitmaps/dialog.bmp") +set(CPACK_WIX_UI_REF "WixUI_FeatureTree_NoLicense") +set(CPACK_WIX_PROPERTY_ARPHELPLINK "${CPACK_PACKAGE_HOMEPAGE_URL}") +set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "${CPACK_PACKAGE_HOMEPAGE_URL}") +set(CPACK_WIX_PROPERTY_ARPURLUPDATEINFO "${CPACK_PACKAGE_HOMEPAGE_URL}/release") +set(CPACK_WIX_ROOT_FEATURE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") +set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high") # set high compression + +set(CPACK_WIX_PATCH_FILE "${CMAKE_SOURCE_DIR}/packaging/wix/app_registration.xml" + "${CMAKE_SOURCE_DIR}/packaging/wix/feature_attributes.xml") +set(CPACK_WIX_EXTRA_SOURCES "${CMAKE_SOURCE_DIR}/packaging/wix/featuretree_nolicense.wxs") + +# DEB (Linux .deb bundle) +set(CPACK_DEBIAN_PACKAGE_SECTION "graphics") +set(CPACK_DEBIAN_INKSCAPE_PACKAGE_SUGGESTS "dia, pstoedit, scribus") +set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) +set(CPACK_DEBIAN_PACKAGE_DEPENDS "inkscape") # all package depend on inkscape +set(CPACK_DEBIAN_INKSCAPE_PACKAGE_DEPENDS "lib2geom${2GEOM_VERSION}") +set(CPACK_DEBIAN_INKSCAPE_PACKAGE_RECOMMENDS "aspell, imagemagick, libwmf-bin, inkscape-extensions, inkscape-translations, inkscape-themes") + +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_COMPONENTS_GROUPING IGNORE) + +set(CPACK_DEBIAN_INKSCAPE-EXTENSIONS_PACKAGE_DEPENDS "python3-numpy, python3-lxml, python3-scour, python3-packaging, python3-cssselect, python3-bs4, python3-requests") +set(CPACK_DEBIAN_INKSCAPE-EXTENSIONS_PACKAGE_RECOMMENDS "inkscape-extension-manager") +set(CPACK_DEBIAN_INKSCAPE-EXTENSION-MANAGER_PACKAGE_DEPENDS "inkscape-extensions, python3-filecache") +set(CPACK_DEBIAN_LIB2GEOM-DEV_PACKAGE_RECOMMENDS "lib2geom${2GEOM_VERSION}") +set(CPACK_DEBIAN_LIB2GEOM1.3.0_PACKAGE_NAME "lib2geom${2GEOM_VERSION}") +set(CPACK_DEBIAN_LIB2GEOM-DEV_PACKAGE_NAME "lib2geom-dev") +set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_ADD_LDCONFIG_CALL ON) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) + +## load cpack module (do this *after* all the CPACK_* variables have been set) +include(CPack) + + + + +## Component definition +# - variable names are UPPER CASE, even if component names are lower case +# - components/groups are ordered alphabetically by component/group name; groups always come first +# - empty (e.g. OS-specific) components are discarded automatically + +cpack_add_install_type(full DISPLAY_NAME Full) +cpack_add_install_type(compact DISPLAY_NAME Compact) # no translations, dictionaries, examples, etc. +cpack_add_install_type(minimal DISPLAY_NAME Minimal) # minimal "working" set-up, excluding everything non-essential + +cpack_add_component_group( + group_1_program_files + DISPLAY_NAME "Program Files" + EXPANDED) +cpack_add_component(inkscape + DISPLAY_NAME "Inkscape SVG Editor" + DESCRIPTION "Inkscape core files and dependencies" + GROUP "group_1_program_files" + REQUIRED) +cpack_add_component(python + DISPLAY_NAME "Python" + DESCRIPTION "Python interpreter (required to run Inkscape extensions)" + GROUP "group_1_program_files" + INSTALL_TYPES full compact) + +cpack_add_component_group( + group_2_inkscape_data + DISPLAY_NAME "Inkscape Data" + EXPANDED) +cpack_add_component(extensions + DISPLAY_NAME "Extensions" + DESCRIPTION "Inkscape extensions (including many import and export plugins)" + GROUP "group_2_inkscape_data" + INSTALL_TYPES full compact) +cpack_add_component(extension_manager + DISPLAY_NAME "Extension Manager" + DESCRIPTION "Extension manager allows user to install extensions from the inkscape website" + DEPENDS "extensions" + GROUP "group_2_inkscape_data" + INSTALL_TYPES full compact) +cpack_add_component(themes + DISPLAY_NAME "Themes" + DESCRIPTION "Inkscape themes (look and feel including icons)" + GROUP "group_2_inkscape_data" + INSTALL_TYPES full compact) +cpack_add_component(examples + DISPLAY_NAME "Examples" + DESCRIPTION "Example files created in Inkscape" + GROUP "group_2_inkscape_data" + INSTALL_TYPES full) +cpack_add_component(tutorials + DISPLAY_NAME "Tutorials" + DESCRIPTION "Tutorials teaching Inkscape usage" + GROUP "group_2_inkscape_data" + INSTALL_TYPES full) + +cpack_add_component(dictionaries + DISPLAY_NAME "Dictionaries" + DESCRIPTION "Dictionaries for some common languages for spell checking in Inkscape" + INSTALL_TYPES full) + +cpack_add_component_group( + group_3_translations + DISPLAY_NAME "Translations" + DESCRIPTION "Translations and localized content for Inkscape") +get_inkscape_languages() +list(LENGTH INKSCAPE_LANGUAGE_CODES length) +math(EXPR length "${length} - 1") +if(WIN32) + foreach(index RANGE ${length}) + list(GET INKSCAPE_LANGUAGE_CODES ${index} language_code) + list(GET INKSCAPE_LANGUAGE_NAMES ${index} language_name) + string(MAKE_C_IDENTIFIER "${language_code}" language_code_escaped) + cpack_add_component(translations.${language_code_escaped} + DISPLAY_NAME "${language_name}" + GROUP "group_3_translations" + INSTALL_TYPES full) + endforeach() +else() + cpack_add_component(translations + DISPLAY_NAME "Translations" + GROUP "group_3_translations" + INSTALL_TYPES full) +endif() + +if(WITH_INTERNAL_2GEOM) + cpack_add_component(lib2geom_dev + DISPLAY_NAME "lib2geom-dev" + DESCRIPTION "Geometry library - dev files") + cpack_add_component(lib2geom${2GEOM_VERSION} + DISPLAY_NAME "lib2geom" + DESCRIPTION "Geometry library" + HIDDEN REQUIRED) +endif() diff --git a/CMakeScripts/ConfigChecks.cmake b/CMakeScripts/ConfigChecks.cmake new file mode 100644 index 0000000..d38d652 --- /dev/null +++ b/CMakeScripts/ConfigChecks.cmake @@ -0,0 +1,27 @@ +include(${CMAKE_CURRENT_LIST_DIR}/ConfigPaths.cmake) + +# Set all HAVE_XXX variables, to correctly set all defines in config.h +include(CheckIncludeFiles) +include(CheckIncludeFileCXX) +include(CheckFunctionExists) +include(CheckStructHasMember) +include(CheckCXXSymbolExists) + +set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${INKSCAPE_LIBS}) +set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${INKSCAPE_INCS_SYS}) + +CHECK_INCLUDE_FILES(ieeefp.h HAVE_IEEEFP_H) +CHECK_FUNCTION_EXISTS(mallinfo HAVE_MALLINFO) +CHECK_FUNCTION_EXISTS(mallinfo2 HAVE_MALLINFO2) +CHECK_INCLUDE_FILES(malloc.h HAVE_MALLOC_H) +CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H) +CHECK_STRUCT_HAS_MEMBER("struct mallinfo" fordblks malloc.h HAVE_STRUCT_MALLINFO_FORDBLKS ) +CHECK_STRUCT_HAS_MEMBER("struct mallinfo" fsmblks malloc.h HAVE_STRUCT_MALLINFO_FSMBLKS ) +CHECK_STRUCT_HAS_MEMBER("struct mallinfo" hblkhd malloc.h HAVE_STRUCT_MALLINFO_HBLKHD ) +CHECK_STRUCT_HAS_MEMBER("struct mallinfo" uordblks malloc.h HAVE_STRUCT_MALLINFO_UORDBLKS ) +CHECK_STRUCT_HAS_MEMBER("struct mallinfo" usmblks malloc.h HAVE_STRUCT_MALLINFO_USMBLKS ) +CHECK_CXX_SYMBOL_EXISTS(sincos math.h HAVE_SINCOS) # 2geom define + +# Create the configuration files config.h in the binary root dir +configure_file(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/include/config.h) +add_definitions(-DHAVE_CONFIG_H) diff --git a/CMakeScripts/ConfigEnv.cmake b/CMakeScripts/ConfigEnv.cmake new file mode 100644 index 0000000..f4783d1 --- /dev/null +++ b/CMakeScripts/ConfigEnv.cmake @@ -0,0 +1,38 @@ +# ----------------------------------------------------------------------------- +# Set platform defaults (originally copied from darktable) +# ----------------------------------------------------------------------------- +if(WIN32) + message("-- Windows build detected, setting default features") + + include(CMakeScripts/ConfigEnvMinGW.cmake) + + # Setup Windows resource files compiler. + set(CMAKE_RC_COMPILER "${MINGW_BIN}/windres.exe") + set(CMAKE_RC_COMPILER_INIT windres) + enable_language(RC) + set(CMAKE_RC_COMPILE_OBJECT " -O coff -i -o ") + + # These options are required for having i18n support on Windows. + option(ENABLE_NLS "Compile with Native Language Support (using gettext)" ON) + + # Does not compile on Windows with these options. + option(ENABLE_BINRELOC "Compile with binary relocation support" OFF) + option(WITH_JEMALLOC "Compile with JEMALLOC support" OFF) +endif() + +if(APPLE) + message("-- Mac OS X build detected, setting default features") + + # prefer macports and/or user-installed libraries over system ones + #LIST(APPEND CMAKE_PREFIX_PATH /opt/local /usr/local) + set(CMAKE_FIND_FRAMEWORK "LAST") + + # test and display relevant env variables + if(DEFINED ENV{CMAKE_PREFIX_PATH}) + message("CMAKE_PREFIX_PATH: $ENV{CMAKE_PREFIX_PATH}") + endif() + + if(DEFINED ENV{GTKMM_BASEPATH}) + message("GTKMM_BASEPATH: $ENV{GTKMM_BASEPATH}") + endif() +endif() diff --git a/CMakeScripts/ConfigEnvMinGW.cmake b/CMakeScripts/ConfigEnvMinGW.cmake new file mode 100644 index 0000000..85b6564 --- /dev/null +++ b/CMakeScripts/ConfigEnvMinGW.cmake @@ -0,0 +1,98 @@ +# ----------------------------------------------------------------------------- +# Set the paths in this file if you want to build Inkscape from a shell other than the +# Windows built-in command line (i.e. MSYS) or IDEs such as CodeLite. These variables +# will be used as default if no environment variables are set. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# MinGW Configuration +# ----------------------------------------------------------------------------- +message(STATUS "Configuring MinGW environment:") + +if("$ENV{MINGW_CHOST}" STREQUAL "") + message(WARNING " Could not detect MinGW build environment. We recommend building with MSYS2. Proceed at your own risk!") +else() + message(STATUS " Detected MinGW environment provided by MSYS2") + set(MINGW_PATH $ENV{MINGW_PREFIX}) +endif() + +# ----------------------------------------------------------------------------- +# MINGW CHECKS +# ----------------------------------------------------------------------------- + +# Try to determine the MinGW processor architecture. +if("$ENV{MINGW_CHOST}" STREQUAL "i686-w64-mingw32") + set(HAVE_MINGW64 OFF) + set(MINGW_ARCH i686-w64-mingw32) +elseif("$ENV{MINGW_CHOST}" STREQUAL "x86_64-w64-mingw32") + set(HAVE_MINGW64 ON) + set(MINGW_ARCH x86_64-w64-mingw32) +elseif("$ENV{MINGW_CHOST}" STREQUAL "aarch64-w64-mingw32") + set(HAVE_MINGW64 ON) + set(MINGW_ARCH aarch64-w64-mingw32) +else() + message(FATAL_ERROR "Unable to determine MinGW processor architecture. Are you using an unsupported MinGW version?") +endif() + +set(MINGW_BIN "${MINGW_PATH}/bin") + +if(NOT EXISTS ${MINGW_BIN}) + message(FATAL_ERROR "MinGW binary directory does not exist: ${MINGW_BIN}") +endif() + +# Eliminate error messages when not having mingw in the environment path variable. +list(APPEND CMAKE_PROGRAM_PATH ${MINGW_BIN}) + +set(MINGW_LIB "${MINGW_PATH}/lib") + +if(NOT EXISTS ${MINGW_LIB}) + message(FATAL_ERROR "MinGW library directory does not exist: ${MINGW_LIB}") +endif() + +# Add MinGW libraries to linker path. +link_directories(${MINGW_LIB}) + +set(MINGW_INCLUDE "${MINGW_PATH}/include") + +if(NOT EXISTS ${MINGW_INCLUDE}) + message(FATAL_ERROR "MinGW include directory does not exist: ${MINGW_INCLUDE}") +endif() + +# Add MinGW headers to compiler include path. +include_directories(SYSTEM ${MINGW_INCLUDE}) + +# ----------------------------------------------------------------------------- +# MSYS CHECKS +# ----------------------------------------------------------------------------- + +# Somehow the MSYS variable does not work as documented.. +if("${CMAKE_GENERATOR}" STREQUAL "MSYS Makefiles") + set(HAVE_MSYS ON) +else() + set(HAVE_MSYS OFF) +endif() + +# Set the path to the 'ar' utility for the MSYS shell as it fails to detect it properly. +if(HAVE_MSYS) + message(STATUS "Configuring MSYS environment:") + + if(NOT EXISTS ${CMAKE_AR}) + set(MINGW_AR ${MINGW_BIN}/ar.exe) + + if(EXISTS ${MINGW_AR}) + set(CMAKE_AR ${MINGW_AR} CACHE FILEPATH "Archive Utility") + else() + message(FATAL_ERROR "ar.exe not found.") + endif() + + message(STATUS " Setting path to ar.exe: ${CMAKE_AR}") + endif() +endif() + +# ----------------------------------------------------------------------------- +# LIBRARY AND LINKER SETTINGS +# ----------------------------------------------------------------------------- + +# Tweak CMake into using Unix-style library names. +set(CMAKE_FIND_LIBRARY_PREFIXES "lib") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".dll") diff --git a/CMakeScripts/ConfigPaths.cmake b/CMakeScripts/ConfigPaths.cmake new file mode 100644 index 0000000..affa3e7 --- /dev/null +++ b/CMakeScripts/ConfigPaths.cmake @@ -0,0 +1,23 @@ +message(STATUS "Creating build files in: ${CMAKE_CURRENT_BINARY_DIR}") + +if(WIN32) + if(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/inkscape" + CACHE PATH "Install path prefix, prepended onto install directories." FORCE) + endif() + + set(INKSCAPE_DATADIR "") # can be set via the environment variable INKSCAPE_DATADIR at runtime +else() + if(NOT INKSCAPE_DATADIR) + set(INKSCAPE_DATADIR "${CMAKE_INSTALL_PREFIX}/share") + endif(NOT INKSCAPE_DATADIR) +endif() + +if(NOT PACKAGE_LOCALE_DIR) + set(PACKAGE_LOCALE_DIR "share/locale") # packagers might overwrite this +endif(NOT PACKAGE_LOCALE_DIR) + +if(NOT SHARE_INSTALL) + set(SHARE_INSTALL "share" CACHE STRING "Data file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.") +endif(NOT SHARE_INSTALL) +set(INKSCAPE_SHARE_INSTALL "${SHARE_INSTALL}/inkscape") diff --git a/CMakeScripts/DefineDependsandFlags.cmake b/CMakeScripts/DefineDependsandFlags.cmake new file mode 100644 index 0000000..0e93631 --- /dev/null +++ b/CMakeScripts/DefineDependsandFlags.cmake @@ -0,0 +1,478 @@ +set(INKSCAPE_LIBS "") +set(INKSCAPE_INCS "") +set(INKSCAPE_INCS_SYS "") +set(INKSCAPE_CXX_FLAGS "") +set(INKSCAPE_CXX_FLAGS_DEBUG "") + +list(APPEND INKSCAPE_INCS ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/src + + # generated includes + ${CMAKE_BINARY_DIR}/include +) + +# NDEBUG implies G_DISABLE_ASSERT +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) +if(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER} MATCHES "-DNDEBUG") + list(APPEND INKSCAPE_CXX_FLAGS "-DG_DISABLE_ASSERT") +endif() + +# AddressSanitizer +# Clang's AddressSanitizer can detect more memory errors and is more powerful +# than compiling with _FORTIFY_SOURCE but has a performance impact (approx. 2x +# slower), so it's not suitable for release builds. +if(WITH_ASAN) + list(APPEND INKSCAPE_CXX_FLAGS "-fsanitize=address -fno-omit-frame-pointer") + list(APPEND INKSCAPE_LIBS "-fsanitize=address") +else() + # Undefine first, to suppress 'warning: "_FORTIFY_SOURCE" redefined' + list(APPEND INKSCAPE_CXX_FLAGS "-U_FORTIFY_SOURCE") + list(APPEND INKSCAPE_CXX_FLAGS "-D_FORTIFY_SOURCE=2") +endif() + +# Disable deprecated Gtk and friends +list(APPEND INKSCAPE_CXX_FLAGS "-DGLIBMM_DISABLE_DEPRECATED") +list(APPEND INKSCAPE_CXX_FLAGS "-DGTKMM_DISABLE_DEPRECATED") +list(APPEND INKSCAPE_CXX_FLAGS "-DGDKMM_DISABLE_DEPRECATED") +list(APPEND INKSCAPE_CXX_FLAGS "-DGTK_DISABLE_DEPRECATED") +list(APPEND INKSCAPE_CXX_FLAGS "-DGDK_DISABLE_DEPRECATED") + +# Errors for common mistakes +list(APPEND INKSCAPE_CXX_FLAGS "-fstack-protector-strong") +list(APPEND INKSCAPE_CXX_FLAGS "-Werror=format") # e.g.: printf("%s", std::string("foo")) +list(APPEND INKSCAPE_CXX_FLAGS "-Werror=format-security") # e.g.: printf(variable); +list(APPEND INKSCAPE_CXX_FLAGS "-Werror=ignored-qualifiers") # e.g.: const int foo(); +list(APPEND INKSCAPE_CXX_FLAGS "-Werror=return-type") # non-void functions that don't return a value +list(APPEND INKSCAPE_CXX_FLAGS "-Wno-switch") # See !849 for discussion +list(APPEND INKSCAPE_CXX_FLAGS "-Wmisleading-indentation") +list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-Og") # -Og for _FORTIFY_SOURCE. One could add -Weffc++ here to see approx. 6000 warnings +list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-Wcomment") +list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-Wunused-function") +list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-Wunused-variable") +list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-D_GLIBCXX_ASSERTIONS") +if (CMAKE_COMPILER_IS_GNUCC) + list(APPEND INKSCAPE_CXX_FLAGS "-Wstrict-null-sentinel") # For NULL instead of nullptr + list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-fexceptions -grecord-gcc-switches -fasynchronous-unwind-tables") + if(CXX_COMPILER_VERSION VERSION_GREATER 8.0) + list(APPEND INKSCAPE_CXX_FLAGS_DEBUG "-fstack-clash-protection -fcf-protection") + endif() +endif() + +# Define the flags for profiling if desired: +if(WITH_PROFILING) + set(BUILD_SHARED_LIBS off) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") +endif() + +include(CheckCXXSourceCompiles) +CHECK_CXX_SOURCE_COMPILES(" +#include +#include +std::atomic x (0); +int main() { + uint64_t i = x.load(std::memory_order_relaxed); + return 0; +} +" +LIBATOMIC_NOT_NEEDED) +IF (NOT LIBATOMIC_NOT_NEEDED) + message(STATUS " Adding -latomic to the libs.") + list(APPEND INKSCAPE_LIBS "-latomic") +ENDIF() + + +# ---------------------------------------------------------------------------- +# Helper macros +# ---------------------------------------------------------------------------- + +# Turns linker arguments like "-framework Foo" into "-Wl,-framework,Foo" to +# make them safe for appending to INKSCAPE_LIBS +macro(sanitize_ldflags_for_libs ldflags_var) + # matches dash-argument followed by non-dash-argument + string(REGEX REPLACE "(^|;)(-[^;]*);([^-])" "\\1-Wl,\\2,\\3" ${ldflags_var} "${${ldflags_var}}") +endmacro() + + +# ---------------------------------------------------------------------------- +# Files we include +# ---------------------------------------------------------------------------- +if(WIN32) + # Set the link and include directories + get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + + list(APPEND INKSCAPE_LIBS "-lmscms") + + list(APPEND INKSCAPE_CXX_FLAGS "-mms-bitfields") + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + list(APPEND INKSCAPE_CXX_FLAGS "-mwindows") + list(APPEND INKSCAPE_CXX_FLAGS "-mthreads") + endif() + + list(APPEND INKSCAPE_LIBS "-lwinpthread") + + if(HAVE_MINGW64) + list(APPEND INKSCAPE_CXX_FLAGS "-m64") + else() + list(APPEND INKSCAPE_CXX_FLAGS "-m32") + endif() +endif() + +find_package(PkgConfig REQUIRED) +pkg_check_modules(INKSCAPE_DEP REQUIRED + harfbuzz + pangocairo>=1.44 + pangoft2 + fontconfig + gsl + gmodule-2.0 + libsoup-2.4>=2.42 + #double-conversion + bdw-gc #boehm-demers-weiser gc + lcms2) + +# remove this line and uncomment the doiuble-conversion above when double-conversion.pc file gets shipped on all platforms we support +find_package(DoubleConversion REQUIRED) # lib2geom dependency + +sanitize_ldflags_for_libs(INKSCAPE_DEP_LDFLAGS) +list(APPEND INKSCAPE_LIBS ${INKSCAPE_DEP_LDFLAGS}) +list(APPEND INKSCAPE_INCS_SYS ${INKSCAPE_DEP_INCLUDE_DIRS}) + +add_definitions(${INKSCAPE_DEP_CFLAGS_OTHER}) + +if(WITH_JEMALLOC) + find_package(JeMalloc) + if (JEMALLOC_FOUND) + list(APPEND INKSCAPE_LIBS ${JEMALLOC_LIBRARIES}) + else() + set(WITH_JEMALLOC OFF) + endif() +endif() + +find_package(Iconv REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${Iconv_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${Iconv_LIBRARIES}) + +find_package(Intl REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${Intl_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${Intl_LIBRARIES}) +add_definitions(${Intl_DEFINITIONS}) + +# Check for system-wide version of 2geom and fallback to internal copy if not found +if(NOT WITH_INTERNAL_2GEOM) + pkg_check_modules(2Geom QUIET IMPORTED_TARGET GLOBAL 2geom>=1.3.0) + if(2Geom_FOUND) + add_library(2Geom::2geom ALIAS PkgConfig::2Geom) + else() + set(WITH_INTERNAL_2GEOM ON CACHE BOOL "Prefer internal copy of lib2geom" FORCE) + message(STATUS "lib2geom not found, using internal copy in src/3rdparty/2geom") + endif() +endif() +if(WITH_INTERNAL_2GEOM) + set(2Geom_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/2geom/include) +endif() + + +if(ENABLE_POPPLER) + find_package(PopplerCairo) + if(POPPLER_FOUND) + set(HAVE_POPPLER ON) + if(ENABLE_POPPLER_CAIRO) + if(POPPLER_CAIRO_FOUND AND POPPLER_GLIB_FOUND) + set(HAVE_POPPLER_CAIRO ON) + endif() + endif() + else() + set(ENABLE_POPPLER_CAIRO OFF) + endif() +else() + set(HAVE_POPPLER OFF) + set(ENABLE_POPPLER_CAIRO OFF) +endif() + +list(APPEND INKSCAPE_INCS_SYS ${POPPLER_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${POPPLER_LIBRARIES}) +add_definitions(${POPPLER_DEFINITIONS}) + +if(WITH_LIBWPG) + pkg_check_modules(LIBWPG libwpg-0.3 librevenge-0.0 librevenge-stream-0.0) + if(LIBWPG_FOUND) + sanitize_ldflags_for_libs(LIBWPG_LDFLAGS) + list(APPEND INKSCAPE_INCS_SYS ${LIBWPG_INCLUDE_DIRS}) + list(APPEND INKSCAPE_LIBS ${LIBWPG_LDFLAGS}) + add_definitions(${LIBWPG_DEFINITIONS}) + else() + set(WITH_LIBWPG OFF) + endif() +endif() + +if(WITH_LIBVISIO) + pkg_check_modules(LIBVISIO libvisio-0.1 librevenge-0.0 librevenge-stream-0.0) + if(LIBVISIO_FOUND) + sanitize_ldflags_for_libs(LIBVISIO_LDFLAGS) + list(APPEND INKSCAPE_INCS_SYS ${LIBVISIO_INCLUDE_DIRS}) + list(APPEND INKSCAPE_LIBS ${LIBVISIO_LDFLAGS}) + add_definitions(${LIBVISIO_DEFINITIONS}) + else() + set(WITH_LIBVISIO OFF) + endif() +endif() + +if(WITH_LIBCDR) + pkg_check_modules(LIBCDR libcdr-0.1 librevenge-0.0 librevenge-stream-0.0) + if(LIBCDR_FOUND) + sanitize_ldflags_for_libs(LIBCDR_LDFLAGS) + list(APPEND INKSCAPE_INCS_SYS ${LIBCDR_INCLUDE_DIRS}) + list(APPEND INKSCAPE_LIBS ${LIBCDR_LDFLAGS}) + add_definitions(${LIBCDR_DEFINITIONS}) + else() + set(WITH_LIBCDR OFF) + endif() +endif() + +FIND_PACKAGE(JPEG) +IF(JPEG_FOUND) + list(APPEND INKSCAPE_INCS_SYS ${JPEG_INCLUDE_DIR}) + list(APPEND INKSCAPE_LIBS ${JPEG_LIBRARIES}) + set(HAVE_JPEG ON) +ENDIF() + +find_package(PNG REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${PNG_PNG_INCLUDE_DIR}) +list(APPEND INKSCAPE_LIBS ${PNG_LIBRARY}) + +find_package(Potrace REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${POTRACE_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${POTRACE_LIBRARIES}) + +if(WITH_SVG2) + add_definitions(-DWITH_MESH -DWITH_CSSBLEND -DWITH_SVG2) +else() + add_definitions(-UWITH_MESH -UWITH_CSSBLEND -UWITH_SVG2) +endif() + +# ---------------------------------------------------------------------------- +# CMake's builtin +# ---------------------------------------------------------------------------- + +# Include dependencies: + +pkg_check_modules( + GTK3 + REQUIRED + gtkmm-3.0>=3.24 + gdkmm-3.0>=3.24 + gtk+-3.0>=3.24 + gdk-3.0>=3.24 + ) +list(APPEND INKSCAPE_CXX_FLAGS ${GTK3_CFLAGS_OTHER}) +list(APPEND INKSCAPE_INCS_SYS ${GTK3_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${GTK3_LIBRARIES}) +link_directories(${GTK3_LIBRARY_DIRS}) + +if(WITH_GSPELL) + pkg_check_modules(GSPELL gspell-1) + if("${GSPELL_FOUND}") + message(STATUS "Using gspell") + list(APPEND INKSCAPE_INCS_SYS ${GSPELL_INCLUDE_DIRS}) + sanitize_ldflags_for_libs(GSPELL_LDFLAGS) + list(APPEND INKSCAPE_LIBS ${GSPELL_LDFLAGS}) + else() + set(WITH_GSPELL OFF) + endif() +endif() + +if(WITH_GSOURCEVIEW) + pkg_check_modules(GSOURCEVIEW gtksourceview-4) + if("${GSOURCEVIEW_FOUND}") + message(STATUS "Using gtksourceview-4") + list(APPEND INKSCAPE_INCS_SYS ${GSOURCEVIEW_INCLUDE_DIRS}) + sanitize_ldflags_for_libs(GSOURCEVIEW_LDFLAGS) + list(APPEND INKSCAPE_LIBS ${GSOURCEVIEW_LDFLAGS}) + else() + set(WITH_GSOURCEVIEW OFF) + endif() +endif() + +# stacktrace print on crash +if(WIN32) + find_package(Boost 1.19.0 REQUIRED COMPONENTS filesystem stacktrace_windbg) + list(APPEND INKSCAPE_LIBS "-lole32") + list(APPEND INKSCAPE_LIBS "-ldbgeng") + add_definitions("-DBOOST_STACKTRACE_USE_WINDBG") +elseif(APPLE) + find_package(Boost 1.19.0 REQUIRED COMPONENTS filesystem stacktrace_basic) + list(APPEND INKSCAPE_CXX_FLAGS "-D_GNU_SOURCE") +else() + find_package(Boost 1.19.0 REQUIRED COMPONENTS filesystem) + # The package stacktrace_backtrace may not be available on all distros. + find_package(Boost 1.19.0 COMPONENTS stacktrace_backtrace) + if (BOOST_FOUND) + list(APPEND INKSCAPE_LIBS "-lbacktrace") + add_definitions("-DBOOST_STACKTRACE_USE_BACKTRACE") + else() # fall back to stacktrace_basic + find_package(Boost 1.19.0 REQUIRED COMPONENTS stacktrace_basic) + list(APPEND INKSCAPE_CXX_FLAGS "-D_GNU_SOURCE") + endif() +endif() +# enable explicit debug symbols +set(CMAKE_ENABLE_EXPORTS ON) + + + +if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9) + list(APPEND INKSCAPE_LIBS "-lstdc++fs") +endif() + +list(APPEND INKSCAPE_INCS_SYS ${Boost_INCLUDE_DIRS}) +# list(APPEND INKSCAPE_LIBS ${Boost_LIBRARIES}) + +#find_package(OpenSSL) +#list(APPEND INKSCAPE_INCS_SYS ${OPENSSL_INCLUDE_DIR}) +#list(APPEND INKSCAPE_LIBS ${OPENSSL_LIBRARIES}) + +find_package(LibXslt REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${LIBXSLT_INCLUDE_DIR}) +list(APPEND INKSCAPE_LIBS ${LIBXSLT_LIBRARIES}) +add_definitions(${LIBXSLT_DEFINITIONS}) + +find_package(LibXml2 REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${LIBXML2_INCLUDE_DIR}) +list(APPEND INKSCAPE_LIBS ${LIBXML2_LIBRARIES}) +add_definitions(${LIBXML2_DEFINITIONS}) + +if(WITH_OPENMP) + find_package(OpenMP) + if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + list(APPEND INKSCAPE_CXX_FLAGS ${OpenMP_CXX_FLAGS}) + if(APPLE OR (MINGW AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")) + list(APPEND INKSCAPE_LIBS "-lomp") + endif() + mark_as_advanced(OpenMP_C_FLAGS) + mark_as_advanced(OpenMP_CXX_FLAGS) + # '-fopenmp' is in OpenMP_C_FLAGS, OpenMP_CXX_FLAGS and implies '-lgomp' + # uncomment explicit linking below if still needed: + set(HAVE_OPENMP ON) + #list(APPEND INKSCAPE_LIBS "-lgomp") # FIXME + else() + set(HAVE_OPENMP OFF) + set(WITH_OPENMP OFF) + endif() +endif() + +find_package(ZLIB REQUIRED) +list(APPEND INKSCAPE_INCS_SYS ${ZLIB_INCLUDE_DIRS}) +list(APPEND INKSCAPE_LIBS ${ZLIB_LIBRARIES}) + +if(WITH_GNU_READLINE) + pkg_check_modules(Readline readline) + if(Readline_FOUND) + message(STATUS "Found GNU Readline: ${Readline_LIBRARY}") + list(APPEND INKSCAPE_INCS_SYS ${Readline_INCLUDE_DIRS}) + list(APPEND INKSCAPE_LIBS ${Readline_LDFLAGS}) + else() + message(STATUS "Did not find GNU Readline") + set(WITH_GNU_READLINE OFF) + endif() +endif() + +if(WITH_IMAGE_MAGICK) + # we want "<" but pkg_check_modules only offers "<=" for some reason; let's hope nobody actually has 7.0.0 + pkg_check_modules(MAGICK ImageMagick++<=7) + if(MAGICK_FOUND) + set(WITH_GRAPHICS_MAGICK OFF) # prefer ImageMagick for now and disable GraphicsMagick if found + else() + set(WITH_IMAGE_MAGICK OFF) + endif() +endif() +if(WITH_GRAPHICS_MAGICK) + pkg_check_modules(MAGICK GraphicsMagick++) + if(NOT MAGICK_FOUND) + set(WITH_GRAPHICS_MAGICK OFF) + endif() +endif() +if(MAGICK_FOUND) + sanitize_ldflags_for_libs(MAGICK_LDFLAGS) + list(APPEND INKSCAPE_LIBS ${MAGICK_LDFLAGS}) + add_definitions(${MAGICK_CFLAGS_OTHER}) + list(APPEND INKSCAPE_INCS_SYS ${MAGICK_INCLUDE_DIRS}) + + set(WITH_MAGICK ON) # enable 'Extensions > Raster' +endif() + +set(ENABLE_NLS OFF) +if(WITH_NLS) + find_package(Gettext) + if(GETTEXT_FOUND) + message(STATUS "Found gettext + msgfmt to convert language files. Translation enabled") + set(ENABLE_NLS ON) + else(GETTEXT_FOUND) + message(STATUS "Cannot find gettext + msgfmt to convert language file. Translation won't be enabled") + set(WITH_NLS OFF) + endif(GETTEXT_FOUND) + find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) + if(GETTEXT_XGETTEXT_EXECUTABLE) + message(STATUS "Found xgettext. inkscape.pot will be re-created if missing.") + else() + message(STATUS "Did not find xgettext. inkscape.pot can't be re-created.") + endif() +endif(WITH_NLS) + +pkg_check_modules(SIGC++ REQUIRED sigc++-2.0 ) +sanitize_ldflags_for_libs(SIGC++_LDFLAGS) +list(APPEND INKSCAPE_LIBS ${SIGC++_LDFLAGS}) +list(APPEND INKSCAPE_CXX_FLAGS ${SIGC++_CFLAGS_OTHER} "-DSIGCXX_DISABLE_DEPRECATED") + +pkg_check_modules(EPOXY REQUIRED epoxy ) +sanitize_ldflags_for_libs(EPOXY_LDFLAGS) +list(APPEND INKSCAPE_LIBS ${EPOXY_LDFLAGS}) +list(APPEND INKSCAPE_CXX_FLAGS ${EPOXY_CFLAGS_OTHER}) + +if(WITH_X11) + find_package(X11 REQUIRED) + list(APPEND INKSCAPE_INCS_SYS ${X11_INCLUDE_DIRS}) + list(APPEND INKSCAPE_LIBS ${X11_LIBRARIES}) + add_definitions(-DHAVE_X11) + + pkg_get_variable(GTK3_TARGETS gtk+-3.0 targets) + if(NOT("${GTK3_TARGETS}" MATCHES "x11")) + message(FATAL_ERROR "GTK+3 doesn't targets X11, this is required for WITH_X11") + endif() +endif(WITH_X11) + +if(WITH_INTERNAL_CAIRO) + add_definitions(-DWITH_PATCHED_CAIRO) +endif() + +# end Dependencies + + + +# Set include directories and CXX flags +# (INKSCAPE_LIBS are set as target_link_libraries for inkscape_base in src/CMakeLists.txt) + +foreach(flag ${INKSCAPE_CXX_FLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +endforeach() +foreach(flag ${INKSCAPE_CXX_FLAGS_DEBUG}) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${flag}") +endforeach() + +# Add color output to ninja +if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + add_compile_options (-fdiagnostics-color) +endif () + +list(REMOVE_DUPLICATES INKSCAPE_LIBS) +list(REMOVE_DUPLICATES INKSCAPE_INCS_SYS) + +include_directories(${INKSCAPE_INCS}) +include_directories(SYSTEM ${INKSCAPE_INCS_SYS}) + +include(${CMAKE_CURRENT_LIST_DIR}/ConfigChecks.cmake) # TODO: Check if this needs to be "hidden" here + +unset(INKSCAPE_INCS) +unset(INKSCAPE_INCS_SYS) +unset(INKSCAPE_CXX_FLAGS) +unset(INKSCAPE_CXX_FLAGS_DEBUG) diff --git a/CMakeScripts/Dist.cmake b/CMakeScripts/Dist.cmake new file mode 100644 index 0000000..6ada40b --- /dev/null +++ b/CMakeScripts/Dist.cmake @@ -0,0 +1,82 @@ +# dist targets for various platforms + + +# get INKSCAPE_REVISION of the source +set(INKSCAPE_SOURCE_DIR ${CMAKE_SOURCE_DIR}) +include(CMakeScripts/inkscape-version.cmake) + +# set distribution prefix (used as filename for distributable packages) +set(INKSCAPE_DIST_PREFIX "${PROJECT_NAME}-${INKSCAPE_VERSION}") +if(INKSCAPE_REVISION_DATE AND INKSCAPE_REVISION_HASH) + set(INKSCAPE_DIST_PREFIX ${INKSCAPE_DIST_PREFIX}_${INKSCAPE_REVISION_DATE}_${INKSCAPE_REVISION_HASH}) +endif() + + + +# ----------------------------------------------------------------------------- +# 'dist' - generate source release tarball +# ----------------------------------------------------------------------------- + +message("INKSCAPE_DIST_PREFIX: ${INKSCAPE_DIST_PREFIX}") +add_custom_target(dist + COMMAND sed -i "s/unknown/${INKSCAPE_REVISION}/" ${CMAKE_SOURCE_DIR}/CMakeScripts/inkscape-version.cmake + COMMAND cmake --build ${CMAKE_BINARY_DIR} --target package_source + COMMAND git checkout ${CMAKE_SOURCE_DIR}/CMakeScripts/inkscape-version.cmake + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + VERBATIM) + + +# ----------------------------------------------------------------------------- +# 'dist-win' - Windows Targets +# ----------------------------------------------------------------------------- +if(WIN32) + if(HAVE_MINGW64) + set(bitness "x64") + else() + set(bitness "x86") + endif() + set(INKSCAPE_DIST_PREFIX ${INKSCAPE_DIST_PREFIX}-${bitness}) + + # ----------------------------------------------------------------------------- + # 'dist-win-7z' - generate binary 7z archive for Windows + # ----------------------------------------------------------------------------- + find_program(7z 7z PATHS "C:/Program Files/7-Zip" + "C:/Program Files (x86)/7-Zip") + if(NOT 7z) + set(7z echo "Could not find '7z'. Please add it to your search path." && exit 1 &&) + endif() + + # default target with very good but slow compression (needs approx. 10 GB RAM) + add_custom_target(dist-win-7z + COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_BINARY_DIR}/${INKSCAPE_DIST_PREFIX}.7z" + COMMAND ${7z} a -mx9 -md512m -mfb256 + "${CMAKE_BINARY_DIR}/${INKSCAPE_DIST_PREFIX}.7z" + "${CMAKE_INSTALL_PREFIX}") + + # fast target with moderate compression + add_custom_target(dist-win-7z-fast + COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_BINARY_DIR}/${INKSCAPE_DIST_PREFIX}.7z" + COMMAND ${7z} a + "${CMAKE_BINARY_DIR}/${INKSCAPE_DIST_PREFIX}.7z" + "${CMAKE_INSTALL_PREFIX}") + + add_dependencies(dist-win-7z install/strip) + add_dependencies(dist-win-7z-fast install/strip) + + # ----------------------------------------------------------------------------- + # 'dist-win-exe' - generate .exe installer (NSIS) for Windows + # ----------------------------------------------------------------------------- + add_custom_target(dist-win-exe COMMAND ${CMAKE_CPACK_COMMAND} -G NSIS) + add_dependencies(dist-win-exe install/strip) # TODO: we'd only need to depend on the "all" target + + # ----------------------------------------------------------------------------- + # 'dist-win-msi' - generate .exe installer (NSIS) for Windows + # ----------------------------------------------------------------------------- + add_custom_target(dist-win-msi COMMAND ${CMAKE_CPACK_COMMAND} -G WIX) + add_dependencies(dist-win-msi install/strip) # TODO: we'd only need to depend on the "all" target + + # ----------------------------------------------------------------------------- + # 'dist-win-all' - generate all 'dist' targets for Windows + # ----------------------------------------------------------------------------- + add_custom_target(dist-win-all DEPENDS dist-win-7z dist-win-exe dist-win-msi) +endif() diff --git a/CMakeScripts/HelperFunctions.cmake b/CMakeScripts/HelperFunctions.cmake new file mode 100644 index 0000000..4814cf4 --- /dev/null +++ b/CMakeScripts/HelperFunctions.cmake @@ -0,0 +1,244 @@ +# pkg_check_variable() - a function to retrieve pkg-config variables in CMake +# +# source: http://bloerg.net/2015/03/06/pkg-config-variables-in-cmake.html +function(pkg_check_variable _pkg _name) + find_package(PkgConfig REQUIRED) + string(TOUPPER ${_pkg} _pkg_upper) + string(TOUPPER ${_name} _name_upper) + string(REPLACE "-" "_" _pkg_upper ${_pkg_upper}) + string(REPLACE "-" "_" _name_upper ${_name_upper}) + set(_output_name "${_pkg_upper}_${_name_upper}") + + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_name} ${_pkg} + OUTPUT_VARIABLE _pkg_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + + set("${_output_name}" "${_pkg_result}" CACHE STRING "pkg-config variable ${_name} of ${_pkg}") +endfunction() + +# Join a cmake list of strings with a given glue character/string +# E.g. join(MY_RESULT, ",", "1; 2; 3;") returns "1, 2, 3" +function(join OUTPUT GLUE) + set(_TMP_RESULT "") + set(_GLUE "") # effective glue is empty at the beginning + foreach(arg ${ARGN}) + # Skip empty lines + if(NOT arg STREQUAL "\n") + set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}") + set(_GLUE "${GLUE}") + endif() + endforeach() + set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE) +endfunction() + + + +# Checks if the last call to execute_process() was successful and throws an error otherwise. +# ${result} and ${stderr} should hold the value of RESULT_VARIABLE and ERROR_VARIABLE respectively +# ${command} can be empty or the command that was executed during the last call of execute_process() +function(check_error result stderr command) + string(STRIP "${result}" result) + string(STRIP "${stderr}" stderr) + string(STRIP "${command}" command) + + if ("${command}" STREQUAL "") + set(command "Process") + else() + set(command "'${command}'") + endif() + + if("${result}" STREQUAL 0) + if(NOT "${stderr}" STREQUAL "") + MESSAGE(WARNING "${command} returned successfully but the following was output to stderr: ${stderr}") + endif() + else() + if("${stderr}" STREQUAL "") + MESSAGE(FATAL_ERROR "${command} failed with error code: ${result}") + else() + MESSAGE(FATAL_ERROR "${command} failed with error code: ${result} (stderr: ${stderr})") + endif() + endif() +endfunction(check_error) + + + +# Get the list of files installed by pacman for package ${package_name} and return it as ${file_list}. +# Paths are relative to the root directory of the MinGW installations (the directory returned by function "get_mingw_root()") +function(list_files_pacman package_name file_list) + set(MINGW_PACKAGE_PREFIX $ENV{MINGW_PACKAGE_PREFIX}) # e.g. "mingw-w64-x86_64" + get_filename_component(MINGW_PREFIX $ENV{MINGW_PREFIX} NAME) # e.g. "mingw64" + + # use pacman to list all files/folders installed by the package + execute_process( + COMMAND pacman -Ql ${MINGW_PACKAGE_PREFIX}-${package_name} + OUTPUT_FILE list_files_pacman_temp.txt + RESULT_VARIABLE res + ERROR_VARIABLE err + ) + check_error("${res}" "${err}" "pacman -Ql ${MINGW_PACKAGE_PREFIX}-${package_name}") + + # clean up output + execute_process( + COMMAND grep -v '/$' # get rid of folders + COMMAND sed -e 's/^${MINGW_PACKAGE_PREFIX}-${package_name} //' # remove package name + COMMAND sed -e 's/^\\/${MINGW_PREFIX}\\///' # remove root path + COMMAND tr '\n' '\;' # finally replace newlines with semicolon + INPUT_FILE list_files_pacman_temp.txt + OUTPUT_VARIABLE out + RESULT_VARIABLE res + ERROR_VARIABLE err + ) + check_error("${res}" "${err}" "Parsing result of 'pacman -Ql ${MINGW_PACKAGE_PREFIX}-${package_name}'") + + SET(${file_list} ${out} PARENT_SCOPE) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/list_files_pacman_temp.txt) +endfunction(list_files_pacman) + + + +# Get the list of files installed by pip for package ${package_name} and return it as ${file_list}. +# Paths are relative to the python distributions "site-packages" folder, i.e. "${root}/lib/python2.7/site-packages" +function(list_files_pip package_name file_list) + # use pip to show package information including full list of files installed by the package + execute_process( + COMMAND pip3 show -f ${package_name} + OUTPUT_FILE list_files_pip_temp.txt + RESULT_VARIABLE res + ERROR_VARIABLE err + ) + check_error("${res}" "${err}" "pip3 show -f ${package_name}") + + # clean up output + execute_process( + COMMAND sed -e '1,/Files:/d' # strip everything but the files list + COMMAND tr -d ' ' # strip spaces + COMMAND tr '\n' '\;' # finally replace newlines with semicolon + INPUT_FILE list_files_pip_temp.txt + OUTPUT_VARIABLE out + RESULT_VARIABLE res + ERROR_VARIABLE err + ) + check_error("${res}" "${err}" "Parsing result of 'pip3 show -f ${package_name}'") + + SET(${file_list} ${out} PARENT_SCOPE) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/list_files_pip_temp.txt) +endfunction(list_files_pip) + + + +# Install a list of files maintaining directory structure +# +# Options: +# FILES - the list of files (absolute or relative paths) +# ROOT - the root to search the files in (if file paths are relative) +# DESTINATION - the destination where to install files to +# COMPONENT - cpack component +# INCLUDE - a (list of) regular expression(s) specifying which files to include +# (omit or leave empty to include all files) +# EXCLUDE - a (list of) regular expression(s) specifying which files to exclude +# (takes precedence over include rules) +function(install_list) + # parse arguments + set(oneValueArgs ROOT DESTINATION COMPONENT) + set(multiValueArgs FILES INCLUDE EXCLUDE) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + #MESSAGE("ARG_FILES: ${ARG_FILES}" ) + #MESSAGE("ARG_ROOT: ${ARG_ROOT}" ) + #MESSAGE("ARG_DESTINATION: ${ARG_DESTINATION}" ) + #MESSAGE("ARG_INCLUDE: ${ARG_INCLUDE}" ) + #MESSAGE("ARG_EXCLUDE: ${ARG_EXCLUDE}" ) + #MESSAGE("ARG_UNPARSED_ARGUMENTS: ${ARG_UNPARSED_ARGUMENTS}" ) + + # install the files + foreach(file ${ARG_FILES}) + #MESSAGE("file: " ${file}) + + # check includes and excludes (excludes take precedence) + set(include_file 0) + if("${ARG_INCLUDE}" STREQUAL "") # start with the assumption to include all files by default + set(include_file 1) + endif() + foreach(include ${ARG_INCLUDE}) + if("${file}" MATCHES "${include}") + set(include_file 1) + endif() + endforeach() + foreach(exclude ${ARG_EXCLUDE}) + if("${file}" MATCHES "${exclude}") + set(include_file 0) + endif() + endforeach() + + # install if file should be included + if(${include_file}) + get_filename_component(directory ${file} DIRECTORY) + install( + FILES "${ARG_ROOT}/${file}" + DESTINATION "${ARG_DESTINATION}${directory}" + COMPONENT "${ARG_COMPONENT}" + ) + endif() + endforeach() +endfunction(install_list) + + + +# Parses "inkscape-preferences.cpp" to get the current list of interface translations +# +# Results are cached in the variables +# - INKSCAPE_LANGUAGE_CODES +# - INKSCAPE_LANGUAGE_NAMES +function(get_inkscape_languages) + if(NOT DEFINED INKSCAPE_LANGUAGE_CODES) + file(READ "${CMAKE_SOURCE_DIR}/src/ui/dialog/inkscape-preferences.cpp" file_content) + + string(REGEX MATCH "Glib::ustring languages\\[\\] = \\{([^\\}]+)\\};" languages "${file_content}") + string(REGEX REPLACE "Glib::ustring languages\\[\\] = \\{([^\\}]+)\\};" "\\1" languages "${languages}") + string(REGEX MATCHALL [[_\(\"([^\\"]+)\"\)]] languages "${languages}") + string(REGEX REPLACE [[_\(\"([^\\"]+)\"\)]] "\\1" languages "${languages}") + + string(REGEX MATCH "Glib::ustring langValues\\[\\] = \\{([^\\}]+)\\};" langValues "${file_content}") + string(REGEX REPLACE "Glib::ustring langValues\\[\\] = \\{([^\\}]+)\\};" "\\1" langValues "${langValues}") + string(REGEX MATCHALL [[\"([^\\"]*)\"]] langValues "${langValues}") + string(REGEX REPLACE [[\"([^\\"]*)\"]] "\\1" langValues "${langValues}") + + list(REMOVE_AT languages 0) + list(REMOVE_AT langValues 0) + + set(INKSCAPE_LANGUAGE_CODES "${langValues}" CACHE INTERNAL "") + set(INKSCAPE_LANGUAGE_NAMES "${languages}" CACHE INTERNAL "") + endif() +endfunction(get_inkscape_languages) + + + +# Filters out translated content from the list of files, then makes sure it is +# installed as part of the matching cpack translations component +# +# Filter is based on filename.${language_code}.ext naming scheme +function(filter_and_install_translated_content file_list destination) + set(remaining_files ${${file_list}}) + + get_inkscape_languages() + foreach(language_code ${INKSCAPE_LANGUAGE_CODES}) + set(translated_files ${remaining_files}) + set(regex "\\.${language_code}\\.[a-z]+$") + list(FILTER translated_files INCLUDE REGEX "${regex}") + list(FILTER remaining_files EXCLUDE REGEX "${regex}") + + if(translated_files) + if(WIN32) + set(COMP translations.${language_code_escaped}) + else() + set(COMP translations) + endif() + string(MAKE_C_IDENTIFIER "${language_code}" language_code_escaped) + install(FILES ${translated_files} + DESTINATION ${destination} + COMPONENT ${COMP}) + endif() + endforeach() + + set(${file_list} ${remaining_files} PARENT_SCOPE) +endfunction(filter_and_install_translated_content) diff --git a/CMakeScripts/HelperMacros.cmake b/CMakeScripts/HelperMacros.cmake new file mode 100644 index 0000000..0f7d755 --- /dev/null +++ b/CMakeScripts/HelperMacros.cmake @@ -0,0 +1,130 @@ +# A macro to replace slashes and spaces in a string with underscores +macro(SANITIZE_PATH _string_var) + string(REGEX REPLACE "[\\/ ]+" "_" ${_string_var} ${${_string_var}}) +endmacro() + + +macro(inkscape_source_group + sources) + + # Group by location on disk + source_group("Source Files" FILES CMakeLists.txt) + + foreach(_SRC ${sources}) + get_filename_component(_SRC_EXT ${_SRC} EXT) + if((${_SRC_EXT} MATCHES ".h") OR (${_SRC_EXT} MATCHES ".hpp")) + source_group("Header Files" FILES ${_SRC}) + else() + source_group("Source Files" FILES ${_SRC}) + endif() + endforeach() + + unset(_SRC) + unset(_SRC_EXT) +endmacro() + + +# only MSVC uses SOURCE_GROUP +macro(add_inkscape_lib + name + sources) + + add_library(${name} STATIC ${sources}) + + # works fine without having the includes + # listed is helpful for IDE's (QtCreator/MSVC) + inkscape_source_group("${sources}") +endmacro() + + +# A macro to append to the global source property +set_property(GLOBAL PROPERTY inkscape_global_SRC "") + +macro (add_inkscape_source + sources) + + foreach(_SRC ${ARGV}) + get_filename_component(_ABS_SRC ${_SRC} ABSOLUTE) + set_property(GLOBAL APPEND PROPERTY inkscape_global_SRC ${_ABS_SRC}) + endforeach() + unset(_SRC) + unset(_ABS_SRC) +endmacro() + +# A macro to append to the global source property +macro (add_inkscape_library + sources) + + foreach(_SRC ${ARGV}) + get_filename_component(_ABS_SRC ${_SRC} ABSOLUTE) + set_property(GLOBAL APPEND PROPERTY inkscape_global_SRC ${_ABS_SRC}) + endforeach() + unset(_SRC) + unset(_ABS_SRC) +endmacro() + +macro(INKSCAPE_PKG_CONFIG_FIND PREFIX MODNAME VERSION PATH_NAME PATH_SUFFIXE LIB_NAME) + if(VERSION) + pkg_check_modules(_${PREFIX} ${MODNAME}${VERSION}) + else(VERSION) + pkg_check_modules(_${PREFIX} ${MODNAME}) + endif(VERSION) + + find_path(${PREFIX}_INCLUDE_DIR + NAMES + ${PATH_NAME} + PATHS + ${_${PREFIX}_INCLUDEDIR} + /usr/include + /usr/local/include + /opt/local/include + /sw/include + $ENV{DEVLIBS_PATH}//include// + PATH_SUFFIXES + ${PATH_SUFFIXE} + ) + + find_library(${PREFIX}_LIBRARY + NAMES + ${LIB_NAME} + PATHS + ${_${PREFIX}_LIBDIR} + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + if (${PREFIX}_LIBRARY) + set(${PREFIX}_FOUND TRUE) + set(${PREFIX}_VERSION ${_${PREFIX}_VERSION}) + endif (${PREFIX}_LIBRARY) + + set(${PREFIX}_INCLUDE_DIRS + ${${PREFIX}_INCLUDE_DIR} + ) + + if (${PREFIX}_FOUND) + set(${PREFIX}_LIBRARIES + ${${PREFIX}_LIBRARIES} + ${${PREFIX}_LIBRARY} + ) + endif (${PREFIX}_FOUND) + + if (${PREFIX}_INCLUDE_DIRS AND ${PREFIX}_LIBRARIES) + set(${PREFIX}_FOUND TRUE) + endif (${PREFIX}_INCLUDE_DIRS AND ${PREFIX}_LIBRARIES) + + if (${PREFIX}_FOUND) + if (NOT ${PREFIX}_FIND_QUIETLY) + message(STATUS "Found ${MODNAME}: ${${PREFIX}_LIBRARIES}") + endif (NOT ${PREFIX}_FIND_QUIETLY) + else (${PREFIX}_FOUND) + if (${PREFIX}_FIND_REQUIRED) + message(FATAL_ERROR "Could not find ${MODNAME}") + endif (${PREFIX}_FIND_REQUIRED) + endif (${PREFIX}_FOUND) + + # show the _INCLUDE_DIRS and _LIBRARIES variables only in the advanced view + mark_as_advanced(${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARIES) +endmacro() diff --git a/CMakeScripts/InstallMSYS2.cmake b/CMakeScripts/InstallMSYS2.cmake new file mode 100644 index 0000000..9903eb8 --- /dev/null +++ b/CMakeScripts/InstallMSYS2.cmake @@ -0,0 +1,403 @@ +if(WIN32) + install(FILES + NEWS.md + README.md + DESTINATION .) + + # mingw-w64 dlls + # (use msys2checkdeps.py to list required libraries / check for missing or unused libraries) + file(GLOB MINGW_LIBS + ${MINGW_BIN}/LIBEAY32.dll + ${MINGW_BIN}/SSLEAY32.dll + ${MINGW_BIN}/imagequant.dll + ${MINGW_BIN}/lib2geom.dll + ${MINGW_BIN}/libLerc.dll + ${MINGW_BIN}/libaom.dll + ${MINGW_BIN}/libaspell-[0-9]*.dll + ${MINGW_BIN}/libatk-1.0-[0-9]*.dll + ${MINGW_BIN}/libatkmm-1.6-[0-9]*.dll + ${MINGW_BIN}/libboost_filesystem-mt.dll + ${MINGW_BIN}/libbrotlicommon.dll + ${MINGW_BIN}/libbrotlidec.dll + ${MINGW_BIN}/libbz2-[0-9]*.dll + ${MINGW_BIN}/libcairo-[0-9]*.dll + ${MINGW_BIN}/libcairo-gobject-[0-9]*.dll + ${MINGW_BIN}/libcairomm-1.0-[0-9]*.dll + ${MINGW_BIN}/libcdr-0.[0-9]*.dll + ${MINGW_BIN}/libcrypto-1_[0-9]*.dll + ${MINGW_BIN}/libcrypto-3*.dll + ${MINGW_BIN}/libcurl-[0-9]*.dll + ${MINGW_BIN}/libdatrie-[0-9]*.dll + ${MINGW_BIN}/libdav1d.dll + ${MINGW_BIN}/libde265-[0-9]*.dll + ${MINGW_BIN}/libdeflate.dll + ${MINGW_BIN}/libdouble-conversion.dll + ${MINGW_BIN}/libenchant-[0-9]*.dll + ${MINGW_BIN}/libepoxy-[0-9]*.dll + ${MINGW_BIN}/libexpat-[0-9]*.dll + ${MINGW_BIN}/libexslt-[0-9]*.dll + ${MINGW_BIN}/libffi-[0-9]*.dll + ${MINGW_BIN}/libfftw3-[0-9]*.dll + ${MINGW_BIN}/libfontconfig-[0-9]*.dll + ${MINGW_BIN}/libfreetype-[0-9]*.dll + ${MINGW_BIN}/libfribidi-[0-9]*.dll + ${MINGW_BIN}/libgc-[0-9]*.dll + ${MINGW_BIN}/libgdk-3-[0-9]*.dll + ${MINGW_BIN}/libgdk_pixbuf-2.0-[0-9]*.dll + ${MINGW_BIN}/libgdkmm-3.0-[0-9]*.dll + ${MINGW_BIN}/libgfortran-[0-9]*.dll + ${MINGW_BIN}/libgio-2.0-[0-9]*.dll + ${MINGW_BIN}/libgiomm-2.4-[0-9]*.dll + ${MINGW_BIN}/libgirepository-1.0-[0-9].dll + ${MINGW_BIN}/libglib-2.0-[0-9]*.dll + ${MINGW_BIN}/libglibmm-2.4-[0-9]*.dll + ${MINGW_BIN}/libgmodule-2.0-[0-9]*.dll + ${MINGW_BIN}/libgmp-[0-9]*.dll + ${MINGW_BIN}/libgobject-2.0-[0-9]*.dll + ${MINGW_BIN}/libgomp-[0-9]*.dll + ${MINGW_BIN}/libgraphite[0-9]*.dll + ${MINGW_BIN}/libgsl-[0-9]*.dll + ${MINGW_BIN}/libgslcblas-[0-9]*.dll + ${MINGW_BIN}/libgspell-1-[0-9]*.dll + ${MINGW_BIN}/libgtk-3-[0-9]*.dll + ${MINGW_BIN}/libgtkmm-3.0-[0-9]*.dll + ${MINGW_BIN}/libgtksourceview-4-[0-9]*.dll + ${MINGW_BIN}/libharfbuzz-[0-9]*.dll + ${MINGW_BIN}/libheif.dll + ${MINGW_BIN}/libiconv-[0-9]*.dll + ${MINGW_BIN}/libicudt[0-9]*.dll + ${MINGW_BIN}/libicuin[0-9]*.dll + ${MINGW_BIN}/libicuuc[0-9]*.dll + ${MINGW_BIN}/libidn2-[0-9]*.dll + ${MINGW_BIN}/libintl-[0-9]*.dll + ${MINGW_BIN}/libjbig-[0-9]*.dll + ${MINGW_BIN}/libjpeg-[0-9]*.dll + ${MINGW_BIN}/liblcms2-[0-9]*.dll + ${MINGW_BIN}/liblqr-1-[0-9]*.dll + ${MINGW_BIN}/liblzma-[0-9]*.dll + ${MINGW_BIN}/libmpdec-[0-9]*.dll + ${MINGW_BIN}/libmpfr-[0-9]*.dll + ${MINGW_BIN}/libncursesw6.dll + ${MINGW_BIN}/libnghttp2*.dll + ${MINGW_BIN}/libnspr[0-9]*.dll + ${MINGW_BIN}/libopenblas.dll + ${MINGW_BIN}/libopenjp2-[0-9]*.dll + ${MINGW_BIN}/libpanelw6.dll + ${MINGW_BIN}/libpango-1.0-[0-9]*.dll + ${MINGW_BIN}/libpangocairo-1.0-[0-9]*.dll + ${MINGW_BIN}/libpangoft2-1.0-[0-9]*.dll + ${MINGW_BIN}/libpangomm-1.4-[0-9]*.dll + ${MINGW_BIN}/libpangowin32-1.0-[0-9]*.dll + ${MINGW_BIN}/libpcre2-8-[0-9]*.dll + ${MINGW_BIN}/libpixman-1-[0-9]*.dll + ${MINGW_BIN}/libplc[0-9]*.dll + ${MINGW_BIN}/libplds[0-9]*.dll + ${MINGW_BIN}/libpng16-[0-9]*.dll + ${MINGW_BIN}/libpoppler-[0-9]*.dll + ${MINGW_BIN}/libpoppler-glib-[0-9]*.dll + ${MINGW_BIN}/libpotrace-[0-9]*.dll + ${MINGW_BIN}/libpsl-[0-9]*.dll + ${MINGW_BIN}/libquadmath-[0-9]*.dll + ${MINGW_BIN}/libraqm-[0-9]*.dll + ${MINGW_BIN}/libreadline8.dll + ${MINGW_BIN}/librevenge-0.[0-9]*.dll + ${MINGW_BIN}/librevenge-stream-0.[0-9]*.dll + ${MINGW_BIN}/librsvg-2-[0-9]*.dll + ${MINGW_BIN}/libsharpyuv-0.dll + ${MINGW_BIN}/libsigc-2.0-[0-9]*.dll + ${MINGW_BIN}/libsoup-2.4-[0-9]*.dll + ${MINGW_BIN}/libsqlite3-[0-9]*.dll + ${MINGW_BIN}/libssh2-[0-9]*.dll + ${MINGW_BIN}/libssl-1_[0-9]*.dll + ${MINGW_BIN}/libssl-3*.dll + ${MINGW_BIN}/libstdc++-[0-9]*.dll + ${MINGW_BIN}/libtermcap-[0-9]*.dll + ${MINGW_BIN}/libthai-[0-9]*.dll + ${MINGW_BIN}/libtiff-[0-9]*.dll + ${MINGW_BIN}/libunistring-[0-9]*.dll + ${MINGW_BIN}/libvisio-0.[0-9]*.dll + ${MINGW_BIN}/libwebp-[0-9]*.dll + ${MINGW_BIN}/libwebpdemux-[0-9]*.dll + ${MINGW_BIN}/libwebpmux-[0-9]*.dll + ${MINGW_BIN}/libwinpthread-[0-9]*.dll + ${MINGW_BIN}/libwmf-0-2-[0-9]*.dll + ${MINGW_BIN}/libwmflite-0-2-[0-9]*.dll + ${MINGW_BIN}/libwpd-0.[0-9]*.dll + ${MINGW_BIN}/libwpg-0.[0-9]*.dll + ${MINGW_BIN}/libxml2-[0-9]*.dll + ${MINGW_BIN}/libxslt-[0-9]*.dll + ${MINGW_BIN}/libx265.dll + ${MINGW_BIN}/libzstd.dll + ${MINGW_BIN}/nss[0-9]*.dll + ${MINGW_BIN}/nssutil[0-9]*.dll + ${MINGW_BIN}/rav1e.dll + ${MINGW_BIN}/smime[0-9]*.dll + ${MINGW_BIN}/tcl[0-9]*.dll + ${MINGW_BIN}/tk[0-9]*.dll + ${MINGW_BIN}/zlib1.dll) + INSTALL(FILES ${MINGW_LIBS} DESTINATION bin) + # There are differences for 64-Bit and 32-Bit build environments. + if(HAVE_MINGW64) + if($ENV{MSYSTEM} STREQUAL "CLANGARM64") + install(FILES + ${MINGW_BIN}/libc++.dll + ${MINGW_BIN}/libunwind.dll + DESTINATION bin) + else() + install(FILES + ${MINGW_BIN}/libgcc_s_seh-1.dll + DESTINATION bin) + endif() + else() + install(FILES + ${MINGW_BIN}/libgcc_s_dw2-1.dll + DESTINATION bin) + endif() + + # Install graphics-magick dlls + if(WITH_GRAPHICS_MAGICK) + install (DIRECTORY ${MINGW_LIB}/GraphicsMagick-1.3.38 + DESTINATION lib + FILES_MATCHING + PATTERN "*.dll" + PATTERN "*.la" + PATTERN "filters" EXCLUDE) + file(GLOB MAGICK_LIBS + ${MINGW_BIN}/libGraphicsMagick[+-]*.dll + ${MINGW_BIN}/libjxl.dll + ${MINGW_BIN}/libjxl_threads.dll + ${MINGW_BIN}/libltdl-[0-9]*.dll + ${MINGW_BIN}/libhwy.dll + ${MINGW_BIN}/libbrotlienc.dll) + install(FILES ${MAGICK_LIBS} DESTINATION bin) + endif() + + if(WITH_IMAGE_MAGICK) + file(GLOB MAGICK_LIBS ${MINGW_BIN}/libMagick*.dll) + install(FILES ${MAGICK_LIBS} DESTINATION bin) + endif() + + # Install hicolor/index.theme to avoid bug 1635207 + install(FILES + ${MINGW_PATH}/share/icons/hicolor/index.theme + DESTINATION share/icons/hicolor) + + install(DIRECTORY ${MINGW_PATH}/share/icons/Adwaita + DESTINATION share/icons) + install(CODE "execute_process(COMMAND gtk-update-icon-cache \${CMAKE_INSTALL_PREFIX}/share/icons/Adwaita)") + + # translations for libraries (we usually shouldn't need many) + get_inkscape_languages() + foreach(language_code ${INKSCAPE_LANGUAGE_CODES}) + string(MAKE_C_IDENTIFIER "${language_code}" language_code_escaped) + install(DIRECTORY ${MINGW_PATH}/share/locale/${language_code} + DESTINATION share/locale + COMPONENT translations.${language_code_escaped} + FILES_MATCHING + PATTERN "*glib20.mo" + PATTERN "*gtk30.mo" + PATTERN "*gspell-1.mo") + endforeach() + + install(DIRECTORY ${MINGW_PATH}/share/poppler + DESTINATION share) + + install(DIRECTORY ${MINGW_PATH}/share/glib-2.0/schemas + DESTINATION share/glib-2.0) + + install(DIRECTORY ${MINGW_PATH}/share/gtksourceview-4 + DESTINATION share) + + # fontconfig + install(DIRECTORY ${MINGW_PATH}/etc/fonts + DESTINATION etc + PATTERN "fonts.conf" EXCLUDE) + install(FILES ${MINGW_PATH}/share/fontconfig/conf.avail/70-no-bitmaps.conf + DESTINATION etc/fonts/conf.d) + # adjust fonts.conf + # - add "%localappdata%\Microsoft\Windows\Fonts" as font dir + # which is the default path for fonts installed per-user in Windows 10 (version 1809) + # - store font cache in non-temporary directory in "%localappdata%\fontconfig\cache" + set(fontdir_default "\\t^WINDOWSFONTDIR^") # the '^' are needed to escape angle brackets on Windows command shell + set(fontdir_additional "\\t^~/AppData/Local/Microsoft/Windows/Fonts^") + set(cachedir_default "\\t^/var/cache/fontconfig^") + set(cachedir_appdata "\\t^LOCAL_APPDATA_FONTCONFIG_CACHE^") + add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/etc/fonts/fonts.conf + COMMAND sed 's!${fontdir_default}!${fontdir_default}\\n${fontdir_additional}!' ${MINGW_PATH}/etc/fonts/fonts.conf | + sed 's!${cachedir_default}!${cachedir_appdata}\\n${cachedir_default}!' > ${CMAKE_BINARY_DIR}/etc/fonts/fonts.conf + MAIN_DEPENDENCY ${MINGW_PATH}/etc/fonts/fonts.conf + ) + add_custom_target(fonts_conf ALL DEPENDS ${CMAKE_BINARY_DIR}/etc/fonts/fonts.conf) + install(DIRECTORY ${CMAKE_BINARY_DIR}/etc/fonts + DESTINATION etc) + + # GTK 3.0 + install(DIRECTORY ${MINGW_LIB}/gtk-3.0 + DESTINATION lib + FILES_MATCHING + PATTERN "*.dll" + PATTERN "*.cache") + + install(DIRECTORY ${MINGW_PATH}/etc/gtk-3.0 + DESTINATION etc) + + install(DIRECTORY ${MINGW_LIB}/gdk-pixbuf-2.0 + DESTINATION lib + FILES_MATCHING + PATTERN "*.dll" + PATTERN "*.cache") + + # Typelibs for gtk, pango, cairo -> can be used in Python extensions + # ToDo: Automate the creation of this collection! + install (FILES + ${MINGW_LIB}/girepository-1.0/Atk-1.0.typelib + ${MINGW_LIB}/girepository-1.0/cairo-1.0.typelib + ${MINGW_LIB}/girepository-1.0/Gdk-3.0.typelib + ${MINGW_LIB}/girepository-1.0/GdkPixbuf-2.0.typelib + ${MINGW_LIB}/girepository-1.0/Gio-2.0.typelib + ${MINGW_LIB}/girepository-1.0/GLib-2.0.typelib + ${MINGW_LIB}/girepository-1.0/GModule-2.0.typelib + ${MINGW_LIB}/girepository-1.0/GObject-2.0.typelib + ${MINGW_LIB}/girepository-1.0/Gtk-3.0.typelib + ${MINGW_LIB}/girepository-1.0/HarfBuzz-0.0.typelib + ${MINGW_LIB}/girepository-1.0/Pango-1.0.typelib + ${MINGW_LIB}/girepository-1.0/PangoCairo-1.0.typelib + ${MINGW_LIB}/girepository-1.0/freetype2-2.0.typelib + DESTINATION lib/girepository-1.0) + + # Aspell dictionaries + install(DIRECTORY ${MINGW_LIB}/aspell-0.60 + DESTINATION lib + COMPONENT dictionaries) + + # Aspell backend for Enchant (gspell uses Enchant to access Aspell dictionaries) + install(FILES + ${MINGW_LIB}/enchant-2/enchant_aspell.dll + DESTINATION lib/enchant-2) + + # tcl/tk related files (required for tkinter) + install(DIRECTORY + ${MINGW_PATH}/lib/tcl8 + ${MINGW_PATH}/lib/tcl8.6 + ${MINGW_PATH}/lib/tk8.6 + DESTINATION lib) + + # Necessary to run extensions on windows if it is not in the path + if (HAVE_MINGW64) + install(FILES + ${MINGW_BIN}/gspawn-win64-helper.exe + ${MINGW_BIN}/gspawn-win64-helper-console.exe + DESTINATION bin) + else() + install(FILES + ${MINGW_BIN}/gspawn-win32-helper.exe + ${MINGW_BIN}/gspawn-win32-helper-console.exe + DESTINATION bin) + endif() + + # Install gdbus helper to avoid warnings printed to command line + # (GApplication unconditionally tries to establish a dbus connection) + install(FILES + ${MINGW_BIN}/gdbus.exe + DESTINATION bin) + + # Python (use executable names without version number for compatibility with python from python.org) + file(GLOB python_version ${MINGW_BIN}/libpython3.[0-9]*.dll) + string(REGEX REPLACE "${MINGW_BIN}/libpython(3\.[0-9]+)\.dll" "\\1" python_version ${python_version}) + + install(FILES + ${MINGW_BIN}/python3.exe + RENAME python.exe + DESTINATION bin + COMPONENT python) + install(FILES + ${MINGW_BIN}/python3w.exe + RENAME pythonw.exe + DESTINATION bin + COMPONENT python) + install(FILES + ${MINGW_BIN}/libpython${python_version}.dll + DESTINATION bin + COMPONENT python) + install(DIRECTORY ${MINGW_LIB}/python${python_version} + DESTINATION lib + COMPONENT python + PATTERN "python${python_version}/site-packages" EXCLUDE # specify individual packages to install below + PATTERN "python${python_version}/test" EXCLUDE # we don't need the Python testsuite + PATTERN "*.pyc" EXCLUDE + ) + + set(site_packages "lib/python${python_version}/site-packages") + # Python packages installed via pacman + set(packages + "python-lxml" "python-numpy" "python-pillow" "python-six" "python-cairo" "python-cssselect" + "python-gobject" "python-coverage" "python-pyserial" "python-packaging" "python-zstandard" "scour") + foreach(package ${packages}) + list_files_pacman(${package} paths) + install_list(FILES ${paths} + ROOT ${MINGW_PATH} + COMPONENT python + INCLUDE ${site_packages} # only include content from "site-packages" (we might consider to install everything) + EXCLUDE ".pyc$" + ) + endforeach() + + # Python packages for the extensions manager, and clipart importer extensions + set(packages + "python-appdirs" "python-msgpack" "python-lockfile" "python-cachecontrol" + "python-idna" "python-urllib3" "python-chardet" "python-certifi" "python-requests" "python-beautifulsoup4" "python-filelock") + foreach(package ${packages}) + list_files_pacman(${package} paths) + install_list(FILES ${paths} + ROOT ${MINGW_PATH} + COMPONENT extension_manager + INCLUDE ${site_packages} # only include content from "site-packages" (we might consider to install everything) + EXCLUDE ".pyc$" + ) + endforeach() + + # Python packages installed via pip + set(packages "") + foreach(package ${packages}) + list_files_pip(${package} paths) + install_list(FILES ${paths} + ROOT ${MINGW_PATH}/${site_packages} + DESTINATION ${site_packages}/ + COMPONENT python + EXCLUDE "^\\.\\.\\/" # exclude content in parent directories (notably scripts installed to /bin) + EXCLUDE ".pyc$" + ) + endforeach() + + install(CODE + "MESSAGE(\"Pre-compiling Python distribution to byte-code (.pyc files)\") + execute_process(COMMAND \${CMAKE_INSTALL_PREFIX}/bin/python -m compileall -qq \${CMAKE_INSTALL_PREFIX}/lib/python${python_version})" + COMPONENT python) + + # gdb + if (NOT $ENV{MSYSTEM} STREQUAL "CLANGARM64") + install(FILES + ${MINGW_BIN}/gdb.exe + ${MINGW_BIN}/libxxhash.dll + DESTINATION bin) + install(DIRECTORY + ${MINGW_PATH}/share/gdb + DESTINATION share + PATTERN "*.pyc" EXCLUDE) + install(FILES + packaging/win32/gdb_create_backtrace.bat + DESTINATION bin) + # convenience launcher + install(FILES + "packaging/win32/Run Inkscape and create debug trace.bat" + DESTINATION .) + endif() + + # convenience launchers + install(FILES + "packaging/win32/Run Inkscape !.bat" + "packaging/win32/Run Inkscape with GTK Inspector.bat" + DESTINATION .) + +endif() diff --git a/CMakeScripts/Modules/FindDoubleConversion.cmake b/CMakeScripts/Modules/FindDoubleConversion.cmake new file mode 100644 index 0000000..bd4c002 --- /dev/null +++ b/CMakeScripts/Modules/FindDoubleConversion.cmake @@ -0,0 +1,27 @@ +# - Try to find double-conversion +# Once done, this will define +# +# DoubleConversion_FOUND - system has double-conversion +# DoubleConversion_INCLUDE_DIRS - the double-conversion include directories +# DoubleConversion_LIBRARIES - link these to use double-conversion + +include(FindPackageHandleStandardArgs) + +find_library(DoubleConversion_LIBRARY double-conversion + PATHS ${DoubleConversion_LIBRARYDIR}) + +find_path(DoubleConversion_INCLUDE_DIR double-conversion/double-conversion.h + PATHS ${DoubleConversion_INCLUDEDIR}) + +find_package_handle_standard_args(DoubleConversion DEFAULT_MSG + DoubleConversion_LIBRARY + DoubleConversion_INCLUDE_DIR) + +mark_as_advanced( + DoubleConversion_LIBRARY + DoubleConversion_INCLUDE_DIR) + +if(DoubleConversion_FOUND) + set(DoubleConversion_LIBRARIES ${DoubleConversion_LIBRARY}) + set(DoubleConversion_INCLUDE_DIRS ${DoubleConversion_INCLUDE_DIR}) +endif() diff --git a/CMakeScripts/Modules/FindJeMalloc.cmake b/CMakeScripts/Modules/FindJeMalloc.cmake new file mode 100644 index 0000000..5c7aa2c --- /dev/null +++ b/CMakeScripts/Modules/FindJeMalloc.cmake @@ -0,0 +1,70 @@ +# - Find JeMalloc library +# Find the native JeMalloc includes and library +# This module defines +# JEMALLOC_INCLUDE_DIRS, where to find jemalloc.h, Set when +# JEMALLOC_INCLUDE_DIR is found. +# JEMALLOC_LIBRARIES, libraries to link against to use JeMalloc. +# JEMALLOC_ROOT_DIR, The base directory to search for JeMalloc. +# This can also be an environment variable. +# JEMALLOC_FOUND, If false, do not try to use JeMalloc. +# +# also defined, but not for general use are +# JEMALLOC_LIBRARY, where to find the JeMalloc library. + +#============================================================================= +# Copyright 2011 Blender Foundation. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# If JEMALLOC_ROOT_DIR was defined in the environment, use it. +IF(NOT JEMALLOC_ROOT_DIR AND NOT $ENV{JEMALLOC_ROOT_DIR} STREQUAL "") + SET(JEMALLOC_ROOT_DIR $ENV{JEMALLOC_ROOT_DIR}) +ENDIF() + +SET(_jemalloc_SEARCH_DIRS + ${JEMALLOC_ROOT_DIR} + /usr/local + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave +) + +FIND_PATH(JEMALLOC_INCLUDE_DIR + NAMES + jemalloc.h + HINTS + ${_jemalloc_SEARCH_DIRS} + PATH_SUFFIXES + include/jemalloc +) + +FIND_LIBRARY(JEMALLOC_LIBRARY + NAMES + jemalloc + HINTS + ${_jemalloc_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib + ) + +# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JeMalloc DEFAULT_MSG + JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR) + +IF(JEMALLOC_FOUND) + SET(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY}) + SET(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR}) +ENDIF(JEMALLOC_FOUND) + +MARK_AS_ADVANCED( + JEMALLOC_INCLUDE_DIR + JEMALLOC_LIBRARY +) diff --git a/CMakeScripts/Modules/FindNSIS.cmake b/CMakeScripts/Modules/FindNSIS.cmake new file mode 100644 index 0000000..21f80d8 --- /dev/null +++ b/CMakeScripts/Modules/FindNSIS.cmake @@ -0,0 +1,55 @@ +# - Try to find NSIS +# Once done this will define +# +# NSIS_ROOT_PATH - Set this variable to the root installation of NSIS +# +# Read-Only variables: +# +# NSIS_FOUND - system has NSIS +# NSIS_MAKE - NSIS creator executable +# +#============================================================================= +# Copyright (c) 2010-2013 Andreas Schneider +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# + +if (WIN32) + set(_NSIS_ROOT_HINTS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]") + + set(_NSIS_ROOT_PATHS + $ENV{PROGRAMFILES}/NSIS) + + find_path(NSIS_ROOT_PATH + NAMES + Include/Library.nsh + HINTS + ${_NSIS_ROOT_HINTS} + PATHS + ${_NSIS_ROOT_PATHS} + ) + mark_as_advanced(NSIS_ROOT_PATH) +endif (WIN32) + +find_program(NSIS_MAKE + NAMES + makensis + PATHS + ${NSIS_ROOT_PATH} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE) + +if (NSIS_MAKE) + set(NSIS_FOUND TRUE) +endif (NSIS_MAKE) + +mark_as_advanced(NSIS_MAKE) diff --git a/CMakeScripts/Modules/FindPopplerCairo.cmake b/CMakeScripts/Modules/FindPopplerCairo.cmake new file mode 100644 index 0000000..bde884e --- /dev/null +++ b/CMakeScripts/Modules/FindPopplerCairo.cmake @@ -0,0 +1,47 @@ +# - Try to find PopplerCairo +# Once done this will define +# +# POPPLER_FOUND - system has PopplerCairo +# POPPLER_INCLUDE_DIRS - the PopplerCairo include directory +# POPPLER_LIBRARIES - Link these to use PopplerCairo +# POPPLER_DEFINITIONS - Compiler switches required for using PopplerCairo +# +# Copyright (c) 2008 Joshua L. Blocher +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + +include(${CMAKE_CURRENT_LIST_DIR}/../HelperMacros.cmake) + +if (POPPLER_LIBRARIES AND POPPLER_INCLUDE_DIRS) + # in cache already + set(POPPLER_FOUND TRUE) +else (POPPLER_LIBRARIES AND POPPLER_INCLUDE_DIRS) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + INKSCAPE_PKG_CONFIG_FIND(POPPLER poppler >=0.20.0 poppler-config.h poppler poppler) + if (POPPLER_FOUND) + INKSCAPE_PKG_CONFIG_FIND(POPPLER_GLIB poppler-glib >=0.20.0 poppler/glib/poppler.h "" poppler-glib) + if (POPPLER_GLIB_FOUND) + list(APPEND POPPLER_INCLUDE_DIRS ${POPPLER_GLIB_INCLUDE_DIRS}) + list(APPEND POPPLER_LIBRARIES ${POPPLER_GLIB_LIBRARIES}) + INKSCAPE_PKG_CONFIG_FIND(CAIRO_SVG cairo-svg 0 cairo-svg.h cairo cairo) + if (CAIRO_SVG_FOUND) + list(APPEND POPPLER_INCLUDE_DIRS ${CAIRO_SVG_INCLUDE_DIRS}) + list(APPEND POPPLER_LIBRARIES ${CAIRO_SVG_LIBRARIES}) + endif (CAIRO_SVG_FOUND) + endif (POPPLER_GLIB_FOUND) + if (ENABLE_POPPLER_CAIRO) + INKSCAPE_PKG_CONFIG_FIND(POPPLER_CAIRO poppler-cairo >=0.20.0 cairo.h cairo cairo) + if (POPPLER_GLIB_FOUND AND POPPLER_CAIRO_FOUND AND NOT CAIRO_SVG_FOUND) + list(APPEND POPPLER_INCLUDE_DIRS ${POPPLER_CAIRO_INCLUDE_DIRS}) + list(APPEND POPPLER_LIBRARIES ${POPPLER_CAIRO_LIBRARIES}) + endif (POPPLER_GLIB_FOUND AND POPPLER_CAIRO_FOUND AND NOT CAIRO_SVG_FOUND) + endif (ENABLE_POPPLER_CAIRO) + endif (POPPLER_FOUND) + endif (PKG_CONFIG_FOUND) +endif (POPPLER_LIBRARIES AND POPPLER_INCLUDE_DIRS) diff --git a/CMakeScripts/Modules/FindPotrace.cmake b/CMakeScripts/Modules/FindPotrace.cmake new file mode 100644 index 0000000..9ab9952 --- /dev/null +++ b/CMakeScripts/Modules/FindPotrace.cmake @@ -0,0 +1,62 @@ +# POTRACE_FOUND - system has Potrace +# POTRACE_INCLUDE_DIRS - the Potrace include directory +# POTRACE_LIBRARIES - The libraries needed to use Potrace + +IF (POTRACE_LIBRARIES AND POTRACE_INCLUDE_DIRS) + # in cache already + SET(POTRACE_FOUND TRUE) +ELSE (POTRACE_LIBRARIES AND POTRACE_INCLUDE_DIRS) + FIND_PATH (POTRACE_INCLUDE_DIR + NAMES + potracelib.h + PATHS + /usr/include + /usr/local/include + $ENV{DEVLIBS_PATH}/include + PATH_SUFFIXES + potrace + ) + + FIND_LIBRARY (POTRACE_LIBRARY + NAMES + potrace + libpotrace + PATHS + /usr/lib + /usr/local/lib + $ENV{DEVLIBS_PATH}/lib + ) + + if (POTRACE_LIBRARY) + set (POTRACE_FOUND TRUE) + endif (POTRACE_LIBRARY) + + set (POTRACE_INCLUDE_DIRS + ${POTRACE_INCLUDE_DIR} + ) + + if (POTRACE_FOUND) + set(POTRACE_LIBRARIES + ${POTRACE_LIBRARIES} + ${POTRACE_LIBRARY} + ) + endif (POTRACE_FOUND) + + if (POTRACE_INCLUDE_DIRS AND POTRACE_LIBRARIES) + set(POTRACE_FOUND TRUE) + endif (POTRACE_INCLUDE_DIRS AND POTRACE_LIBRARIES) + + if (POTRACE_FOUND) + if (NOT Potrace_FIND_QUIETLY) + message(STATUS "Found Potrace: ${POTRACE_LIBRARIES}") + endif (NOT Potrace_FIND_QUIETLY) + else (POTRACE_FOUND) + if (Potrace_FIND_REQUIRED) + message(FATAL_ERROR "Could not find potrace") + endif (Potrace_FIND_REQUIRED) + endif (POTRACE_FOUND) + + # show the POTRACE_INCLUDE_DIRS and POTRACE_LIBRARIES variables only in the advanced view + MARK_AS_ADVANCED(POTRACE_INCLUDE_DIRS POTRACE_LIBRARIES) + +endif (POTRACE_LIBRARIES AND POTRACE_INCLUDE_DIRS) diff --git a/CMakeScripts/Pod2man.cmake b/CMakeScripts/Pod2man.cmake new file mode 100644 index 0000000..7405ad5 --- /dev/null +++ b/CMakeScripts/Pod2man.cmake @@ -0,0 +1,83 @@ +# Use pod2man to generate manual pages from .pod files + +# Usage: pod2man( ) +# +# E.g.: pod2man("/path/to/file/mypod.pod" "1.2.3" 1 "My Manual Pages") + +include(GNUInstallDirs) + +find_program(POD2MAN pod2man) +if(NOT POD2MAN) + message(STATUS "Could not find pod2man - man pages disabled") +endif() + +find_program(GZIP gzip) +if(NOT GZIP) + message(STATUS "Could not find gzip - man pages uncompressed") +endif() + +macro(pod2man PODFILE_FULL RELEASE SECTION CENTER) + get_filename_component(PODFILE ${PODFILE_FULL} NAME) + string(REPLACE "." ";" PODFILE_LIST ${PODFILE}) + list(GET PODFILE_LIST 0 NAME) + list(GET PODFILE_LIST 1 LANG) + string(TOUPPER ${NAME} NAME_UPCASE) + if(${LANG} STREQUAL "pod") + set(LANG "") + endif() + + if(NOT EXISTS ${PODFILE_FULL}) + message(FATAL_ERROR "Could not find pod file ${PODFILE_FULL} to generate man page") + endif(NOT EXISTS ${PODFILE_FULL}) + + if(POD2MAN) + if(LANG) + set(MANPAGE_TARGET "man-${NAME}-${LANG}") + set(MANFILE_TEMP "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${LANG}.tmp") + set(MANFILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${LANG}.${SECTION}") + set(MANFILE_FULL_GZ "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${LANG}.${SECTION}.gz") + set(MANFILE_DEST "${CMAKE_INSTALL_MANDIR}/${LANG}/man${SECTION}") + else() + set(MANPAGE_TARGET "man-${NAME}") + set(MANFILE_TEMP "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.tmp") + set(MANFILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECTION}") + set(MANFILE_FULL_GZ "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECTION}.gz") + set(MANFILE_DEST "${CMAKE_INSTALL_MANDIR}/man${SECTION}") + endif() + add_custom_command( + OUTPUT ${MANFILE_TEMP} + COMMAND ${POD2MAN} --utf8 --section="${SECTION}" --center="${CENTER}" + --release="${RELEASE}" --name="${NAME_UPCASE}" "${PODFILE_FULL}" "${MANFILE_TEMP}" + ) + + add_custom_command( + OUTPUT ${MANFILE_FULL} + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/fix-roff-punct "${MANFILE_TEMP}" > ${MANFILE_FULL} + DEPENDS ${MANFILE_TEMP} + ) + if(GZIP AND WITH_MANPAGE_COMPRESSION) + add_custom_command( + OUTPUT ${MANFILE_FULL_GZ} + COMMAND ${GZIP} -f -k --best -n "${MANFILE_FULL}" + DEPENDS ${MANFILE_FULL} + ) + add_custom_target(${MANPAGE_TARGET} ALL + DEPENDS ${MANFILE_FULL_GZ} + ) + install( + FILES ${MANFILE_FULL_GZ} + RENAME ${NAME}.${SECTION}.gz + DESTINATION ${MANFILE_DEST} + ) + else() + add_custom_target(${MANPAGE_TARGET} ALL + DEPENDS ${MANFILE_FULL} + ) + install( + FILES ${MANFILE_FULL} + RENAME ${NAME}.${SECTION} + DESTINATION ${MANFILE_DEST} + ) + endif() + endif() +endmacro(pod2man PODFILE NAME SECTION CENTER) diff --git a/CMakeScripts/UseGlibMarshal.cmake b/CMakeScripts/UseGlibMarshal.cmake new file mode 100644 index 0000000..8fabcaa --- /dev/null +++ b/CMakeScripts/UseGlibMarshal.cmake @@ -0,0 +1,40 @@ +# - This is a module to Generate files using Glib-Marshal +# Both the header and source files (.h and .cpp) +# Copyright 2008 - Joshua L. Blocher +# +# And it defines the following variables: +# GLIB_MARSHAL_PREFIX - The name of the files +# GLIB_MARSHAL_FILE - File to Generate from (.list) and to generate to (.h and .cpp) +# GLIB_MARSHAL_OUTPUT_HEADER - Result of Generation +# GLIB_MARSHAL_OUTPUT_CPP - Result of Generation +# GLIB_MARSHAL_OUTPUT_LOCATION - Where we are putting the Output + +find_program(GLIB_MARSHAL_EXECUTABLE NAMES glib-genmarshal PATHS /usr/local/bin ) + +macro(GLIB_MARSHAL GLIB_MARSHAL_PREFIX GLIB_MARSHAL_FILE GLIB_MARSHAL_OUTPUT_LOCATION) + if(GLIB_MARSHAL_EXECUTABLE) + set(GLIB_MARSHAL_OUTPUT_EXTRA_LINE "#include \"${GLIB_MARSHAL_FILE}.h\" \n" ) + + message(STATUS "Generating header and sourcefiles from ${GLIB_MARSHAL_FILE}.list (Glib-Marshal)") + execute_process(COMMAND ${GLIB_MARSHAL_EXECUTABLE} --prefix=${GLIB_MARSHAL_PREFIX} --header ${CMAKE_CURRENT_SOURCE_DIR}/${GLIB_MARSHAL_FILE}.list + OUTPUT_VARIABLE GLIB_MARSHAL_OUTPUT_HEADER ) + execute_process(COMMAND ${GLIB_MARSHAL_EXECUTABLE} --prefix=${GLIB_MARSHAL_PREFIX} --body ${CMAKE_CURRENT_SOURCE_DIR}/${GLIB_MARSHAL_FILE}.list + OUTPUT_VARIABLE GLIB_MARSHAL_OUTPUT_CPP ) + + # check whether the generated file is the same as the existing one + if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${GLIB_MARSHAL_FILE}.h) + file(READ ${CMAKE_CURRENT_BINARY_DIR}/${GLIB_MARSHAL_FILE}.h GLIB_MARSHAL_HEADER_OLD) + else() + set(GLIB_MARSHAL_HEADER_OLD "") + endif() + if(NOT GLIB_MARSHAL_HEADER_OLD STREQUAL GLIB_MARSHAL_OUTPUT_HEADER) + message(STATUS "${GLIB_MARSHAL_FILE}.h changed; overwriting") + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${GLIB_MARSHAL_FILE}.h "${GLIB_MARSHAL_OUTPUT_HEADER}") + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${GLIB_MARSHAL_FILE}.cpp "${GLIB_MARSHAL_OUTPUT_EXTRA_LINE}") + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/${GLIB_MARSHAL_FILE}.cpp "${GLIB_MARSHAL_OUTPUT_CPP}") + else() + message(STATUS "${GLIB_MARSHAL_FILE}.h unchanged") + endif() + endif() +endmacro() + diff --git a/CMakeScripts/UsePkgConfig.cmake b/CMakeScripts/UsePkgConfig.cmake new file mode 100644 index 0000000..86c2425 --- /dev/null +++ b/CMakeScripts/UsePkgConfig.cmake @@ -0,0 +1,103 @@ +# - pkg-config module for CMake +# +# Defines the following macros: +# +# PKGCONFIG_FOUND(package found) +# PKGCONFIG(package includedir libdir linkflags cflags) +# PKGCONFIG_VERSION(package version) +# PKGCONFIG_DEFINITION(package definition) + +# Calling PKGCONFIG_FOUND will fill into the argument the value of the package search's result +# e.g. PKGCONFIG_FOUND(libart-2.0 LIBART_FOUND) +# +# Calling PKGCONFIG_VERSION will fill the desired version into the argument, +# e.g. PKGCONFIG_VERSION(libart-2.0 LIBART_VERSION) +# Calling PKGCONFIG will fill the desired information into the 4 given arguments, +# e.g. PKGCONFIG(libart-2.0 LIBART_INCLUDE_DIR LIBART_LINK_DIR LIBART_LINK_FLAGS LIBART_CFLAGS) +# if pkg-config was NOT found or the specified software package doesn't exist, the +# variable will be empty when the function returns, otherwise they will contain the respective information +# +# Calling PKGCONFIG_VERSION will fill the desired version into the argument, +# e.g. PKGCONFIG_VERSION(libart-2.0 LIBART_VERSION) +# +# Calling PKGCONFIG_DEFINITION will fill the definition (e.g -D_REENTRANT) into the argument, +# e.g. PKGCONFIG_DEFINITION(libart-2.0 LIBART_DEFINITION) + +find_program(PKGCONFIG_EXECUTABLE NAMES pkg-config PATHS /usr/local/bin ) + +macro(STRIP_NEWLINES _string_var) + string(REGEX REPLACE "[\n\r]+" "" ${_string_var} ${${_string_var}}) +endmacro(STRIP_NEWLINES _string_var) + +macro(PKGCONFIG_FOUND _package _found) + # reset the variable at the beginning + set(${_found}) + + # if pkg-config has been found + if(PKGCONFIG_EXECUTABLE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --print-errors --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull ) + if(${_pkgconfigDevNull}) + message(STATUS "${_pkgconfigDevNull}") + endif(${_pkgconfigDevNull}) + + if(NOT _return_VALUE) + set(${_found} "TRUE") + endif(NOT _return_VALUE) + endif(PKGCONFIG_EXECUTABLE) +endmacro(PKGCONFIG_FOUND _found) + +macro(PKGCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags) + # reset the variables at the beginning + set(${_include_DIR}) + set(${_link_DIR}) + set(${_link_FLAGS}) + set(${_cflags}) + + # if pkg-config has been found + if(PKGCONFIG_EXECUTABLE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull ) + + # and if the package of interest also exists for pkg-config, then get the information + if(NOT _return_VALUE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=includedir OUTPUT_VARIABLE ${_include_DIR} ) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=libdir OUTPUT_VARIABLE ${_link_DIR} ) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --libs OUTPUT_VARIABLE ${_link_FLAGS} ) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --cflags OUTPUT_VARIABLE ${_cflags} ) + strip_newlines(${_cflags}) + endif(NOT _return_VALUE) + endif(PKGCONFIG_EXECUTABLE) +endmacro(PKGCONFIG _include_DIR _link_DIR _link_FLAGS _cflags) + +macro(PKGCONFIG_VERSION _package _version) + # reset the variables at the beginning + set(${_version}) + + # if pkg-config has been found + if(PKGCONFIG_EXECUTABLE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS --print-errors ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull ) + + # and if the package of interest also exists for pkg-config, then get the information + if(NOT _return_VALUE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS --print-errors ${_package} --modversion OUTPUT_VARIABLE ${_version} ) + endif(NOT _return_VALUE) + endif(PKGCONFIG_EXECUTABLE) +endmacro(PKGCONFIG_VERSION _package _version) + +mark_as_advanced(PKGCONFIG_EXECUTABLE) + +macro(PKGCONFIG_DEFINITION _package _definition) + # reset the variables at the beginning + set(${_definition}) + + # if pkg-config has been found + if(PKGCONFIG_EXECUTABLE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS --print-errors ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull ) + + # and if the package of interest also exists for pkg-config, then get the information + if(NOT _return_VALUE) + exec_program(${PKGCONFIG_EXECUTABLE} ARGS --print-errors ${_package} --cflags-only-other OUTPUT_VARIABLE ${_definition} ) + endif(NOT _return_VALUE) + endif(PKGCONFIG_EXECUTABLE) +endmacro(PKGCONFIG_DEFINITION _package _definition) + +mark_as_advanced(PKGCONFIG_EXECUTABLE) diff --git a/CMakeScripts/cmake_consistency_check.py b/CMakeScripts/cmake_consistency_check.py new file mode 100755 index 0000000..d79c480 --- /dev/null +++ b/CMakeScripts/cmake_consistency_check.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python3 + +# $Id: cmake_consistency_check.py 38869 2011-07-31 03:15:37Z campbellbarton $ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributor(s): Campbell Barton +# +# ***** END GPL LICENSE BLOCK ***** + +# + +import sys +if not sys.version.startswith("3"): + print("\nPython3.x needed, found %s.\nAborting!\n" % + sys.version.partition(" ")[0]) + sys.exit(1) + +from cmake_consistency_check_config import ( + IGNORE, + UTF8_CHECK, + SOURCE_DIR, +) + + +import os +from os.path import join, dirname, normpath, splitext + +global_h = set() +global_c = set() +global_refs = {} + + +def replace_line(f, i, text, keep_indent=True): + file_handle = open(f, 'r') + data = file_handle.readlines() + file_handle.close() + + l = data[i] + ws = l[:len(l) - len(l.lstrip())] + + data[i] = "%s%s\n" % (ws, text) + + file_handle = open(f, 'w') + file_handle.writelines(data) + file_handle.close() + + +def source_list(path, filename_check=None): + for dirpath, dirnames, filenames in os.walk(path): + + # skip '.git' + if dirpath.startswith("."): + continue + + for filename in filenames: + if filename_check is None or filename_check(filename): + yield os.path.join(dirpath, filename) + + +# extension checking +def is_cmake(filename): + ext = splitext(filename)[1] + return (ext == ".cmake") or (filename == "CMakeLists.txt") + + +def is_c_header(filename): + ext = splitext(filename)[1] + return (ext in {".h", ".hpp", ".hxx", ".hh"}) + + +def is_c(filename): + ext = splitext(filename)[1] + return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"}) + + +def is_c_any(filename): + return is_c(filename) or is_c_header(filename) + + +def cmake_get_src(f): + + sources_h = [] + sources_c = [] + + filen = open(f, "r", encoding="utf8") + it = iter(filen) + found = False + i = 0 + # print(f) + + def is_definition(l, f, i, name): + if l.startswith("unset("): + return False + + if ('set(%s' % name) in l or ('set(' in l and l.endswith(name)): + if len(l.split()) > 1: + raise Exception("strict formatting not kept 'set(%s*' %s:%d" % (name, f, i)) + return True + + if ("list(APPEND %s" % name) in l or ('list(APPEND ' in l and l.endswith(name)): + if l.endswith(")"): + raise Exception("strict formatting not kept 'list(APPEND %s...)' on 1 line %s:%d" % (name, f, i)) + return True + + while it is not None: + context_name = "" + while it is not None: + i += 1 + try: + l = next(it) + except StopIteration: + it = None + break + l = l.strip() + if not l.startswith("#"): + found = is_definition(l, f, i, "SRC") + if found: + context_name = "SRC" + break + found = is_definition(l, f, i, "INC") + if found: + context_name = "INC" + break + + if found: + cmake_base = dirname(f) + + while it is not None: + i += 1 + try: + l = next(it) + except StopIteration: + it = None + break + + l = l.strip() + + if not l.startswith("#"): + + if ")" in l: + if l.strip() != ")": + raise Exception("strict formatting not kept '*)' %s:%d" % (f, i)) + break + + # replace dirs + l = l.replace("${CMAKE_CURRENT_SOURCE_DIR}", cmake_base) + l = l.strip('"') + + if not l: + pass + elif l.startswith("$"): + if context_name == "SRC": + # assume if it ends with context_name we know about it + if not l.split("}")[0].endswith(context_name): + print("Can't use var '%s' %s:%d" % (l, f, i)) + elif len(l.split()) > 1: + raise Exception("Multi-line define '%s' %s:%d" % (l, f, i)) + else: + new_file = normpath(join(cmake_base, l)) + + if context_name == "SRC": + if is_c_header(new_file): + sources_h.append(new_file) + global_refs.setdefault(new_file, []).append((f, i)) + elif is_c(new_file): + sources_c.append(new_file) + global_refs.setdefault(new_file, []).append((f, i)) + elif l in {"PARENT_SCOPE", }: + # cmake var, ignore + pass + elif new_file.endswith(".list"): + pass + elif new_file.endswith(".def"): + pass + elif new_file.endswith(".cl"): # opencl + pass + elif new_file.endswith(".cu"): # cuda + pass + elif new_file.endswith(".osl"): # open shading language + pass + elif new_file.endswith(".glsl"): + pass + else: + raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file)) + + elif context_name == "INC": + if os.path.isdir(new_file): + new_path_rel = os.path.relpath(new_file, cmake_base) + + if new_path_rel != l: + print("overly relative path:\n %s:%d\n %s\n %s" % (f, i, l, new_path_rel)) + + # # Save time. just replace the line + # replace_line(f, i - 1, new_path_rel) + + else: + raise Exception("non existent include %s:%d -> %s" % (f, i, new_file)) + + # print(new_file) + + global_h.update(set(sources_h)) + global_c.update(set(sources_c)) + ''' + if not sources_h and not sources_c: + raise Exception("No sources %s" % f) + + sources_h_fs = list(source_list(cmake_base, is_c_header)) + sources_c_fs = list(source_list(cmake_base, is_c)) + ''' + # find missing C files: + ''' + for ff in sources_c_fs: + if ff not in sources_c: + print(" missing: " + ff) + ''' + + # reset + del sources_h[:] + del sources_c[:] + + filen.close() + + +def is_ignore(f, ignore_used): + for index, ig in enumerate(IGNORE): + if ig in f: + ignore_used[index] = True + return True + return False + + +def main(): + + print("Scanning:", SOURCE_DIR) + + for cmake in source_list(SOURCE_DIR, is_cmake): + cmake_get_src(cmake) + + # First do stupid check, do these files exist? + print("\nChecking for missing references:") + is_err = False + errs = [] + for f in (global_h | global_c): + + if not os.path.exists(f): + refs = global_refs[f] + if refs: + for cf, i in refs: + errs.append((cf, i)) + else: + raise Exception("CMake referenecs missing, internal error, aborting!") + is_err = True + + errs.sort() + errs.reverse() + for cf, i in errs: + print("%s:%d" % (cf, i)) + # Write a 'sed' script, useful if we get a lot of these + # print("sed '%dd' '%s' > '%s.tmp' ; mv '%s.tmp' '%s'" % (i, cf, cf, cf, cf)) + + if is_err: + raise Exception("CMake referenecs missing files, aborting!") + del is_err + del errs + + ignore_used = [False] * len(IGNORE) + + # now check on files not accounted for. + print("\nC/C++ Files CMake does not know about...") + for cf in sorted(source_list(SOURCE_DIR, is_c)): + if not is_ignore(cf, ignore_used): + if cf not in global_c: + print("missing_c: ", cf) + + # check if automake builds a corrasponding .o file. + ''' + if cf in global_c: + out1 = os.path.splitext(cf)[0] + ".o" + out2 = os.path.splitext(cf)[0] + ".Po" + out2_dir, out2_file = out2 = os.path.split(out2) + out2 = os.path.join(out2_dir, ".deps", out2_file) + if not os.path.exists(out1) and not os.path.exists(out2): + print("bad_c: ", cf) + ''' + + print("\nC/C++ Headers CMake does not know about...") + for hf in sorted(source_list(SOURCE_DIR, is_c_header)): + if not is_ignore(hf, ignore_used): + if hf not in global_h: + print("missing_h: ", hf) + + if UTF8_CHECK: + # test encoding + import traceback + for files in (global_c, global_h): + for f in sorted(files): + if os.path.exists(f): + # ignore outside of our source tree + if "extern" not in f: + i = 1 + try: + for l in open(f, "r", encoding="utf8"): + i += 1 + except UnicodeDecodeError: + print("Non utf8: %s:%d" % (f, i)) + if i > 1: + traceback.print_exc() + + # Check ignores aren't stale + print("\nCheck for unused 'IGNORE' paths...") + for index, ig in enumerate(IGNORE): + if not ignore_used[index]: + print("unused ignore: %r" % ig) + + +if __name__ == "__main__": + main() diff --git a/CMakeScripts/cmake_consistency_check_config.py b/CMakeScripts/cmake_consistency_check_config.py new file mode 100644 index 0000000..94bec1d --- /dev/null +++ b/CMakeScripts/cmake_consistency_check_config.py @@ -0,0 +1,55 @@ +import os + +IGNORE = ( + # dirs + "/cxxtest/", + "/dom/work/", + "/src/extension/dxf2svg/", + "/test/", + + # files + "buildtool.cpp", + "src/inkscape-x64.rc", + "src/inkview-x64.rc", + "packaging/macosx/ScriptExec/main.c", + "share/ui/keybindings.rc", + "src/deptool.cpp", + "src/display/nr-filter-skeleton.cpp", + "src/display/testnr.cpp", + "src/dom/io/httpclient.cpp", + "src/dom/odf/SvgOdg.cpp", + "src/dom/xmlwriter.cpp", + "src/inkview.cpp", + "src/inkview.rc", + "src/io/streamtest.cpp", + "src/libcola/cycle_detector.cpp", + "src/libnr/nr-compose-reference.cpp", + "src/libnr/testnr.cp", + "src/live_effects/lpe-skeleton.cpp", + "src/svg/test-stubs.cpp", + "src/winconsole.cpp", + + # header files + "share/filters/filters.svg.h", + "share/palettes/palettes.h", + "share/paint/patterns.svg.h", + "share/templates/templates.h", + "share/symbols/symbols.h", + "src/libcola/cycle_detector.h", + "src/libnr/in-svg-plane-test.h", + "src/libnr/nr-point-fns-test.h", + "src/libnr/nr-translate-test.h", + "src/svg/test-stubs.h", + + # generated files, created by an in-source build + "CMakeFiles/CompilerIdC/CMakeCCompilerId.c", + "CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp", + "src/helper/sp-marshal.cpp", + "src/helper/sp-marshal.h", + "src/inkscape-version.cpp", + "config.h", + ) + +UTF8_CHECK = False + +SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(__file__), "..")))) diff --git a/CMakeScripts/cmake_uninstall.cmake.in b/CMakeScripts/cmake_uninstall.cmake.in new file mode 100644 index 0000000..2037e36 --- /dev/null +++ b/CMakeScripts/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/CMakeScripts/inkscape-version.cmake b/CMakeScripts/inkscape-version.cmake new file mode 100644 index 0000000..a100f9a --- /dev/null +++ b/CMakeScripts/inkscape-version.cmake @@ -0,0 +1,52 @@ +# This is called by cmake as an extermal process from +# ./src/CMakeLists.txt and creates inkscape-version.cpp +# +# It's also included directly in ./CMakeScripts/Dist.cmake to +# determine INKSCAPE_REVISION, INKSCAPE_REVISION_HASH and INKSCAPE_REVISION_DATE +# for the 'dist' targets +# +# These variables are defined by the caller, matching the CMake equivilents. +# - ${INKSCAPE_SOURCE_DIR} +# - ${INKSCAPE_BINARY_DIR} + +set(INKSCAPE_REVISION "0e150ed6c4, 2023-07-21") + +if(EXISTS ${INKSCAPE_SOURCE_DIR}/.git) + execute_process(COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${INKSCAPE_SOURCE_DIR} + OUTPUT_VARIABLE INKSCAPE_REVISION_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND git log -n 1 --pretty=%cd --date=short + WORKING_DIRECTORY ${INKSCAPE_SOURCE_DIR} + OUTPUT_VARIABLE INKSCAPE_REVISION_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(INKSCAPE_REVISION "${INKSCAPE_REVISION_HASH}, ${INKSCAPE_REVISION_DATE}") + + execute_process(COMMAND + git status -s ${INKSCAPE_SOURCE_DIR}/src + WORKING_DIRECTORY ${INKSCAPE_SOURCE_DIR} + OUTPUT_VARIABLE INKSCAPE_SOURCE_MODIFIED + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT INKSCAPE_SOURCE_MODIFIED STREQUAL "") + set(INKSCAPE_REVISION "${INKSCAPE_REVISION}, custom") + endif() +elseif(EXISTS ${INKSCAPE_SOURCE_DIR}/debian/git-build-recipe.manifest) + # workaround for debian packaging in ppa (where we have no repo) + # TODO: figure out how to match this to standard build environments + execute_process(COMMAND sed -n "s/.*deb-version\\s*//p" git-build-recipe.manifest + WORKING_DIRECTORY ${INKSCAPE_SOURCE_DIR}/debian + OUTPUT_VARIABLE DEB_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(INKSCAPE_REVISION "${DEB_VERSION}") +endif() + +if(${INKSCAPE_REVISION_DATE} MATCHES "^([0-9][0-9][0-9][0-9])-[0-9][0-9]-[0-9][0-9]$") + set(INKSCAPE_BUILD_YEAR ${CMAKE_MATCH_1}) +else() + string(TIMESTAMP INKSCAPE_BUILD_YEAR %Y UTC) +endif() + +if(NOT "${INKSCAPE_BINARY_DIR}" STREQUAL "") + message("revision is " ${INKSCAPE_REVISION}) + configure_file(${INKSCAPE_BINARY_DIR}/src/inkscape-version.cpp.in ${INKSCAPE_BINARY_DIR}/src/inkscape-version.cpp) +endif() -- cgit v1.2.3