From 5b9d51daa1a0b216bb1de1a8605339891328f294 Mon Sep 17 00:00:00 2001 From: Rogier Date: Mon, 26 May 2014 21:26:27 +0200 Subject: [PATCH] Improve installation and package generation; add deb and rpm Minetestmapper can now be installed into a proper directory hierarchy (instead of all files being dumped into /usr/local/. for instance.) Non-hierarchical installation (or creation of a non-hierarchical archive) is also still supported, and remains the default, for backwards compatibility. Packaging on windows remains unchanged, due to lack of infrastructure :-) --- CMakeCPackLists.txt | 20 +++++ CMakeLists.txt | 188 +++++++++++++++++++++++++++++++++++----- README.rst | 28 ++++++ cmake_config.h.in | 2 + package-description.txt | 23 +++++ 5 files changed, 241 insertions(+), 20 deletions(-) create mode 100644 CMakeCPackLists.txt create mode 100644 package-description.txt diff --git a/CMakeCPackLists.txt b/CMakeCPackLists.txt new file mode 100644 index 0000000..fe6710f --- /dev/null +++ b/CMakeCPackLists.txt @@ -0,0 +1,20 @@ + +if(CPACK_GENERATOR STREQUAL "TGZ") + if(CPACK_TGZ_PACKAGE_FILE_NAME) + set(CPACK_PACKAGE_FILE_NAME "${CPACK_TGZ_PACKAGE_FILE_NAME}") + endif(CPACK_TGZ_PACKAGE_FILE_NAME) +endif(CPACK_GENERATOR STREQUAL "TGZ") + +if(CPACK_GENERATOR STREQUAL "DEB") + if(CPACK_DEBIAN_PACKAGE_FILE_NAME) + set(CPACK_PACKAGE_FILE_NAME "${CPACK_DEBIAN_PACKAGE_FILE_NAME}") + endif(CPACK_DEBIAN_PACKAGE_FILE_NAME) +endif(CPACK_GENERATOR STREQUAL "DEB") + +if(CPACK_GENERATOR STREQUAL "RPM") + message(WARNING "cpack's rpm packaging code currently produces packages that have a directory conflict with a system package on fedora\nThe rpm package will probably not be installable unless --replacefiles is used") + if(CPACK_RPM_PACKAGE_FILE_NAME) + set(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_FILE_NAME}") + endif(CPACK_RPM_PACKAGE_FILE_NAME) +endif(CPACK_GENERATOR STREQUAL "RPM") + diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d3149f..a365286 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,11 @@ cmake_minimum_required(VERSION 2.6) cmake_policy(SET CMP0003 NEW) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -# Try to compute a sensible version number. +if(WIN32) + message(WARNING "Thanks for using minetestmapper on Windows.\nAs I do not have a windows computer at my disposal, I have not been able\nto test some windows-specific parts.\nPlease let me know if minetestmapper compiles OK, and if it runs fine.\nThanks!\n(Contact me via github)") +endif(WIN32) + +# Try to compute a useful version number. (goal: uniquely identify the commit used to generate it) # Prefer the output of git describe (if available) # Else, use a stored version, and a checksum of the files (and hope that is dependable) @@ -213,6 +217,7 @@ if(NOT USE_SQLITE3 AND NOT USE_LEVELDB AND NOT USE_REDIS) message(SEND_ERROR "No database backends are configured, or none could be found") endif(NOT USE_SQLITE3 AND NOT USE_LEVELDB AND NOT USE_REDIS) + include_directories( "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" @@ -221,12 +226,6 @@ include_directories( ${ZLIB_INCLUDE_DIR} ) -configure_file( - "${PROJECT_SOURCE_DIR}/cmake_config.h.in" - "${PROJECT_BINARY_DIR}/cmake_config.h" -) -add_definitions ( -DUSE_CMAKE_CONFIG_H ) - set(mapper_SRCS PixelAttributes.cpp PlayerAttributes.cpp @@ -261,28 +260,177 @@ target_link_libraries( ${ZLIB_LIBRARY} ) -install(FILES "AUTHORS" DESTINATION ".") -install(FILES "COPYING" DESTINATION ".") -install(FILES "README.rst" DESTINATION ".") -install(FILES "colors.txt" DESTINATION ".") # CPack -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Overview mapper for Minetest") +file(GLOB META_FILES RELATIVE "${CMAKE_HOME_DIRECTORY}" AUTHORS COPYING LICENSE.* README.rst) + +#set(CPACK_SET_DESTDIR ON) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Map generator for Minetest") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_HOME_DIRECTORY}/package-description.txt") set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) -set(CPACK_PACKAGE_VENDOR "celeron55") -set(CPACK_PACKAGE_CONTACT "Perttu Ahola ") +set(CPACK_PACKAGE_VERSION_PATCH 1) +set(CPACK_PACKAGE_VENDOR "Minetestmapper") +set(CPACK_PACKAGE_CONTACT "(Unknown)") +set(CPACK_PACKAGE_URL "https://github.com/Rogier-5/minetest-mapper-cpp") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}-${VERSION_STRING}") +set(CPACK_PACKAGE_EXECUTABLES minetestmapper) +set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CMakeCPackLists.txt") + +# Make install as root leaves a root-owned file behind that interferes +# with package creation - remove it. +if(EXISTS install_manifest.txt) + file(REMOVE install_manifest.txt) +endif(EXISTS install_manifest.txt) + +set(ARCHIVE_PACKAGE_NAME "" CACHE STRING "Name of the .zip / .tar.gz archive package to be created by cpack (without extension)") +if(NOT WIN32) + set(CREATE_FLAT_PACKAGE TRUE CACHE BOOL "Create the .tar.gz package without included directory hierarchy (must be OFF for 'make install' and to create .deb, .rpm packages)") +endif(NOT WIN32) if(WIN32) - install(FILES "${PROJECT_BINARY_DIR}/minetestmapper.exe" DESTINATION ".") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") + set(PACKAGING_FLAT 1) set(CPACK_GENERATOR ZIP) -else() - install(FILES "${PROJECT_BINARY_DIR}/minetestmapper" DESTINATION ".") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-linux") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") + + install(FILES ${META_FILES} DESTINATION ".") + install(FILES "colors.txt" DESTINATION ".") + install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper.exe" DESTINATION ".") + +elseif(CREATE_FLAT_PACKAGE) + set(PACKAGING_FLAT 1) + message(WARNING "CREATE_FLAT_PACKAGE is set ON: creating a flat package.\nFor 'make install', .deb and .rpm packages, CREATE_FLAT_PACKAGE must be OFF") set(CPACK_GENERATOR TGZ) set(CPACK_SOURCE_GENERATOR TGZ) -endif() + if(ARCHIVE_PACKAGE_NAME) + set(CPACK_TGZ_PACKAGE_FILE_NAME "${ARCHIVE_PACKAGE_NAME}") + else(ARCHIVE_PACKAGE_NAME) + if (APPLE) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_MAJOR}-MacOSX-flat") + else(APPLE) + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_MAJOR}-Linux-flat") + endif(APPLE) + endif(ARCHIVE_PACKAGE_NAME) + message(STATUS "Flat archive package name: ${CPACK_PACKAGE_FILE_NAME}.tar.gz") + + install(FILES ${META_FILES} DESTINATION ".") + install(FILES "colors.txt" DESTINATION ".") + install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper" DESTINATION ".") + +else(WIN32) + set(PACKAGING_FLAT 0) + set(CPACK_GENERATOR TGZ) + set(CPACK_SOURCE_GENERATOR TGZ) + + # Determine binary architecture + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -v + RESULT_VARIABLE VERSION_EXIT + OUTPUT_VARIABLE PACKAGE_TARGET_ARCHITECTURE + ERROR_VARIABLE PACKAGE_TARGET_ARCHITECTURE + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE ".*[\n\r]Target:[ \t\n\r]*([^ \t\n\r]+).*" "\\1" PACKAGE_TARGET_ARCHITECTURE "${PACKAGE_TARGET_ARCHITECTURE}") + if(VERSION_EXIT) + message(FATAL_ERROR "Could not determine target architecture") + elseif(PACKAGE_TARGET_ARCHITECTURE MATCHES "[ \t\n\r]") + message(FATAL_ERROR "Could not determine target architecture - error parsing compiler messages") + else(VERSION_EXIT) + message(STATUS "Target architecture: ${PACKAGE_TARGET_ARCHITECTURE}") + endif(VERSION_EXIT) + + # default package name (i.e. for .tar.gz) + if(ARCHIVE_PACKAGE_NAME) + set(CPACK_TGZ_PACKAGE_FILE_NAME "${ARCHIVE_PACKAGE_NAME}") + else(ARCHIVE_PACKAGE_NAME) + set(CPACK_TGZ_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-${PACKAGE_TARGET_ARCHITECTURE}") + endif(ARCHIVE_PACKAGE_NAME) + message(STATUS "Archive package name: ${CPACK_TGZ_PACKAGE_FILE_NAME}.tar.gz") + + install(FILES ${META_FILES} DESTINATION "share/doc/${PROJECT_NAME}" COMPONENT mapper) + install(FILES colors.txt DESTINATION "share/games/${PROJECT_NAME}" COMPONENT mapper) + install(TARGETS minetestmapper RUNTIME DESTINATION bin COMPONENT mapper) + + if(CMAKE_INSTALL_PREFIX STREQUAL "/usr") + # Require install prefix to be /usr when building .deb and .rpm packages + # (else minetestmapper will not find the default colors.txt file) + + # .deb settings + # Debian package building needs xxxxx, but cpack doesn't check for it first... + find_program(DPKG_AVAILABLE "dpkg") + # Fakeroot is needed to get correct file ownership (root/root) in the package + find_program(FAKEROOT_AVAILABLE "fakeroot") + if(DPKG_AVAILABLE AND FAKEROOT_AVAILABLE) + message(STATUS "dpkg and fakeroot found - enabling .deb package generation") + set(CPACK_GENERATOR ${CPACK_GENERATOR} DEB) + + # Cmake does not support delayed variable expansion. No alternative but to compute things ourselves :-(((( + # Maybe we should be checking PACKAGE_TARGET_ARCHITECTURE as well (and add specific code for every architecture :-() + # (on a multiarch system, the only compiler installed may not be the native one...) + execute_process(COMMAND dpkg --print-architecture + RESULT_VARIABLE VERSION_EXIT + OUTPUT_VARIABLE DEBIAN_PACKAGE_ARCHITECTURE + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(VERSION_EXIT) + message(FATAL_ERROR "Could not determine target architecture for debian package") + else(VERSION_EXIT) + message(STATUS "Debian package architecture: ${DEBIAN_PACKAGE_ARCHITECTURE}") + endif(VERSION_EXIT) + + set(CPACK_DEBIAN_PACKAGE_FILE_NAME "${PROJECT_NAME}_${VERSION_STRING}-${CPACK_PACKAGE_VERSION_PATCH}_${DEBIAN_PACKAGE_ARCHITECTURE}") + message(STATUS "Debian package name: ${CPACK_DEBIAN_PACKAGE_FILE_NAME}.deb") + set(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") + file(READ "${CPACK_PACKAGE_DESCRIPTION_FILE}" CPACK_DEBIAN_PACKAGE_DESCRIPTION) + # Unfortunately, cpack does not use (and adequately format) the description file - must do it ourselves + string(STRIP "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" CPACK_DEBIAN_PACKAGE_DESCRIPTION) + string(REGEX REPLACE "\n" "\n " CPACK_DEBIAN_PACKAGE_DESCRIPTION " ${CPACK_DEBIAN_PACKAGE_DESCRIPTION}") + string(REGEX REPLACE "(^ |\n )[ \t]*\n" "\\1.\n" CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n${CPACK_DEBIAN_PACKAGE_DESCRIPTION}") + set(CPACK_DEBIAN_PACKAGE_ENHANCES "minetest") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS 1) + set(CPACK_DEBIAN_PACKAGE_SECTION "games") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_PACKAGE_URL}") + else(DPKG_AVAILABLE AND FAKEROOT_AVAILABLE) + if(NOT DPKG_AVAILABLE) + message(STATUS "dpkg not found - no .deb package will be generated") + endif(NOT DPKG_AVAILABLE) + if(NOT FAKEROOT_AVAILABLE) + message(STATUS "fakeroot not found - no .deb package will be generated") + endif(NOT FAKEROOT_AVAILABLE) + endif(DPKG_AVAILABLE AND FAKEROOT_AVAILABLE) + unset(FAKEROOT_AVAILABLE CACHE) + unset(DPKG_AVAILABLE CACHE) + + # .rpm settings + # RPM package building needs rpmbuild, but cpack doesn't check for it first... + find_program(RPM_AVAILABLE "rpmbuild") + if(RPM_AVAILABLE) + message(STATUS "rpmbuild found - enabling .rpm package generation") + set(CPACK_GENERATOR ${CPACK_GENERATOR} RPM) + + set(CPACK_RPM_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-${CPACK_PACKAGE_VERSION_PATCH}-${PACKAGE_TARGET_ARCHITECTURE}") + message(STATUS "Rpm package name: ${CPACK_RPM_PACKAGE_FILE_NAME}.rpm") + set(CPACK_RPM_PACKAGE_VERSION "${VERSION_STRING}") + set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games") + set(CPACK_RPM_PACKAGE_LICENSE "GPLv2.1+") + set(CPACK_RPM_PACKAGE_URL "${CPACK_PACKAGE_URL}") + else(RPM_AVAILABLE) + message(STATUS "rpmbuild not found - no .rpm package will be generated") + endif(RPM_AVAILABLE) + unset(RPM_AVAILABLE CACHE) + else(CMAKE_INSTALL_PREFIX STREQUAL "/usr") + message(STATUS "Install prefix is not '/usr' - not building .deb / .rpm packages") + endif(CMAKE_INSTALL_PREFIX STREQUAL "/usr") + +endif(WIN32) include(CPack) + +# DO this near the end - to make sure all variables have been computed +# and are final. +configure_file( + "${PROJECT_SOURCE_DIR}/cmake_config.h.in" + "${PROJECT_BINARY_DIR}/cmake_config.h" +) +add_definitions ( -DUSE_CMAKE_CONFIG_H ) + diff --git a/README.rst b/README.rst index 0cbf3a4..32f3d72 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,12 @@ With levelDB and Redis support: cmake -DENABLE_LEVELDB=true -DENABLE_REDIS=true . make +Create installation package(s): + +:: + + cpack + Cmake variables: ^^^^^^^^^^^^^^^^ @@ -46,6 +52,28 @@ ENABLE_ALL_DATABASES: CMAKE_BUILD_TYPE: Type of build: 'Release' or 'Debug'. Defaults to 'Release'. +CREATE_FLAT_PACKAGE: + Create a .tar.gz package suitable for installation in a user's private directory. + The archive will unpack into a single directory, with the mapper's files inside + (this is the default). + + If off, .tar.gz, .deb and .rpm packages suitable for system-wide installation + will be created if possible. The tar.gz package will unpack into a directory hierarchy. + + For creation of .deb and .rpm packages, CMAKE_INSTALL_PREFIX must be '/usr'. + + For .deb package creation, dpkg and fakeroot are required. + + For .rpm package creation, rpmbuild is required. + +ARCHIVE_PACKAGE_NAME: + Name of the .zip or .tar.gz package (without extension). This will also be + the name of the directory into which the archive unpacks. + + Defaults to minetestmapper-- + + The name of .deb and .rpm packages are *not* affected by this variable. + Usage ----- diff --git a/cmake_config.h.in b/cmake_config.h.in index 55bf00f..eb10906 100644 --- a/cmake_config.h.in +++ b/cmake_config.h.in @@ -10,6 +10,8 @@ #define VERSION_MAJOR "@VERSION_MAJOR@" #define VERSION_MINOR "@VERSION_MINOR@" +#define PACKAGING_FLAT @PACKAGING_FLAT@ #define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@" + #endif diff --git a/package-description.txt b/package-description.txt new file mode 100644 index 0000000..11a357a --- /dev/null +++ b/package-description.txt @@ -0,0 +1,23 @@ +Minetestmapper generates maps of a minetest world. + +It reads from the world database directly, and generates a +map in png format. One world node is rendered as one map pixel. + +Features: +- Standard color mapping file included (which maps node (e.g. default:stone) to desired color) +- Use custom color mapping files (user-specific, world-specific, command-line) +- Supports sqlite3, leveldb and redis backends +Options: +- Limit the area of the world being rendered (and thus the size of the map) +- Render nodes transparently or not (e.g. water) +- Draw player positions on the map +- Draw a scale on the sides of the map +- Disable shading (rendering of height differences) +- Draw a grid to the map +- Draw geometric figures or text on the map +- Show actual world and map dimensions and report rendering statistics. + +Due to limitations of the drawing library, the maximum map size is limited. +The following numbers were determined by experimentation, and may vary: +- On 32-bit platforms, to a little over 570 megapixels (e.g. about 24000 x 24000) +- On 64-bit platforms, to a little over 2.1 gigapixels (e.g. about 46000 x 46000)