reduce code duplication in build system

- get rid of qmake project file
- provide CMake modules for common tasks
- provide templates for *.desktop files
experiment/meta_header
Martchus 7 years ago
parent 4b2110e452
commit bd0cbd5802
  1. 172
      CMakeLists.txt
  2. 8
      README.md
  3. 93
      c++utilities.pro
  4. 122
      cmake/modules/AppTarget.cmake
  5. 55
      cmake/modules/BasicConfig.cmake
  6. 218
      cmake/modules/LibraryTarget.cmake
  7. 17
      cmake/modules/TestTarget.cmake
  8. 48
      cmake/modules/WindowsResources.cmake
  9. 14
      cmake/templates/Config.cmake.in
  10. 9
      cmake/templates/config.h.in
  11. 8
      cmake/templates/desktop.in
  12. 0
      cmake/templates/windows.rc.in
  13. 103
      general.pri
  14. 12
      io/path.h
  15. 9
      resources/config.h.in
  16. 11
      tests/testutils.cpp

@ -49,6 +49,7 @@ set(SRC_FILES
misc/random.cpp
tests/testutils.cpp
)
set(TEST_HEADER_FILES
)
@ -59,155 +60,40 @@ set(TEST_SRC_FILES
tests/chronotests.cpp
)
set(CMAKE_MODULE_FILES
cmake/modules/BasicConfig.cmake
cmake/modules/LibraryTarget.cmake
cmake/modules/TestTarget.cmake
cmake/modules/AppTarget.cmake
cmake/modules/WindowsResources.cmake
)
set(CMAKE_TEMPLATE_FILES
cmake/templates/Config.cmake.in
cmake/templates/config.h.in
cmake/templates/desktop.in
)
if(MINGW)
list(APPEND CMAKE_TEMPLATE_FILES
cmake/templates/windows.rc.in
)
endif()
# required to include CMake modules from own project directory
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" "${CMAKE_MODULE_PATH}")
# meta data
set(META_PROJECT_NAME c++utilities)
set(META_PROJECT_VARNAME CPP_UTILITIES)
set(META_APP_NAME "C++ Utilities")
set(META_APP_AUTHOR "Martchus")
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities.")
set(META_VERSION_MAJOR 3)
set(META_VERSION_MINOR 2)
set(META_VERSION_PATCH 0)
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
# stringification of meta data
set(META_PROJECT_NAME_STR "\"${META_PROJECT_NAME}\"")
set(META_APP_NAME_STR "\"${META_APP_NAME}\"")
set(META_APP_AUTHOR_STR "\"${META_APP_AUTHOR}\"")
set(META_APP_URL_STR "\"${META_APP_URL}\"")
set(META_APP_DESCRIPTION_STR "\"${META_APP_DESCRIPTION}\"")
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
set(META_APP_VERSION_STR "\"${META_APP_VERSION}\"")
# define project
project(${META_PROJECT_NAME})
# add configuration header
configure_file(
"${PROJECT_SOURCE_DIR}/resources/config.h.in"
"${PROJECT_BINARY_DIR}/resources/config.h"
)
include_directories("${PROJECT_BINARY_DIR}")
# add windows resource file
if(MINGW)
# create windows rc file from template
set(WINDOWS_EXT "dll")
configure_file(
"${PROJECT_SOURCE_DIR}/resources/windows.rc.in"
"${PROJECT_BINARY_DIR}/resources/windows.rc"
)
# set windres as resource compiler
set(RES_FILES "${PROJECT_BINARY_DIR}/resources/windows.rc")
set(CMAKE_RC_COMPILER_INIT windres)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
enable_language(RC)
endif(MINGW)
# remove library prefix when building with mingw-w64 (just for consistancy with qmake)
if(MINGW)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif(MINGW)
set(META_VERSION_PATCH 1)
# disable new ABI (can't catch ios_base::failure with new ABI)
add_definitions(
-D_GLIBCXX_USE_CXX11_ABI=0
)
# executable and linking
add_library(${META_PROJECT_NAME} SHARED ${HEADER_FILES} ${SRC_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH})
set_target_properties(${META_PROJECT_NAME} PROPERTIES
VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}
SOVERSION ${META_VERSION_MAJOR}
CXX_STANDARD 11
)
if(MINGW)
# enable static library when building with mingw-w64
add_library(${META_PROJECT_NAME}_static STATIC ${HEADER_FILES} ${SRC_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH})
set_target_properties(${META_PROJECT_NAME}_static PROPERTIES
VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}
SOVERSION ${META_VERSION_MAJOR}
OUTPUT_NAME ${META_PROJECT_NAME}
CXX_STANDARD 11
)
endif(MINGW)
# add check target
if(NOT TARGET check)
set(CMAKE_CTEST_COMMAND ctest -V)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
enable_testing()
endif()
add_executable(${META_PROJECT_NAME}_tests EXCLUDE_FROM_ALL ${TEST_HEADER_FILES} ${TEST_SRC_FILES})
target_link_libraries(${META_PROJECT_NAME}_tests ${META_PROJECT_NAME} cppunit)
set_target_properties(${META_PROJECT_NAME}_tests PROPERTIES CXX_STANDARD 11)
add_test(NAME ${META_PROJECT_NAME}_cppunit COMMAND ${META_PROJECT_NAME}_tests -p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles")
add_dependencies(check ${META_PROJECT_NAME}_tests)
# add install target
install(TARGETS ${META_PROJECT_NAME}
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION lib
COMPONENT binary
ARCHIVE DESTINATION lib
COMPONENT binary
)
if(MINGW)
install(TARGETS ${META_PROJECT_NAME}_static
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION lib
COMPONENT binary
ARCHIVE DESTINATION lib
COMPONENT binary
)
endif(MINGW)
foreach(HEADER_FILE ${HEADER_FILES})
get_filename_component(HEADER_DIR ${HEADER_FILE} DIRECTORY)
install(
FILES ${HEADER_FILE}
DESTINATION include/${META_PROJECT_NAME}/${HEADER_DIR}
COMPONENT header
)
endforeach()
if(NOT TARGET install-binary)
add_custom_target(install-binary
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
if(NOT TARGET install-header)
add_custom_target(install-header
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
if(NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64
DEPENDS install-binary install-header
)
endif()
if(NOT TARGET install-binary-strip)
add_custom_target(install-binary-strip
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
if(NOT TARGET install-mingw-w64-importlib-strip)
add_custom_target(install-mingw-w64-importlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" --strip-unneeded "${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.dll.a"
)
endif()
if(NOT TARGET install-mingw-w64-staticlib-strip)
add_custom_target(install-mingw-w64-staticlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" -g "${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.a"
)
endif()
if(NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip
DEPENDS install-binary-strip install-mingw-w64-importlib-strip install-mingw-w64-staticlib-strip install-header
)
endif()
# include modules to apply configuration
include(BasicConfig)
include(WindowsResources)
include(LibraryTarget)
include(TestTarget)

@ -33,12 +33,6 @@ make check # build and run unit tests (optional)
make install
```
Building with qmake is also possible:
```
INSTALL_ROOT="/where/you/want/to/install" qmake-qt5 "path/to/projectfile"
make && make install
```
Building for Windows with Mingw-w64 cross compiler can be utilized using a small
[cmake wrapper from Fedora](https://aur.archlinux.org/cgit/aur.git/tree/mingw-cmake.sh?h=mingw-w64-cmake):
```
@ -58,5 +52,5 @@ PKGBUILD files to build for Windows using the Mingw-w64 compiler are also includ
is currently disabled. Linking against cppunit built using new libstdc++ ABI isn't possible.
## TODO
- rewrite argument parser
- rewrite argument parser (the API might change slightly)
- remove unused features

@ -1,93 +0,0 @@
# meta data
projectname = c++utilities
appname = "C++ Utilities"
appauthor = Martchus
QMAKE_TARGET_DESCRIPTION = "Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities."
VERSION = 3.2.0
# include ../../common.pri when building as part of a subdirs project; otherwise include general.pri
!include(../../common.pri) {
!include(./general.pri) {
error("Couldn't find the common.pri or the general.pri file!")
}
}
# basic configuration: shared library, no Qt
TEMPLATE = lib
CONFIG -= qt
CONFIG += shared
# add project files
HEADERS += \
application/argumentparser.h \
application/commandlineutils.h \
application/failure.h \
application/fakeqtconfigarguments.h \
application/global.h \
chrono/datetime.h \
chrono/period.h \
chrono/timespan.h \
conversion/binaryconversion.h \
conversion/binaryconversionprivate.h \
conversion/conversionexception.h \
conversion/stringconversion.h \
conversion/types.h \
conversion/widen.h \
io/ansiescapecodes.h \
io/binaryreader.h \
io/binarywriter.h \
io/bitreader.h \
io/copy.h \
io/inifile.h \
io/path.h \
math/math.h \
misc/memory.h \
misc/random.h \
tests/testutils.h \
tests/cppunit.h \
SOURCES += \
application/argumentparser.cpp \
application/commandlineutils.cpp \
application/failure.cpp \
application/fakeqtconfigarguments.cpp \
chrono/datetime.cpp \
chrono/period.cpp \
chrono/timespan.cpp \
conversion/conversionexception.cpp \
conversion/stringconversion.cpp \
io/ansiescapecodes.cpp \
io/binaryreader.cpp \
io/binarywriter.cpp \
io/bitreader.cpp \
io/inifile.cpp \
io/path.cpp \
math/math.cpp \
misc/random.cpp \
tests/testutils.cpp
OTHER_FILES += \
README.md \
LICENSE \
CMakeLists.txt \
resources/config.h.in \
resources/windows.rc.in
# installs
mingw-w64-install {
target.path = $$(INSTALL_ROOT)
target.extra = install -m755 -D $${OUT_PWD}/release/lib$(TARGET).a $$(INSTALL_ROOT)/lib/lib$(TARGET).a
INSTALLS += target
dlltarget.path = $$(INSTALL_ROOT)
dlltarget.extra = install -m755 -D $${OUT_PWD}/release/$(TARGET) $$(INSTALL_ROOT)/bin/$(TARGET)
INSTALLS += dlltarget
} else {
target.path = $$(INSTALL_ROOT)/lib
INSTALLS += target
}
for(dir, $$list(application io conversion chrono math misc tests)) {
eval(inc_$${dir} = $${dir})
inc_$${dir}.path = $$(INSTALL_ROOT)/include/$$projectname/$${dir}
inc_$${dir}.files = $${dir}/*.h
INSTALLS += inc_$${dir}
}

@ -0,0 +1,122 @@
# before including this module, BasicConfig must be included
# set the windows extension to "exe", this is required by the mingw-w64 specific WindowsResources module
if(MINGW)
set(WINDOWS_EXT "exe")
endif(MINGW)
# add target for building the application
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${GUI_TYPE} ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES} ${WINDOWS_ICON_PATH})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${LIBRARIES})
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES
CXX_STANDARD 11
)
# add install target for binary
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
COMPONENT binary
)
if(NOT TARGET install-binary)
add_custom_target(install-binary
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for localization
if(NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64
DEPENDS install-binary ${LOCALIZATION_TARGET}
)
endif()
# add install target for desktop entries and icons
foreach(DESKTOP_FILE ${DESKTOP_FILES})
install(
FILES "${DESKTOP_FILE}"
DESTINATION "share/applications"
COMPONENT desktop
)
endforeach()
foreach(ICON_FILE ${ICON_FILES})
install(
FILES "${ICON_FILE}"
DESTINATION "share/icons/hicolor/scalable/apps"
COMPONENT desktop
)
endforeach()
if(NOT TARGET install-desktop)
add_custom_target(install-desktop
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=desktop -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for stripped binaries
if(NOT TARGET install-binary-strip)
add_custom_target(install-binary-strip
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add mingw-w64 specific install target
if(NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip
DEPENDS install-binary-strip ${LOCALIZATION_TARGET}
)
endif()
# find template for *.desktop files
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/desktop.in")
# check own source directory
set(APP_DESKTOP_TEMPLATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/desktop.in")
message(STATUS "Using template for *.desktop file from own source directory.")
elseif(EXISTS "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/desktop.in")
# check sources of c++utilities
set(APP_DESKTOP_TEMPLATE_FILE "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/desktop.in")
message(STATUS "Using template for *.desktop file from c++utilities source directory.")
elseif(EXISTS "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/desktop.in")
# check installed version of c++utilities
set(APP_DESKTOP_TEMPLATE_FILE "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/desktop.in")
message(STATUS "Using template for *.desktop file from c++utilities installation.")
else()
message(FATAL_ERROR "Template for *.desktop file can not be located.")
endif()
# function to add *.desktop files
function(add_custom_desktop_file
FILE_NAME
DESKTOP_FILE_APP_NAME
DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD
DESKTOP_FILE_ICON)
# create desktop file from template
configure_file(
"${APP_DESKTOP_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
)
# add install for the desktop file
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
DESTINATION "share/applications"
COMPONENT desktop
)
endfunction()
# convenience function to add *.desktop file from project meta data
function(add_desktop_file)
add_custom_desktop_file(
"${META_PROJECT_NAME}"
"${META_APP_NAME}"
"${META_APP_DESCRIPTION}"
"${META_APP_CATEGORIES}"
"${META_PROJECT_NAME}"
"${META_PROJECT_NAME}"
)
endfunction()

@ -0,0 +1,55 @@
# before including this module, the project meta-data must be set
# set project name (displayed in Qt Creator)
project(${META_PROJECT_NAME})
# might be useful so other projects built as part of the same subdirs project
# can access files from this project
set(${META_PROJECT_VARNAME}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
set(${META_PROJECT_VARNAME}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
set(${META_PROJECT_NAME}_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
# stringify the meta data
set(META_PROJECT_NAME_STR "\"${META_PROJECT_NAME}\"")
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
set(META_APP_NAME_STR "\"${META_APP_NAME}\"")
set(META_APP_AUTHOR_STR "\"${META_APP_AUTHOR}\"")
set(META_APP_URL_STR "\"${META_APP_URL}\"")
set(META_APP_DESCRIPTION_STR "\"${META_APP_DESCRIPTION}\"")
set(META_APP_VERSION_STR "\"${META_APP_VERSION}\"")
# find config.h template
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/config.h.in")
# check own source directory
set(CONFIG_H_TEMPLATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/config.h.in")
message(STATUS "Using template for config.h from own source directory.")
elseif(EXISTS "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/config.h.in")
# check sources of c++utilities
set(CONFIG_H_TEMPLATE_FILE "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/config.h.in")
message(STATUS "Using template for config.h from c++utilities source directory.")
elseif(EXISTS "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/config.h.in")
# check installed version of c++utilities
set(CONFIG_H_TEMPLATE_FILE "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/config.h.in")
message(STATUS "Using template for config.h from c++utilities installation.")
else()
message(FATAL_ERROR "Template for config.h file can not be located.")
endif()
# add configuration header
configure_file(
"${CONFIG_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/config.h"
)
# ensure generated include files are found
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
# disable new ABI (can't catch ios_base::failure with new ABI)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
message(STATUS "Forcing usage of old CXX11 ABI to be able to catch std::ios_base::failure.")
# enable debug-only code when doing a debug build
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DDEBUG_BUILD)
message(STATUS "Debug build enabled.")
endif()

@ -0,0 +1,218 @@
# before including this module, BasicConfig must be included
# include for configure_package_config_file and write_basic_package_version_file
include(CMakePackageConfigHelpers)
# find template for CMake config file
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/Config.cmake.in")
# check own source directory
set(CONFIG_TEMPLATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/Config.cmake.in")
elseif(EXISTS "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/Config.cmake.in")
# check sources of c++utilities
set(CONFIG_TEMPLATE_FILE "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/Config.cmake.in")
elseif(EXISTS "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/Config.cmake.in")
# check installed version of c++utilities
set(CONFIG_TEMPLATE_FILE "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake/templates/Config.cmake.in")
else()
message(FATAL_ERROR "Template for configuration file can not be located.")
endif()
# set install destination for the CMake modules, config files and header files
set(HEADER_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/include")
set(LIB_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_MODULE_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake/modules")
set(CMAKE_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake")
# create the CMake config file from the template
configure_package_config_file(
"${CONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
"${CMAKE_CONFIG_INSTALL_DESTINATION}"
PATH_VARS
CMAKE_MODULE_INSTALL_DESTINATION
CMAKE_CONFIG_INSTALL_DESTINATION
HEADER_INSTALL_DESTINATION
LIB_INSTALL_DESTINATION
)
# write the CMake version config file
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
COMPATIBILITY SameMajorVersion
)
# remove library prefix when building with mingw-w64 (just for consistency with qmake)
if(MINGW)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif(MINGW)
# set the windows extension to "dll", this is required by the mingw-w64 specific WindowsResources module
if(MINGW)
set(WINDOWS_EXT "dll")
endif(MINGW)
# add target for building the library
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} SHARED ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES} ${WINDOWS_ICON_PATH})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${LIBRARIES})
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES
VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}
SOVERSION ${META_VERSION_MAJOR}
CXX_STANDARD 11
)
# add target for building a static version of the library when building with mingw-w64
if(MINGW)
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static STATIC ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES} ${WINDOWS_ICON_PATH})
# add target link libraries for the static lib also because otherwise Qt header files can not be located
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static ${LIBRARIES})
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static PROPERTIES
VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}
SOVERSION ${META_VERSION_MAJOR}
OUTPUT_NAME ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
CXX_STANDARD 11
)
endif(MINGW)
# add install target for the CMake config files
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake"
DESTINATION
"${CMAKE_CONFIG_INSTALL_DESTINATION}"
COMPONENT
cmake-config
)
if(NOT TARGET install-cmake-config)
add_custom_target(install-cmake-config
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-config -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for dynamic libs
install(
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION lib
COMPONENT binary
ARCHIVE DESTINATION lib
COMPONENT binary
)
if(NOT TARGET install-binary)
add_custom_target(install-binary
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install for static libs when building with mingw-w64
if(MINGW)
install(
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION lib
COMPONENT binary
ARCHIVE DESTINATION lib
COMPONENT binary
)
endif(MINGW)
# add install target for stripped libs
if(NOT TARGET install-binary-strip)
add_custom_target(install-binary-strip
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for header files
foreach(HEADER_FILE ${HEADER_FILES})
get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY)
install(
FILES "${HEADER_FILE}"
DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}"
COMPONENT header
)
endforeach()
if(NOT TARGET install-header)
add_custom_target(install-header
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for CMake modules
foreach(CMAKE_MODULE_FILE ${CMAKE_MODULE_FILES})
get_filename_component(CMAKE_MODULE_DIR ${CMAKE_MODULE_FILE} DIRECTORY)
install(
FILES ${CMAKE_MODULE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR}
COMPONENT cmake-modules
)
endforeach()
if(NOT TARGET install-cmake-modules)
add_custom_target(install-cmake-modules
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-modules -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for CMake templates
foreach(CMAKE_TEMPLATE_FILE ${CMAKE_TEMPLATE_FILES})
get_filename_component(CMAKE_TEMPLATE_DIR ${CMAKE_TEMPLATE_FILE} DIRECTORY)
install(
FILES ${CMAKE_TEMPLATE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR}
COMPONENT cmake-templates
)
endforeach()
if(NOT TARGET install-cmake-templates)
add_custom_target(install-cmake-templates
DEPENDS ${META_PROJECT_NAME}
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-templates -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
# add install target for all the cmake stuff
if(NOT TARGET install-cmake-stuff)
add_custom_target(install-cmake-stuff
DEPENDS install-cmake-config install-cmake-modules install-cmake-templates
)
endif()
# add mingw-w64 specific install targets
if(NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64
DEPENDS install-binary install-header
)
endif()
if(NOT TARGET install-mingw-w64-importlib-strip)
add_custom_target(install-mingw-w64-importlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" --strip-unneeded "${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.dll.a"
)
endif()
if(NOT TARGET install-mingw-w64-staticlib-strip)
add_custom_target(install-mingw-w64-staticlib-strip
DEPENDS install-binary-strip
COMMAND "${CMAKE_FIND_ROOT_PATH}/bin/strip" -g "${CMAKE_INSTALL_PREFIX}/lib/lib${META_PROJECT_NAME}.a"
)
endif()
if(NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip
DEPENDS install-binary-strip install-mingw-w64-importlib-strip install-mingw-w64-staticlib-strip install-header
)
endif()

@ -0,0 +1,17 @@
# before including this module, BasicConfig must be included
# add autotools-style check target
if(NOT TARGET check)
set(CMAKE_CTEST_COMMAND ctest -V)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
enable_testing()
endif()
# add test executable, but exclude it from the "all target"
add_executable(${META_PROJECT_NAME}_tests EXCLUDE_FROM_ALL ${TEST_HEADER_FILES} ${TEST_SRC_FILES})
target_link_libraries(${META_PROJECT_NAME}_tests ${META_PROJECT_NAME} ${TEST_LIBRARIES} cppunit)
set_target_properties(${META_PROJECT_NAME}_tests PROPERTIES CXX_STANDARD 11)
add_test(NAME ${META_PROJECT_NAME}_cppunit COMMAND ${META_PROJECT_NAME}_tests -p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles")
# add the test executable to the dependencies of the check target
add_dependencies(check ${META_PROJECT_NAME}_tests)

@ -0,0 +1,48 @@
# generates and adds a Windows rc file for the application/library
# also attaches the application icon if ffmpeg is available
# does nothing if not building with mingw-w64
# before including this module, LibraryConfig/ApplicationConfig must be included
if(MINGW)
# find rc template
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/windows.rc.in")
# check own source directory
set(RC_TEMPLATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/windows.rc.in")
elseif(EXISTS "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/windows.rc.in")
# check sources of c++utilities
set(RC_TEMPLATE_FILE "${CPP_UTILITIES_SOURCE_DIR}/cmake/templates/windows.rc.in")
elseif(EXISTS "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake-templates/windows.rc.in")
# check installed version of c++utilities
set(RC_TEMPLATE_FILE "${CMAKE_INSTALL_PREFIX}/share/c++utilities/cmake-templates/windows.rc.in")
else()
message(FATAL_ERROR "Template for Windows *.rc file can not be located.")
endif()
# create Windows icon from png with ffmpeg if available
set(WINDOWS_ICON_PATH "")
set(WINDOWS_ICON_RC_ENTRY "")
find_program(FFMPEG_BIN ffmpeg avconv)
if(FFMPEG_BIN)
set(PNG_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/resources/icons/hicolor/128x128/apps/${META_PROJECT_NAME}.png")
if(EXISTS "${PNG_ICON_PATH}")
set(WINDOWS_ICON_PATH "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}.ico")
set(WINDOWS_ICON_RC_ENTRY "IDI_ICON1 ICON DISCARDABLE \"${WINDOWS_ICON_PATH}\"")
add_custom_command(
OUTPUT "${WINDOWS_ICON_PATH}"
COMMAND ${FFMPEG_BIN} -y -i "${PNG_ICON_PATH}" -vf crop=iw-20:ih-20:10:10,scale=64:64 "${WINDOWS_ICON_PATH}"
)
endif()
endif(FFMPEG_BIN)
# create Windows rc file from template
configure_file(
"${RC_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/windows.rc"
)
# set windres as resource compiler
set(RES_FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/windows.rc")
set(CMAKE_RC_COMPILER_INIT windres)
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
enable_language(RC)
endif(MINGW)

@ -0,0 +1,14 @@
@PACKAGE_INIT@
set(@META_PROJECT_VARNAME@_LIBS "@META_PROJECT_NAME@")
set(@META_PROJECT_VARNAME@_INCLUDE_DIRS "@PACKAGE_HEADER_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_MODULE_DIRS "@PACKAGE_CMAKE_MODULE_INSTALL_DESTINATION@")
set(@META_PROJECT_VARNAME@_CONFIG_DIRS "@PACKAGE_CMAKE_CONFIG_INSTALL_DESTINATION@")
macro(use_@META_PROJECT_VARNAME@)
include_directories(BEFORE SYSTEM ${@META_PROJECT_VARNAME@_INCLUDE_DIRS})
link_directories(${@META_PROJECT_VARNAME@_LIB_DIR})
list(APPEND LIBRARIES ${@META_PROJECT_VARNAME@_LIBS})
list(APPEND CMAKE_MODULE_PATH ${@META_PROJECT_VARNAME@_MODULE_DIRS})
endmacro()

@ -0,0 +1,9 @@
#ifndef APP_METADATA_AVAIL
# define APP_METADATA_AVAIL
# define PROJECT_NAME @META_PROJECT_NAME_STR@
# define APP_NAME @META_APP_NAME_STR@
# define APP_VERSION @META_APP_VERSION_STR@
# define APP_AUTHOR @META_APP_AUTHOR_STR@
# define APP_URL @META_APP_URL_STR@
# define APP_DESCRIPTION @META_APP_DESCRIPTION_STR@
#endif // APP_METADATA_AVAIL

@ -0,0 +1,8 @@
[Desktop Entry]
Name=@DESKTOP_FILE_APP_NAME@
Comment=@DESKTOP_FILE_DESCRIPTION@
Exec=@DESKTOP_FILE_CMD@
Icon=@DESKTOP_FILE_ICON@
Terminal=false
Type=Application
Categories=@DESKTOP_FILE_CATEGORIES@

@ -1,103 +0,0 @@
# specify build directories for moc, object and rcc files
MOC_DIR = ./moc
OBJECTS_DIR = ./obj
RCC_DIR = ./res
# compiler flags: enable C++11
QMAKE_CXXFLAGS += -std=c++11
QMAKE_LFLAGS += -std=c++11
# disable new ABI (can't catch ios_base::failure with new ABI)
DEFINES += _GLIBCXX_USE_CXX11_ABI=0
# variables to check target architecture
win32-g++:QMAKE_TARGET.arch = $$QMAKE_HOST.arch
win32-g++-32:QMAKE_TARGET.arch = x86
win32-g++-64:QMAKE_TARGET.arch = x86_64
linux-g++:QMAKE_TARGET.arch = $$QMAKE_HOST.arch
linux-g++-32:QMAKE_TARGET.arch = x86
linux-g++-64:QMAKE_TARGET.arch = x86_64
# determine and print target prefix
targetprefix = $$(TARGET_PREFIX)
message("Using target prefix \"$${targetprefix}\".")
# print install root
message("Using install root \"$$(INSTALL_ROOT)\".")
# set target
CONFIG(debug, debug|release) {
TARGET = $${targetprefix}$${projectname}d
} else {
TARGET = $${targetprefix}$${projectname}
}
# add defines for meta data
DEFINES += "APP_METADATA_AVAIL"
DEFINES += "'PROJECT_NAME=\"$${projectname}\"'"
DEFINES += "'APP_NAME=\"$${appname}\"'"
DEFINES += "'APP_AUTHOR=\"$${appauthor}\"'"
DEFINES += "'APP_URL=\"$${appurl}\"'"
DEFINES += "'APP_VERSION=\"$${VERSION}\"'"
# configure Qt modules and defines
mobile {
DEFINES += CONFIG_MOBILE
} else:desktop {
DEFINES += CONFIG_DESKTOP
} else:android {
CONFIG += mobile
DEFINES += CONFIG_MOBILE
} else {
CONFIG += desktop
DEFINES += CONFIG_DESKTOP
}
no-gui {
QT -= gui
DEFINES += GUI_NONE
guiqtquick || guiqtwidgets {
error("Can not use no-gui with guiqtquick or guiqtwidgets.")
} else {
message("Configured for no GUI support.")
}
} else {
QT += gui
mobile {
CONFIG += guiqtquick
}
desktop {
CONFIG += guiqtwidgets
}
}
guiqtquick {
message("Configured for Qt Quick GUI support.")
QT += quick
CONFIG(debug, debug|release) {
CONFIG += qml_debug
}
DEFINES += GUI_QTQUICK
}
guiqtwidgets {
message("Configured for Qt widgets GUI support.")
QT += widgets
DEFINES += GUI_QTWIDGETS
DEFINES += MODEL_UNDO_SUPPORT
}
# configuration for cross compliation with mingw-w64
win32 {
QMAKE_TARGET_PRODUCT = "$${appname}"
QMAKE_TARGET_COPYRIGHT = "by $${appauthor}"
}
mingw-w64-manualstrip-dll {
QMAKE_POST_LINK=$${CROSS_COMPILE}strip --strip-unneeded ./release/$(TARGET); \
$${CROSS_COMPILE}strip --strip-unneeded ./release/lib$(TARGET).a
}
mingw-w64-manualstrip-exe {
QMAKE_POST_LINK=$${CROSS_COMPILE}strip --strip-unneeded ./release/$(TARGET)
}
mingw-w64-noversion {
TARGET_EXT = ".dll"
TARGET_VERSION_EXT = ""
CONFIG += skip_target_version_ext
}

@ -8,6 +8,18 @@
#include <string>
#ifdef PLATFORM_WINDOWS
# define PATH_SEP_CHAR '\\'
# define SEARCH_PATH_SEP_CHAR ';'
# define PATH_SEP_STR "\\"
# define SEARCH_PATH_SEP_STR ";"
#else
# define PATH_SEP_CHAR '/'
# define SEARCH_PATH_SEP_CHAR ':'
# define PATH_SEP_STR "/"
# define SEARCH_PATH_SEP_STR ":"
#endif
namespace IoUtilities {
LIB_EXPORT std::string fileName(const std::string &path);

@ -1,9 +0,0 @@
#ifndef APP_METADATA_AVAIL
#define APP_METADATA_AVAIL
#define PROJECT_NAME @META_PROJECT_NAME_STR@
#define APP_NAME @META_APP_NAME_STR@
#define APP_VERSION @META_APP_VERSION_STR@
#define APP_AUTHOR @META_APP_AUTHOR_STR@
#define APP_URL @META_APP_URL_STR@
#define APP_DESCRIPTION @META_APP_DESCRIPTION_STR@
#endif // APP_METADATA_AVAIL

@ -166,16 +166,15 @@ string TestApplication::workingCopyPath(const string &name) const
if(!parts.empty()) {
string currentLevel = m_workingDir;
for(auto i = parts.cbegin(), end = parts.end() - 1; i != end; ++i) {
if(stat((currentLevel += *i).c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) {
if(currentLevel.back() != '/') {
currentLevel += '/';
}
currentLevel += *i;
if(stat(currentLevel.c_str(), &currentStat) || !S_ISDIR(currentStat.st_mode)) {
if(mkdir(currentLevel.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl;
return string();
}
if(currentLevel.back() != '/') {
currentLevel += '/';
}
currentLevel += *i;
}
}
}

Loading…
Cancel
Save