diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..dd09360 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,329 @@ +cmake_minimum_required (VERSION 3.10) + + +################ +## Project +######################### +project(modest LANGUAGES C) + + +################ +## User choices +######################### +option(MODEST_BUILD_SHARED "Build shared library" ON) +option(MODEST_BUILD_STATIC "Build static library" ON) +option(MyHTML_BUILD_WITHOUT_THREADS "Build MyHTML without POSIX Threads" OFF) +option(MyCORE_BUILD_WITHOUT_THREADS "Build MyCORE without POSIX Threads" OFF) +option(MODEST_INSTALL_HEADERS "Install header files" ON) +set(CMAKE_C_STANDARD 99 CACHE STRING "desired compilation C standard: 90, 99, 11") +#set_property(CACHE CMAKE_C_STANDARD PROPERTY STRINGS 90 99 11) +option(CMAKE_C_STANDARD_REQUIRED "don't compile using a previous C standard if the one specified is not met" ON) +#set(CMAKE_CXX_STANDARD 11 CACHE STRING "desired compilation C++ standard: 98, 11, 14, 17, 20") +#set_property(CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS 98 11 14 17 20) +#option(CMAKE_CXX_STANDARD_REQUIRED "don't compile using a previous C++ standard if the one specified is not met" ON) +#option(CMAKE_CXX_EXTENSIONS "compile using C++ standard extensions" FALSE) +set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Suffix for debug binaries") + + +################ +## Dependencies +######################### +if(NOT MyHTML_BUILD_WITHOUT_THREADS OR NOT MyCORE_BUILD_WITHOUT_THREADS) + set(CMAKE_THREAD_PREFER_PTHREAD 1) + find_package(Threads REQUIRED) + if(NOT CMAKE_USE_PTHREADS_INIT) + message(FATAL_ERROR "Could NOT find pthreads (missing: CMAKE_USE_PTHREADS_INIT)") + endif() +endif() + + +################ +## Project Version +######################### +set(PROJECT_VERSION_HEADER_FILE "${CMAKE_CURRENT_LIST_DIR}/include/modest/myosi.h") + +file(STRINGS ${PROJECT_VERSION_HEADER_FILE} PROJECT_VERSION_PARTS +REGEX "^#define[ \t]+MODEST_VERSION_(MAJOR|MINOR|PATCH)[ \t]+[0-9]+$") + +list(GET PROJECT_VERSION_PARTS 0 PROJECT_VERSION_MAJOR_PART) +list(GET PROJECT_VERSION_PARTS 1 PROJECT_VERSION_MINOR_PART) +list(GET PROJECT_VERSION_PARTS 2 PROJECT_VERSION_PATCH_PART) + +string(REGEX REPLACE "#define[ \t]+MODEST_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR_PART}) +string(REGEX REPLACE "#define[ \t]+MODEST_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR_PART}) +string(REGEX REPLACE "#define[ \t]+MODEST_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" PROJECT_VERSION_PATCH ${PROJECT_VERSION_PATCH_PART}) + +set(PROJECT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +message(STATUS "Project version: ${PROJECT_VERSION_STRING}") + + +################ +## Turn on the ability to create folders to organize projects (.vcproj) +######################### +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + + +################ +## Includes +######################### +set(PROJECT_DIR_API_HEADER "${CMAKE_CURRENT_LIST_DIR}/include") +#file(GLOB_RECURSE PROJECT_PUBLIC_HEADERS ${PROJECT_DIR_API_HEADER}/*.h) + + +################ +## Sources +######################### +MACRO(GET_MODULES_LIST result curdir) +FILE(GLOB children ${curdir}/ ${curdir}/*) + SET(dirlist "") + FOREACH(child ${children}) + string(REGEX MATCH "\\.[^/]+$" MATCHSTR ${child}) + IF(IS_DIRECTORY ${child} AND MATCHSTR STREQUAL "") + string(REGEX MATCH "[^/]+$" MATCHSTR ${child}) + IF(NOT MATCHSTR STREQUAL "myport") + LIST(APPEND dirlist ${MATCHSTR}) + ENDIF() + ENDIF() + ENDFOREACH() + SET(${result} ${dirlist}) +ENDMACRO() + +MACRO(CREATE_MODULES_SOURCE_PATH result dirpath modules) + SET(dirlist "") + FOREACH(module ${modules}) + LIST(APPEND dirlist ${dirpath}/${module}/*.c) + ENDFOREACH() + SET(${result} ${dirlist}) +ENDMACRO() + +set(PROJECT_SOURCE "${CMAKE_CURRENT_LIST_DIR}/source") + +GET_MODULES_LIST(MODULES ${PROJECT_SOURCE}) +CREATE_MODULES_SOURCE_PATH(MODULES_PATH ${PROJECT_SOURCE} "${MODULES}") + +file(GLOB_RECURSE PROJECT_SOURCES ${MODULES_PATH}) + +message(STATUS "Project modules: ${MODULES}") +#message(STATUS "${PROJECT_SOURCES}") + + +################ +## Include port based on OS +######################### +set(PROJECT_SOURCE_PORT_DIR "${PROJECT_SOURCE}/myport") + +if(WIN32) + file(GLOB_RECURSE PROJECT_SOURCES_PORT ${PROJECT_SOURCE_PORT_DIR}/windows_nt/mycore/*.c ${PROJECT_SOURCE_PORT_DIR}/windows_nt/mycore/*/*.c) +else() + file(GLOB_RECURSE PROJECT_SOURCES_PORT ${PROJECT_SOURCE_PORT_DIR}/posix/mycore/*.c ${PROJECT_SOURCE_PORT_DIR}/posix/mycore/utils/*/*.c) +endif(WIN32) + +message(STATUS "Port sources:") +foreach(__item IN LISTS PROJECT_SOURCES_PORT) + message(STATUS "${__item}") +endforeach() + + +################ +## Target properties +######################### +set(PROJECT_PRIVATE_COMPILE_DEFINITIONS "") +set(PROJECT_INTERFACE_COMPILE_DEFINITIONS "") +set(PROJECT_INTERFACE_COMPILE_OPTIONS "") +set(PROJECT_PRIVATE_COMPILE_OPTIONS "") + +if (WIN32) + if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS _WIN64) + else() + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS _WIN32) + endif() +endif() + + +if(MSVC) + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS /wd4100 /wd4255 /wd4820 /wd4668) + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS") + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS "MODEST_BUILD_OS=Windows_NT") + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS "MODEST_PORT_NAME=windows_nt") + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS "MyCORE_OS_WINDOWS_NT") + + list(APPEND PROJECT_INTERFACE_COMPILE_DEFINITIONS "MyCORE_OS_WINDOWS_NT") +else() + list(APPEND PROJECT_PRIVATE_COMPILE_OPTIONS -Wall -Werror -pipe -pedantic -Wno-unused-variable -Wno-unused-function) +endif() + +list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS $<$:MyCORE_BUILD_DEBUG> $<$:MyCORE_BUILD_DEBUG>) + +if(MyCORE_BUILD_WITHOUT_THREADS) + message(STATUS "Build without POSIX Threads") + list(APPEND PROJECT_PRIVATE_COMPILE_DEFINITIONS "MyCORE_BUILD_WITHOUT_THREADS") + list(APPEND PROJECT_INTERFACE_COMPILE_DEFINITIONS "MyCORE_BUILD_WITHOUT_THREADS") +else() + message(STATUS "Build with POSIX Threads") +endif() + +#message(STATUS "Project private compile definitions: ${PROJECT_PRIVATE_COMPILE_DEFINITIONS}") + + +################ +## Define targets: static/dynamic library +######################### +set(PROJECT_LIB_SHARED "${PROJECT_NAME}_shared") +set(PROJECT_LIB_STATIC "${PROJECT_NAME}_static") +set(PROJECT_LIB_SHARED_FILE_NAME "${PROJECT_NAME}") +if(MSVC) + set(PROJECT_LIB_STATIC_FILE_NAME "${PROJECT_NAME}_a") +else() + set(PROJECT_LIB_STATIC_FILE_NAME "${PROJECT_NAME}") +endif() +set(PROJECT_LIBRARY_TARGETS "") + + +if(MODEST_BUILD_SHARED) + add_library(${PROJECT_LIB_SHARED} SHARED ${PROJECT_SOURCES} ${PROJECT_SOURCES_PORT}) + set_target_properties(${PROJECT_LIB_SHARED} PROPERTIES OUTPUT_NAME ${PROJECT_LIB_SHARED_FILE_NAME}) +if (MSVC) + set_target_properties(${PROJECT_LIB_SHARED} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +endif() + list(APPEND PROJECT_LIBRARY_TARGETS ${PROJECT_LIB_SHARED}) +endif() + +if(MODEST_BUILD_STATIC) + add_library(${PROJECT_LIB_STATIC} STATIC ${PROJECT_SOURCES} ${PROJECT_SOURCES_PORT}) + set_target_properties(${PROJECT_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_LIB_STATIC_FILE_NAME}) + list(APPEND PROJECT_LIBRARY_TARGETS ${PROJECT_LIB_STATIC}) +endif() + +foreach(__item IN LISTS PROJECT_LIBRARY_TARGETS) + set_target_properties(${__item} PROPERTIES VERSION ${PROJECT_VERSION_STRING} SOVERSION ${PROJECT_VERSION_MAJOR}) +# target_compile_features(${__item} PRIVATE c_std_99) +# target_compile_features(${__item} PRIVATE cxx_std_11) + target_compile_definitions(${__item} + INTERFACE ${PROJECT_INTERFACE_COMPILE_DEFINITIONS} + PRIVATE ${PROJECT_PRIVATE_COMPILE_DEFINITIONS} + ) + target_compile_options(${__item} +# INTERFACE ${PROJECT_PRIVATE_COMPILE_OPTIONS} + PRIVATE ${PROJECT_PRIVATE_COMPILE_OPTIONS} + ) + target_include_directories(${__item} + PUBLIC + $ + $ # /${CMAKE_INSTALL_INCLUDEDIR} + ) + target_link_libraries(${__item} + PRIVATE ${CMAKE_THREAD_LIBS_INIT} + ) +endforeach() + + +################ +## Install +######################### +if(NOT MSVC) + include(GNUInstallDirs) +endif() + +if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) + set(CMAKE_INSTALL_INCLUDEDIR "include") +endif() + +if(NOT DEFINED CMAKE_INSTALL_BINDIR) + set(CMAKE_INSTALL_BINDIR "bin") +endif() + +if(NOT DEFINED CMAKE_INSTALL_LIBDIR) + set(CMAKE_INSTALL_LIBDIR "lib") +endif() + +set(MODEST_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake" CACHE PATH + "install location of folder with project cmake config files, either relative to CMAKE_INSTALL_PREFIX, or an absolute path") + + +if(MODEST_INSTALL_HEADERS) + install(DIRECTORY "${PROJECT_DIR_API_HEADER}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" FILES_MATCHING PATTERN "*.h") +endif() + +install(TARGETS ${PROJECT_LIBRARY_TARGETS} EXPORT ${PROJECT_NAME} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + #PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + #INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) + +#Use this to change the exported target name to be different than the defined target name +#set_target_properties(modest_shared PROPERTIES EXPORT_NAME Modest_shared) + +if(MSVC) + install(FILES "$" DESTINATION "${CMAKE_INSTALL_BINDIR}" OPTIONAL) +endif() + + +#this makes an IMPORTED targets definition file which is specific to the build tree, and is not relocatable +#export(EXPORT ${PROJECT_NAME} FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.cmake NAMESPACE JSONUtils::) + + +#this makes an IMPORTED targets definition file which is relocatable +install( + EXPORT ${PROJECT_NAME} + NAMESPACE ${PROJECT_NAME}:: + DESTINATION "${MODEST_INSTALL_CONFIGDIR}" + FILE ${PROJECT_NAME}.cmake + CONFIGURATIONS Debug Release + ) + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${MODEST_INSTALL_CONFIGDIR} + PATH_VARS + MODEST_INSTALL_CONFIGDIR + ) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${PROJECT_VERSION_STRING} + COMPATIBILITY AnyNewerVersion + ) + +#Install the config, configversion and custom find modules +install(FILES +# ${CMAKE_CURRENT_LIST_DIR}/cmake/FindRapidJSON.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${MODEST_INSTALL_CONFIGDIR} + ) + +#Register package in user's package registry +#export(PACKAGE ${PROJECT_NAME}) + + +#Add an alias so that library can be used inside the build tree, e.g. when testing +add_library(${PROJECT_NAME}::${PROJECT_LIB_SHARED} ALIAS ${PROJECT_LIB_SHARED}) +add_library(${PROJECT_NAME}::${PROJECT_LIB_STATIC} ALIAS ${PROJECT_LIB_STATIC}) + + +################ +## Build a package +######################### +set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fast C/C++ HTML 5 Renderer. Using threads.") +set(CPACK_PACKAGE_CONTACT "lex.borisov@gmail.com (Alexander Borisov)") +set(CPACK_PACKAGE_VENDOR "Alexander Borisov") + +set(CPACK_PACKAGE_RELEASE 1) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION_STRING}) + +if(${CMAKE_SIZEOF_VOID_P} EQUAL 4) + set(CPACK_RPM_PACKAGE_ARCHITECTURE i686) +else() + set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) +endif() + +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}.${CPACK_RPM_PACKAGE_ARCHITECTURE}") + +include(CPack) diff --git a/modestConfig.cmake.in b/modestConfig.cmake.in new file mode 100644 index 0000000..acbe38e --- /dev/null +++ b/modestConfig.cmake.in @@ -0,0 +1,11 @@ +@PACKAGE_INIT@ + +#include(CMakeFindDependencyMacro) +# NOTE Had to use find_package because find_dependency does not support COMPONENTS or MODULE until 3.8.0 +#find_package(Boost 1.55 REQUIRED COMPONENTS regex) + +# prevent including it several times +if(NOT @PROJECT_NAME@_FOUND) + include("@PACKAGE_MODEST_INSTALL_CONFIGDIR@/@PROJECT_NAME@.cmake") + check_required_components(@PROJECT_NAME@}) +endif() \ No newline at end of file