From 44ffb9fef7f19b545a4f9e1b3b68c2a04fd2e8dd Mon Sep 17 00:00:00 2001 From: Krylov Yaroslav Date: Sat, 7 Aug 2021 23:15:18 +0300 Subject: [PATCH] #138 Add initial CMake support --- CMakeLists.txt | 131 ++++++++++++++++++++++++++++++++++++++++++++ Config.cmake.in | 6 ++ FindV8.cmake | 72 ++++++++++++++++++++++++ test/CMakeLists.txt | 10 ++++ v8pp/CMakeLists.txt | 50 +++++++++++++++++ 5 files changed, 269 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 Config.cmake.in create mode 100644 FindV8.cmake create mode 100644 test/CMakeLists.txt create mode 100644 v8pp/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..e74572ed --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,131 @@ +cmake_minimum_required(VERSION 3.14) +# using file(CREATE_LINK) that was added in 3.14 + +# Get version from config.hpp +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/v8pp/config.hpp config_hpp) +if(NOT config_hpp MATCHES "V8PP_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\"") + message(FATAL_ERROR "Cannot get V8PP_VERSION from config.hpp.") +endif() +unset(config_hpp) +# Use math to skip leading zeros if any. +math(EXPR V8PP_VERSION_MAJOR ${CMAKE_MATCH_1}) +math(EXPR V8PP_VERSION_MINOR ${CMAKE_MATCH_2}) +math(EXPR V8PP_VERSION_PATCH ${CMAKE_MATCH_3}) +set(V8PP_VERSION ${V8PP_VERSION_MAJOR}.${V8PP_VERSION_MINOR}.${V8PP_VERSION_PATCH}) + +project(v8pp VERSION ${V8PP_VERSION} LANGUAGES CXX) + +# Determine if v8pp is built as a subproject (using add_subdirectory) +# or if it is the master project. +if(NOT DEFINED V8PP_MASTER_PROJECT) + set(V8PP_MASTER_PROJECT OFF) + if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(V8PP_MASTER_PROJECT ON) + endif() +endif() + +# Options that control generation of various targets. +option(V8PP_WARNING "Enable extra warnings and expensive tests." ${V8PP_MASTER_PROJECT}) +option(V8PP_WERROR "Halt the compilation with an error on compiler warnings." OFF) +option(V8PP_TEST "Generate the test target." ${V8PP_MASTER_PROJECT}) +option(V8PP_INSTALL "Generate install target." ${V8PP_MASTER_PROJECT}) + +# Warnings setup +set(V8PP_WARNING_OPTIONS) + +if(V8PP_WARNING) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + list(APPEND V8PP_WARNING_OPTIONS "-Wall") + list(APPEND V8PP_WARNING_OPTIONS "-Wextra") + list(APPEND V8PP_WARNING_OPTIONS "-Wno-unused-function") + elseif( + CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + ) + list(APPEND V8PP_WARNING_OPTIONS "-Wall") + list(APPEND V8PP_WARNING_OPTIONS "-Wextra") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set_msvc_warning_flags(WARNING_OPTIONS) + list(APPEND V8PP_WARNING_OPTIONS "/W3") + else() + message(SEND_ERROR "unknown compiler \"${CMAKE_CXX_COMPILER_ID}\"") + endif() +endif() + +if(V8PP_WERROR) + if( + CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + ) + list(APPEND V8PP_WARNING_OPTIONS "-Werror") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set_msvc_warning_flags(WARNING_OPTIONS) + list(APPEND V8PP_WARNING_OPTIONS "/WX") + else() + message(SEND_ERROR "unknown compiler \"${CMAKE_CXX_COMPILER_ID}\"") + endif() +endif() + +# Find V8 package +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") + +find_package(V8 REQUIRED) + +add_subdirectory(v8pp) + +if(V8PP_TEST) + add_subdirectory(test) +endif() + +if(V8PP_INSTALL) + # cmake code for install is based on https://github.com/onqtam/doctest/blob/master/CMakeLists.txt + + set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") + + if(CMAKE_SYSTEM_NAME STREQUAL Linux) + include(GNUInstallDirs) + set(include_install_dir ${CMAKE_INSTALL_INCLUDEDIR}) + set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + else() + set(include_install_dir "include") + set(config_install_dir "lib/cmake/${PROJECT_NAME}") + endif() + + set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") + set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") + set(targets_export_name "${PROJECT_NAME}Targets") + set(namespace "${PROJECT_NAME}::") + + include(CMakePackageConfigHelpers) + + write_basic_package_version_file( + "${version_config}" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + + configure_file("Config.cmake.in" "${project_config}" @ONLY) + + install( + TARGETS v8pp v8pp-header-only + EXPORT "${targets_export_name}" + INCLUDES DESTINATION "${include_install_dir}" + ) + + install( + DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/v8pp/include/" + DESTINATION "${include_install_dir}/" + ) + + install( + FILES "${project_config}" "${version_config}" + DESTINATION "${config_install_dir}" + ) + + install( + EXPORT "${targets_export_name}" + NAMESPACE "${namespace}" + DESTINATION "${config_install_dir}" + ) +endif() diff --git a/Config.cmake.in b/Config.cmake.in new file mode 100644 index 00000000..b2a5c1bf --- /dev/null +++ b/Config.cmake.in @@ -0,0 +1,6 @@ +if(NOT TARGET v8pp::v8pp) + # Provide path for scripts + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") + + include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") +endif() \ No newline at end of file diff --git a/FindV8.cmake b/FindV8.cmake new file mode 100644 index 00000000..0bb35a98 --- /dev/null +++ b/FindV8.cmake @@ -0,0 +1,72 @@ +# Based on https://raw.githubusercontent.com/nicehash/cpp-ethereum/master/cmake/Findv8.cmake +# +# Find v8 +# +# Find the v8 includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# V8_INCLUDE_DIRS, where to find header, etc. +# V8_LIBRARIES, the libraries needed to use v8. +# V8_FOUND, If false, do not try to use v8. + +# only look in default directories +find_path(V8_INCLUDE_DIR NAMES v8.h PATHS /usr/include/v8 DOC "v8 include dir") + +find_library(V8_LIBRARY NAMES v8 PATHS /usr/lib DOC "v8 library") + +set(V8_INCLUDE_DIRS ${V8_INCLUDE_DIR}) +set(V8_LIBRARIES ${V8_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library(V8_LIBRARY NAMES v8_base DOC "v8 base library") + + find_library( + V8_NO_SNAPSHOT_LIBRARY + NAMES v8_nosnapshot + DOC "v8 nosnapshot library" + ) + + set(V8_LIBRARIES ${V8_LIBRARY} ${V8_NO_SNAPSHOT_LIBRARY}) + + find_library(V8_LIBRARY_DEBUG NAMES v8_based DOC "v8 base library") + + find_library( + V8_NO_SNAPSHOT_LIBRARY_DEBUG + NAMES v8_nosnapshotd + DOC "v8 nosnapshot library" + ) + + set(V8_LIBRARIES + "ws2_32" + "winmm" + optimized + ${V8_LIBRARIES} + debug + ${V8_LIBRARY_DEBUG} + ${V8_NO_SNAPSHOT_LIBRARY_DEBUG} + ) +endif() + +# handle the QUIETLY and REQUIRED arguments and set V8_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(V8 DEFAULT_MSG V8_INCLUDE_DIR V8_LIBRARY) +mark_as_advanced(V8_INCLUDE_DIR V8_LIBRARY) + +if(V8_FOUND) + if(NOT TARGET V8::V8) + add_library(V8::V8 SHARED IMPORTED) + + set_target_properties( + V8::V8 + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${V8_INCLUDE_DIR}" + IMPORTED_LOCATION "${V8_LIBRARY}" + ) + endif() +endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..d933dc58 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,10 @@ +# Test target +file(GLOB v8pp_test_cpp *.cpp) + +list(SORT v8pp_test_cpp) + +add_executable(v8pp_test ${v8pp_test_cpp}) + +target_link_libraries(v8pp_test PRIVATE v8pp::v8pp) + +target_compile_options(v8pp_test PRIVATE ${V8PP_WARNING_OPTIONS}) diff --git a/v8pp/CMakeLists.txt b/v8pp/CMakeLists.txt new file mode 100644 index 00000000..b4a1a933 --- /dev/null +++ b/v8pp/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copy all headers to ${CMAKE_CURRENT_BINARY_DIR}/v8pp +# It makes this repo a little bit submodule friendly +set(V8PP_INCLUDES_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") +file(MAKE_DIRECTORY "${V8PP_INCLUDES_DIR}/v8pp") + +file(GLOB v8pp_hpp RELATIVE ${CMAKE_CURRENT_LIST_DIR} *.hpp) +file(GLOB v8pp_ipp RELATIVE ${CMAKE_CURRENT_LIST_DIR} *.ipp) + +foreach(f ${v8pp_hpp};${v8pp_ipp}) + set(_original "${CMAKE_CURRENT_LIST_DIR}/${f}") + set(_linkname "${V8PP_INCLUDES_DIR}/v8pp/${f}") + file(CREATE_LINK "${_original}" "${_linkname}" COPY_ON_ERROR) +endforeach() + +# Header only library target +add_library(v8pp-header-only INTERFACE) + +add_library(v8pp::v8pp-header-only ALIAS v8pp-header-only) + +target_include_directories(v8pp-header-only INTERFACE + $ + $) + +target_compile_definitions(v8pp-header-only INTERFACE V8PP_HEADER_ONLY=1) + +target_compile_features(v8pp-header-only INTERFACE cxx_std_14) + +target_link_libraries(v8pp-header-only INTERFACE V8::V8) + +# Static library target +file(GLOB v8pp_cpp *.cpp) +list(SORT v8pp_cpp) + +add_library(v8pp STATIC ${v8pp_cpp}) + +add_library(v8pp::v8pp ALIAS v8pp) + +target_include_directories(v8pp PUBLIC + $ + $) + +target_compile_definitions(v8pp PUBLIC V8PP_HEADER_ONLY=0) + +target_compile_features(v8pp PUBLIC cxx_std_14) + +target_link_libraries(v8pp PUBLIC V8::V8 ${CMAKE_DL_LIBS}) + +target_compile_options(v8pp PRIVATE ${V8PP_WARNING_OPTIONS}) + +set_property(TARGET v8pp PROPERTY POSITION_INDEPENDENT_CODE ON)