cmake_minimum_required(VERSION 2.8.12...3.27) # Options: # LEXBOR_OPTIMIZATION_LEVEL default: -O2 # LEXBOR_C_FLAGS default: see this file # LEXBOR_CXX_FLAGS default: see this file # LEXBOR_WITHOUT_THREADS default: ON; Not used now, for the future # LEXBOR_BUILD_SHARED default: ON; Create shaded library # LEXBOR_BUILD_STATIC default: ON; Create static library # LEXBOR_BUILD_SEPARATELY default: OFF; Build all modules separately. # Each module will have its own shared library # LEXBOR_BUILD_WASM default: OFF; Build WASM modules (requires Emscripten) # LEXBOR_WASM_INSTALL_DIR default: "share/lexbor/wasm"; Install directory for WASM files # LEXBOR_BUILD_EXAMPLES default: OFF; Build all examples # LEXBOR_BUILD_TESTS default: OFF; Build tests # LEXBOR_BUILD_TESTS_CPP default: OFF; Build C++ tests. # Used with LEXBOR_BUILD_TESTS # LEXBOR_TEST_AMALGAMATION default: OFF; Testing all modules to create a single header file. # Used with LEXBOR_BUILD_TESTS # LEXBOR_BUILD_BENCHMARKS default: OFF; Build benchmarks. # LEXBOR_BUILD_UTILS default: OFF; Build utils/helpers for project. # LEXBOR_BUILD_WITH_ASAN default: OFF; Build with address sanitizer if possible # LEXBOR_BUILD_WITH_MSAN default: OFF; Build with memory sanitizer if possible # LEXBOR_BUILD_WITH_FUZZER default: OFF; Build with fuzzer tests if possible # LEXBOR_INSTALL_HEADERS default: ON; The header files will be installed # if set to ON # LEXBOR_WITH_PERF default: OFF; Enables support for rdtsc # LEXBOR_MAKE_RPM_FILES default: OFF; Create "spec" files in "packaging" direcotry # for create packages # LEXBOR_MAKE_DEB_FILES default: OFF; Create "control" files in "packaging" direcotry # for create packages # LEXBOR_MAKE_DISTRO_NUM default: 1; For packaging # LEXBOR_PRINT_MODULE_DEPENDENCIES default: OFF; Prints dependencies between modules # For build with ASAN use CMake flag: # -DLEXBOR_BUILD_WITH_ASAN=ON # or # -DCMAKE_C_FLAGS='-O0 -g -fsanitize=address' # or # -DLEXBOR_C_FLAGS='-O0 -g -fsanitize=address' set(PROJECT_NAME "lexbor") message(STATUS "Project name: ${PROJECT_NAME}") ################ ## Options ######################### option(LEXBOR_WITHOUT_THREADS "Build without Threads" ON) option(LEXBOR_BUILD_SHARED "Build shared library" ON) option(LEXBOR_BUILD_STATIC "Build static library" ON) option(LEXBOR_BUILD_SEPARATELY "Build modules separately" OFF) option(LEXBOR_BUILD_WASM "Build WASM modules (requires Emscripten)" OFF) option(LEXBOR_BUILD_EXAMPLES "Build examples" OFF) option(LEXBOR_BUILD_TESTS "Build tests" OFF) option(LEXBOR_BUILD_TESTS_CPP "Build C++ tests" OFF) option(LEXBOR_TEST_AMALGAMATION "Testing all modules to create a single header file" OFF) option(LEXBOR_BUILD_UTILS "Build utils" OFF) option(LEXBOR_BUILD_BENCHMARKS "Build with benchmarks" OFF) option(LEXBOR_BUILD_WITH_ASAN "Build with address sanitizer" OFF) option(LEXBOR_BUILD_WITH_MSAN "Build with memory sanitizer" OFF) option(LEXBOR_BUILD_WITH_FUZZER "Build with fuzzer" OFF) option(LEXBOR_INSTALL_HEADERS "Install header files" ON) option(LEXBOR_WITH_PERF "Enables support for rdtsc." OFF) option(LEXBOR_MAKE_PACKAGES_FILES "Create files for build packages" OFF) option(LEXBOR_PRINT_MODULE_DEPENDENCIES "Prints dependencies" OFF) set(LEXBOR_WASM_INSTALL_DIR "share/lexbor/wasm" CACHE STRING "Install directory for WASM files") IF(NOT LEXBOR_MAKE_DISTRO_NUM) set(LEXBOR_MAKE_DISTRO_NUM "1") ENDIF() enable_language(C) IF(LEXBOR_BUILD_TESTS_CPP) enable_language(CXX) ENDIF() IF(LEXBOR_BUILD_BENCHMARKS) add_definitions(-DLEXBOR_WITH_PERF) message(STATUS "Build with LEXBOR_BUILD_BENCHMARKS=ON, hard set LEXBOR_WITH_PERF as defined.") ENDIF() ################ ## Version and path ######################### set(LEXBOR_BASE "core") set(LEXBOR_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/source" CACHE STRING "") set(LEXBOR_SOURCE_LEXBOR "${LEXBOR_SOURCE}/lexbor" CACHE STRING "") set(LEXBOR_DIR_LIB "${CMAKE_CURRENT_SOURCE_DIR}/lib" CACHE STRING "") set(LEXBOR_DIR_HEADER "${LEXBOR_SOURCE}" CACHE STRING "") set(LEXBOR_DIR_HEADER_LEXBOR "${LEXBOR_SOURCE}/lexbor" CACHE STRING "") set(LEXBOR_SOURCE_PORT_DIR "${LEXBOR_SOURCE_LEXBOR}/ports" CACHE STRING "") set(LEXBOR_DIR_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" CACHE STRING "") set(LEXBOR_VERSION_FILEPATH "${CMAKE_CURRENT_SOURCE_DIR}/version" CACHE STRING "") set(LEXBOR_INSTALL_DLL_EXE_DIR "bin") ################ ## Policy ######################### IF(CMAKE_VERSION VERSION_GREATER "3.1" OR CMAKE_VERSION VERSION_EQUAL "3.1") cmake_policy(SET CMP0054 NEW) ENDIF() ################ ## RPATH ######################### IF(APPLE) set(CMAKE_MACOSX_RPATH ON) set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}) ELSEIF(UNIX) include(GNUInstallDirs) ENDIF() ################ ## lib param ######################### IF(NOT DEFINED CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR "lib") ENDIF() ################ ## CMake Includes ######################### include("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake") ################ ## Project Version ######################### GET_LEXBOR_VERSION(LEXBOR_VERSION_MAJOR LEXBOR_VERSION_MINOR LEXBOR_VERSION_PATCH LEXBOR_VERSION_STRING) message(STATUS "Lexbor version: ${LEXBOR_VERSION_STRING}") IF(CMAKE_VERSION VERSION_LESS "3.0") IF(LEXBOR_BUILD_TESTS_CPP) PROJECT("${PROJECT_NAME}") ELSE() PROJECT("${PROJECT_NAME}" "C") ENDIF() ELSE() cmake_policy(SET CMP0048 NEW) IF(LEXBOR_BUILD_TESTS_CPP) PROJECT("${PROJECT_NAME}" VERSION "${LEXBOR_VERSION_STRING}") ELSE() PROJECT("${PROJECT_NAME}" VERSION "${LEXBOR_VERSION_STRING}" LANGUAGES "C") ENDIF() ENDIF() ################ ## Features ######################### include("${CMAKE_CURRENT_SOURCE_DIR}/feature.cmake") ################ ## Includes ######################### include_directories(${LEXBOR_DIR_HEADER}) ################ ## Export LEXBOR_INCLUDE_DIRS and LEXBOR_LIBRARIES to global CACHE ######################### set(LEXBOR_INCLUDES ${LEXBOR_DIR_HEADER} CACHE STRING "Include paths for ${PROJECT_NAME}") set(LEXBOR_LIBRARIES ${LEXBOR_LIB_NAME} CACHE STRING "Libraries to link for ${PROJECT_NAME}") ################ ## Sources ######################### GET_MODULES_LIST(LEXBOR_MODULES "${LEXBOR_SOURCE}") ################ ## Create packages files ######################### IF(LEXBOR_MAKE_RPM_FILES) CREATE_RPM_SPEC_FILE() RETURN() ENDIF() IF(LEXBOR_MAKE_DEB_FILES) CREATE_DEB_FILES() RETURN() ENDIF() ################ ## Build all modules in one liblexbor library ######################### set(LEXBOR_LIB_NAME "${PROJECT_NAME}") set(LEXBOR_LIB_NAME_STATIC "${LEXBOR_LIB_NAME}_static") ## Get all source files from modules FOREACH(module ${LEXBOR_MODULES}) GET_MODULE_RESURSES(headers sources "${LEXBOR_SOURCE}" "${PROJECT_NAME}" ${module}) LIST(APPEND LEXBOR_SOURCES ${sources}) ENDFOREACH() ## First, need to add target for shared and static library IF(LEXBOR_BUILD_SHARED) add_library(${LEXBOR_LIB_NAME} SHARED ${LEXBOR_SOURCES}) target_include_directories(${LEXBOR_LIB_NAME} PUBLIC $ $) target_compile_definitions(${LEXBOR_LIB_NAME} PRIVATE "LEXBOR_BUILDING") ENDIF() IF(LEXBOR_BUILD_STATIC) add_library(${LEXBOR_LIB_NAME_STATIC} STATIC ${LEXBOR_SOURCES}) target_include_directories(${LEXBOR_LIB_NAME_STATIC} PUBLIC $ $) set_target_properties(${LEXBOR_LIB_NAME_STATIC} PROPERTIES OUTPUT_NAME ${LEXBOR_LIB_NAME_STATIC}) set_target_properties(${LEXBOR_LIB_NAME_STATIC} PROPERTIES COMPILE_PDB_NAME "${LEXBOR_LIB_NAME_STATIC}" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") target_compile_definitions(${LEXBOR_LIB_NAME_STATIC} PUBLIC "LEXBOR_STATIC") ENDIF() ## Load configurations from all modules. Print modules name and version. IF(NOT LEXBOR_BUILD_SEPARATELY) FOREACH(module ${LEXBOR_MODULES}) IF(LEXBOR_INSTALL_HEADERS) INSTALL_MODULE_HEADERS("${LEXBOR_SOURCE}" "${PROJECT_NAME}" ${module}) ENDIF() INCLUDE_MODULE_CONFIG(${PROJECT_NAME} ${module} "${LEXBOR_SOURCE_LEXBOR}/${module}") GET_MODULE_DEPENDENCIES(${PROJECT_NAME} ${module} module_deps) GET_MODULE_VERSION(major minor patch version_string "${LEXBOR_SOURCE}" "${PROJECT_NAME}" ${module}) MODULE_PRINT(${module} ${version_string} "${module_deps}") ENDFOREACH() ENDIF() ## Create dynamic/static library IF(LEXBOR_BUILD_SHARED) ADD_MODULE_LIBRARY(SHARED ${LEXBOR_LIB_NAME} ${LEXBOR_VERSION_STRING} ${LEXBOR_VERSION_MAJOR}) ENDIF() IF(LEXBOR_BUILD_STATIC) ADD_MODULE_LIBRARY(STATIC ${LEXBOR_LIB_NAME_STATIC} ${LEXBOR_VERSION_STRING} ${LEXBOR_VERSION_MAJOR}) ENDIF() ################ ## Build separately modules in liblexbor- ######################### IF(LEXBOR_BUILD_SEPARATELY) FOREACH(module ${LEXBOR_MODULES}) set(lexbor_deps "${lexbor_deps} ${module}") set(libname "${PROJECT_NAME}-${module}") GET_MODULE_VERSION(major minor patch version_string "${LEXBOR_SOURCE}" "${PROJECT_NAME}" ${module}) GET_MODULE_RESURSES(headers sources "${LEXBOR_SOURCE}" "${PROJECT_NAME}" ${module}) IF(LEXBOR_BUILD_SHARED) add_library(${libname} SHARED ${sources}) target_compile_definitions(${libname} PRIVATE "LEXBOR_BUILDING") ADD_MODULE_LIBRARY(SHARED ${libname} ${version_string} ${major}) ENDIF() IF(LEXBOR_BUILD_STATIC) add_library("${libname}_static" STATIC ${sources}) set_target_properties("${libname}_static" PROPERTIES OUTPUT_NAME "${libname}_static") set_target_properties("${libname}_static" PROPERTIES COMPILE_PDB_NAME "${libname}_static" COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") target_compile_definitions("${libname}_static" PRIVATE "LEXBOR_STATIC") ADD_MODULE_LIBRARY(STATIC "${libname}_static" ${version_string} ${major}) ENDIF() IF(LEXBOR_INSTALL_HEADERS) INSTALL_MODULE_HEADERS("${LEXBOR_SOURCE}" "${PROJECT_NAME}" "${module}") ENDIF() INCLUDE_MODULE_CONFIG(${PROJECT_NAME} ${module} "${LEXBOR_SOURCE_LEXBOR}/${module}") GET_MODULE_DEPENDENCIES(${PROJECT_NAME} ${module} module_deps) IF(LEXBOR_BUILD_SHARED) SET_MODULE_LIB_DEPENDENCIES(${libname} "${module_deps}" "") ENDIF() IF(LEXBOR_BUILD_STATIC) SET_MODULE_LIB_DEPENDENCIES("${libname}_static" "${module_deps}" "_static") ENDIF() MODULE_PRINT(${module} ${version_string} "${module_deps}") ENDFOREACH() ENDIF() ################ ## Sets C_FLAGS ######################### set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LEXBOR_OPTIMIZATION_LEVEL} ${LEXBOR_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEXBOR_OPTIMIZATION_LEVEL} ${LEXBOR_CXX_FLAGS}") message(STATUS "CFLAGS: ${CMAKE_C_FLAGS}") message(STATUS "CXXFLAGS: ${CMAKE_CXX_FLAGS}") ################ ## Check features ######################### FEATURE_CHECK_ASAN(LEXBOR_HAVE_ASAN) IF(${LEXBOR_HAVE_ASAN}) add_definitions(-DLEXBOR_HAVE_ADDRESS_SANITIZER) ENDIF() FEATURE_CHECK_MSAN(LEXBOR_HAVE_MSAN) IF(${LEXBOR_HAVE_MSAN}) add_definitions(-DLEXBOR_HAVE_MEMORY_SANITIZER) ENDIF() FEATURE_CHECK_FUZZER(LEXBOR_HAVE_FUZZER) IF(${LEXBOR_HAVE_FUZZER}) set(LEXBOR_BUILD_EXAMPLES OFF) set(LEXBOR_BUILD_UTILS OFF) message(STATUS "Build only fuzzing test.") message(STATUS "Set LEXBOR_BUILD_TESTS to OFF.") message(STATUS "Set LEXBOR_BUILD_EXAMPLES to OFF.") message(STATUS "Set LEXBOR_BUILD_UTILS to OFF.") add_definitions(-DLEXBOR_HAVE_FUZZER) ENDIF() ################ ## WASM ######################### IF(LEXBOR_BUILD_WASM) message(STATUS "WASM build: enabled.") IF(LEXBOR_BUILD_SHARED) set(LEXBOR_BUILD_SHARED OFF) message(STATUS "WASM: set LEXBOR_BUILD_SHARED to OFF.") ENDIF() IF(NOT LEXBOR_BUILD_STATIC) set(LEXBOR_BUILD_STATIC ON) message(STATUS "WASM: set LEXBOR_BUILD_STATIC to ON.") ENDIF() IF(LEXBOR_BUILD_TESTS) set(LEXBOR_BUILD_TESTS OFF) message(STATUS "WASM: set LEXBOR_BUILD_TESTS to OFF.") ENDIF() IF(LEXBOR_BUILD_EXAMPLES) set(LEXBOR_BUILD_EXAMPLES OFF) message(STATUS "WASM: set LEXBOR_BUILD_EXAMPLES to OFF.") ENDIF() IF(LEXBOR_BUILD_UTILS) set(LEXBOR_BUILD_UTILS OFF) message(STATUS "WASM: set LEXBOR_BUILD_UTILS to OFF.") ENDIF() IF(LEXBOR_BUILD_BENCHMARKS) set(LEXBOR_BUILD_BENCHMARKS OFF) message(STATUS "WASM: set LEXBOR_BUILD_BENCHMARKS to OFF.") ENDIF() add_subdirectory(wasm) ENDIF() ################ ## Tests ######################### IF(LEXBOR_BUILD_TESTS) enable_testing() add_subdirectory(test) ENDIF() ################ ## Examples ######################### IF(LEXBOR_BUILD_EXAMPLES) add_subdirectory(examples) ENDIF() ################ ## Utils ######################### IF(LEXBOR_BUILD_UTILS) add_subdirectory(utils) ENDIF() ################ ## Benchmarks ######################### IF(LEXBOR_BUILD_BENCHMARKS) add_subdirectory(benchmarks) ENDIF() ################ ## CMake target export ######################### IF(NOT LEXBOR_BUILD_WASM) include("CMakePackageConfigHelpers") install( EXPORT "${PROJECT_NAME}-export" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/" FILE "${PROJECT_NAME}-targets.cmake" NAMESPACE "${PROJECT_NAME}::") configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/") write_basic_package_version_file( "${PROJECT_NAME}-config-version.cmake" COMPATIBILITY SameMajorVersion VERSION "${LEXBOR_VERSION_STRING}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/") ################ ## pkg-config configuration ######################### configure_file( "${PROJECT_SOURCE_DIR}/lexbor.pc.in" "${PROJECT_BINARY_DIR}/lexbor.pc" @ONLY ) install( FILES "${PROJECT_BINARY_DIR}/lexbor.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" ) ENDIF() ################ ## Build an RPM. ######################### set(CPACK_PACKAGE_VERSION ${LEXBOR_VERSION_STRING}) if(LEXBOR_PLATFORM STREQUAL "Debian") set(CPACK_GENERATOR "DEB") elseif(LEXBOR_PLATFORM STREQUAL "Redhat") set(CPACK_GENERATOR "RPM") elseif(LEXBOR_PLATFORM STREQUAL "SuSe") set(CPACK_GENERATOR "RPM") else() set(CPACK_GENERATOR "TGZ") endif() set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_RELEASE 1) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HTML Renderer") set(CPACK_PACKAGE_CONTACT "Alexander Borisov") set(CPACK_PACKAGE_VENDOR "Alexander Borisov") if(32BIT) 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)