Add Cppcheck and Doxygen in Meson...

...fix RapidJSON dependency, remove features from CMake

I've now implemented in Meson all the remaining features that were in
CMake, like Cppcheck and Doxygen documentation. I've also removed almost
all the non-essential features from CMake, like building examples,
documentation, code coverage, the install target, Cppcheck, and tarball
generation. This should help with maintainability, while preserving
testability, following @kiplingw and @dennisjenkins75 main concerns.

Cppcheck is not ran by default, but it is a build target; you can run it
with `meson compile -C builddir cppcheck`.

I've also made some little fixes and tweaks:

Fixed RapidJSON
dependency, as it was previously declared only as a dependency of the
run_rest_description example, while used in
include/pistache/thirdparty/serializer/rapidjson.h.

Updated CMakeLists, replacing the old Include(Dart) with the newer
Include(CTest), and also adding messaging suggesting the user to install
RapidJSON and GoogleTest on their system rather than building them from
source.

Fixed a "small" issue in meson.build, replacing add_global_arguments
with add_project_arguments, since the former can't be used in
subprojects and can cause build failures for users.
parent cfd5322e
......@@ -234,8 +234,7 @@ install:
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
# Install Meson >=0.57.0
- export PATH=$HOME/.local/bin:$PATH
- pip3 install -qqq --user --ignore-installed meson
- sudo pip3 install -qqq --ignore-installed meson
before_script:
- cd ${TRAVIS_BUILD_DIR}
......@@ -254,28 +253,6 @@ before_script:
- service --status-all || true
- initctl list || true
# CMake debug build
- cmake -S .
-B cmake_build_debug
-DCMAKE_BUILD_TYPE=Debug
-DPISTACHE_BUILD_EXAMPLES=true
-DPISTACHE_BUILD_TESTS=true
-DPISTACHE_USE_SSL=true
# CMake debug build, no SSL
- cmake -S .
-B cmake_build_debug-nossl
-DCMAKE_BUILD_TYPE=Debug
-DPISTACHE_BUILD_EXAMPLES=true
-DPISTACHE_BUILD_TESTS=true
-DPISTACHE_USE_SSL=false
# CMake release build
- cmake -S .
-B cmake_build_release
-DCMAKE_BUILD_TYPE=Release
-DPISTACHE_USE_SSL=true
# Meson debug build
- meson setup meson_build_debug
--buildtype=debug
......@@ -297,6 +274,26 @@ before_script:
--buildtype=release
-DPISTACHE_USE_SSL=true
# CMake debug build
- cmake -S .
-B cmake_build_debug
-DCMAKE_BUILD_TYPE=Debug
-DPISTACHE_BUILD_TESTS=true
-DPISTACHE_USE_SSL=true
# CMake debug build, no SSL
- cmake -S .
-B cmake_build_debug-nossl
-DCMAKE_BUILD_TYPE=Debug
-DPISTACHE_BUILD_TESTS=true
-DPISTACHE_USE_SSL=false
# CMake release build
- cmake -S .
-B cmake_build_release
-DCMAKE_BUILD_TYPE=Release
-DPISTACHE_USE_SSL=true
script:
# Set the ulimit
- ulimit -c unlimited -S
......
......@@ -18,21 +18,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
include(CheckAtomic)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
add_compile_options(-g -Og --coverage -fstack-protector-all --param=ssp-buffer-size=4)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13")
add_link_options(--coverage)
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
endif()
endif()
option(BUILD_SHARED_LIBS "build shared library" ON)
option(PISTACHE_BUILD_TESTS "build tests alongside the project" OFF)
option(PISTACHE_ENABLE_NETWORK_TESTS "if tests are built, run ones needing network access" ON)
option(PISTACHE_BUILD_EXAMPLES "build examples alongside the project" OFF)
option(PISTACHE_BUILD_DOCS "build docs alongside the project" OFF)
option(PISTACHE_INSTALL "add pistache as install target (recommended)" ON)
option(PISTACHE_USE_SSL "add support for SSL server" OFF)
option(PISTACHE_PIC "Enable pistache PIC" ON)
......@@ -45,32 +33,6 @@ if(CMAKE_INTERPROCEDURAL_OPTIMIZATION OR CMAKE_CXX_FLAGS MATCHES "-flto" OR CMAK
endif()
endif()
if (PISTACHE_BUILD_TESTS)
find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind)
find_program(CTEST_COVERAGE_COMMAND NAMES gcov)
find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
if (CMAKE_CXX_CPPCHECK)
message("-- Cppcheck found " ${CMAKE_CXX_CPPCHECK})
list(
APPEND CMAKE_CXX_CPPCHECK
"--enable=all"
"-DCPPCHECK"
"--suppress=*:${PROJECT_SOURCE_DIR}/third-party/*"
"--suppress=*:${PROJECT_SOURCE_DIR}/tests/*"
"--suppress=noExplicitConstructor:include/pistache/optional.h"
)
else()
message("-- Cppcheck not found")
set(CMAKE_CXX_CPPCHECK "")
endif()
INCLUDE(Dart)
add_custom_target(test_memcheck COMMAND ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --test-action memcheck)
add_custom_target(coverage COMMAND ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --test-action coverage)
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
......@@ -101,6 +63,9 @@ endif ()
string(REGEX MATCH "VERSION_GIT_DATE *([0-9]+)" _ ${VERSION_FILE})
set(VERSION_GIT_DATE ${CMAKE_MATCH_1})
# Full version
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-git${VERSION_GIT_DATE})
# Make available in a header file...
configure_file (
"include/pistache/version.h.in"
......@@ -108,16 +73,6 @@ endif ()
@ONLY
)
# Install version header...
if(PISTACHE_INSTALL)
install (
FILES
${CMAKE_CURRENT_BINARY_DIR}/include/pistache/version.h
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/pistache/
)
endif()
# Set public interface version...
# Major should be incremented every time a non-backward compatible change
......@@ -130,56 +85,14 @@ endif ()
string(REGEX MATCH "SONAME_VERSION_MINOR *([0-9]+)" _ ${VERSION_FILE})
set(SONAME_VERSION_MINOR ${CMAKE_MATCH_1})
# Set libraries that we need to link against...
# Minimum...
set(LIBS "-lpistache -lpthread")
if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
set(LIBS "-latomic")
endif ()
# If building with OpenSSL support...
if(PISTACHE_USE_SSL)
set(LIBS "${LIBS} -lssl -lcrypto")
endif(PISTACHE_USE_SSL)
# Configure the pkg-config metadata...
# Initialize the metadata variables and to support remote builds...
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin)
set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}/)
set(libs ${LIBS})
set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}/)
set(version ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-git${VERSION_GIT_DATE})
# Perform substitutions...
configure_file (
"libpistache.pc.in"
"libpistache.pc"
@ONLY
)
# Install pkg-config metadata into standard location within the prefix...
if(PISTACHE_INSTALL)
install (
FILES
${CMAKE_CURRENT_BINARY_DIR}/libpistache.pc
DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig/
)
endif()
add_subdirectory (src)
if (PISTACHE_BUILD_EXAMPLES)
add_subdirectory (examples)
endif()
if (PISTACHE_BUILD_TESTS)
include(CTest)
find_package(GTest QUIET)
if (NOT GTEST_FOUND)
include(FetchContent)
message("GoogleTest not found. Consider installing it on your system. Downloading it from source...")
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
......@@ -196,53 +109,3 @@ if (PISTACHE_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
if (PISTACHE_BUILD_DOCS)
find_package(Doxygen
REQUIRED dot
OPTIONAL_COMPONENTS mscgen dia)
if (DOXYGEN_FOUND)
set(DOXYGEN_IN ${CMAKE_SOURCE_DIR}/docs/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile)
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
add_custom_target(docs
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs
COMMENT "Generating doxygen documentation"
VERBATIM)
message("-- Adding doxygen documentation done")
else(DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen need to be installed to generate the doxygen documentation")
endif(DOXYGEN_FOUND)
endif()
# Generate source tarball...
# Define version of source archive...
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
# Generate a .tar.bz2
set(CPACK_SOURCE_GENERATOR "TBZ2")
# Set filename...
set(CPACK_SOURCE_PACKAGE_FILE_NAME
"${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
# Don't include these files in the archive...
set(CPACK_SOURCE_IGNORE_FILES
"/build/;/debian/;/prefix/;/.git*/;~$;${CPACK_SOURCE_IGNORE_FILES}")
# Include the CPack module for generating the archive and add the standard
# dist target to the generated makefile...
include(CPack)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
......@@ -198,15 +198,15 @@ $ meson test -C build
Be patient, async_test can take some time before completing. And that's it, now you can start playing with your newly installed Pistache framework.
Some other Meson and CMake options:
Some other Meson options:
| Option | Default | Description |
|-------------------------------|-------------|------------------------------------------------|
| PISTACHE_BUILD_EXAMPLES | False | Build all of the example apps |
| PISTACHE_USE_SSL | False | Build server with SSL support |
| PISTACHE_BUILD_TESTS | False | Build all of the unit tests |
| PISTACHE_ENABLE_NETWORK_TESTS | True | Run unit tests requiring remote network access |
| PISTACHE_USE_SSL | False | Build server with SSL support |
| PISTACHE_PIC | True | Enable PIC in the static library |
| PISTACHE_BUILD_EXAMPLES | False | Build all of the example apps |
| PISTACHE_BUILD_DOCS | False | Build Doxygen docs |
## Continuous Integration Testing
......
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs/
INPUT = @CMAKE_SOURCE_DIR@/README.md @CMAKE_SOURCE_DIR@/src/ @CMAKE_SOURCE_DIR@/include/ @CMAKE_SOURCE_DIR@/examples/ @CMAKE_SOURCE_DIR@/docs/
USE_MDFILE_AS_MAINPAGE = @CMAKE_SOURCE_DIR@/README.md
OUTPUT_DIRECTORY = @CURRENT_BUILD_DIR@/docs/
INPUT = @SOURCE_DIR@/README.md @SOURCE_DIR@/src/ @SOURCE_DIR@/include/ @SOURCE_DIR@/examples/ @SOURCE_DIR@/docs/
USE_MDFILE_AS_MAINPAGE = @SOURCE_DIR@/README.md
EXCLUDE_PATTERNS = */.git/*
EXCLUDE_PATTERNS += */subprojects/*
EXCLUDE_PATTERNS += */tests/*
......
doxygen = find_program('doxygen', required: true)
doxygen = find_program('doxygen')
dot = find_program('dot')
mscgen = find_program('mscgen', required: false)
configure_file(input: 'Doxyfile.in', output: 'Doxyfile', configuration: {
'CMAKE_CURRENT_BINARY_DIR': meson.current_build_dir(),
'CMAKE_SOURCE_DIR': meson.project_source_root(),
'CURRENT_BUILD_DIR': meson.current_build_dir(),
'SOURCE_DIR': meson.source_root(),
'PROJECT_NAME': meson.project_name()
})
......
function(pistache_example example_name)
set(EXAMPLE_EXECUTABLE run_${example_name})
set(EXAMPLE_SOURCE ${example_name}.cc)
add_executable(${EXAMPLE_EXECUTABLE} ${EXAMPLE_SOURCE})
target_link_libraries(${EXAMPLE_EXECUTABLE} pistache_static)
endfunction()
pistache_example(hello_server)
pistache_example(http_server)
pistache_example(http_client)
pistache_example(rest_server)
pistache_example(custom_header)
pistache_example(http_server_shutdown)
find_package(RapidJSON QUIET)
if (NOT RapidJSON_FOUND)
include(FetchContent)
FetchContent_Declare(
RapidJSON
GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
GIT_TAG v1.1.0
GIT_SHALLOW true
)
set(RAPIDJSON_BUILD_DOC OFF CACHE BOOL "")
set(RAPIDJSON_BUILD_EXAMPLES OFF CACHE BOOL "")
set(RAPIDJSON_BUILD_TESTS OFF CACHE BOOL "")
if(NOT RapidJSON_POPULATED)
FetchContent_Populate(RapidJSON)
add_subdirectory(${rapidjson_SOURCE_DIR} ${rapidjson_BINARY_DIR})
endif()
pistache_example(rest_description)
target_include_directories(run_rest_description PRIVATE ${rapidjson_SOURCE_DIR}/include)
else()
pistache_example(rest_description)
target_include_directories(run_rest_description PRIVATE ${RAPIDJSON_INCLUDE_DIRS})
endif()
rapidjson_dep = dependency('RapidJSON', fallback: ['rapidjson', 'rapidjson_dep'], required: true)
pistache_example_files = [
'custom_header',
'hello_server',
'http_client',
'http_server_shutdown',
'http_server',
'rest_server'
'rest_server',
'rest_description'
]
foreach example_name : pistache_example_files
executable('run'+example_name, example_name+'.cc', dependencies: pistache_static_dep)
endforeach
executable('run_rest_description', 'rest_description.cc', dependencies: [pistache_static_dep, rapidjson_dep])
......@@ -24,7 +24,7 @@ add_project_arguments(compiler.get_supported_arguments(['-Wconversion', '-Wno-mi
# No need for --coverage, since b_coverage is set
if get_option('b_coverage')
add_global_arguments(compiler.get_supported_arguments(['-fstack-protector-all', '--param=ssp-buffer-size=4']), language: 'cpp')
add_project_arguments(compiler.get_supported_arguments(['-fstack-protector-all', '--param=ssp-buffer-size=4']), language: 'cpp')
endif
##### BEGIN CheckAtomic.cmake
......@@ -65,10 +65,10 @@ if is_libatomic_needed
pc_libs += '-latomic'
endif
deps_libpistache = [dependency('threads')]
deps_libpistache = [dependency('threads'), dependency('RapidJSON', fallback: ['rapidjson', 'rapidjson_dep'])]
if get_option('PISTACHE_USE_SSL')
deps_libpistache += dependency('openssl', required: true)
deps_libpistache += dependency('openssl')
pc_libs += ['-lssl', '-lcrypto']
endif
......
......@@ -24,7 +24,7 @@ sudo apt install libpistache-dev
Otherwise, here's how to build and install the latest release:
```shell
git clone --recurse-submodules https://github.com/pistacheio/pistache.git
git clone https://github.com/pistacheio/pistache.git
cd pistache
meson setup build
meson install -C build
......
......@@ -18,14 +18,32 @@ add_definitions(-DONLY_C_LOCALE=1)
set(PISTACHE_INCLUDE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
find_package(RapidJSON QUIET)
if (NOT RapidJSON_FOUND)
message("RapidJSON not found. Consider installing it on your system. Downloading it from source...")
include(FetchContent)
FetchContent_Declare(
RapidJSON
GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
GIT_TAG v1.1.0
GIT_SHALLOW true
)
set(RAPIDJSON_BUILD_DOC OFF CACHE BOOL "")
set(RAPIDJSON_BUILD_EXAMPLES OFF CACHE BOOL "")
set(RAPIDJSON_BUILD_TESTS OFF CACHE BOOL "")
if(NOT RapidJSON_POPULATED)
FetchContent_Populate(RapidJSON)
add_subdirectory(${rapidjson_SOURCE_DIR} ${rapidjson_BINARY_DIR})
endif()
target_include_directories(pistache PRIVATE ${rapidjson_SOURCE_DIR}/include)
else()
target_include_directories(pistache PRIVATE ${RAPIDJSON_INCLUDE_DIRS})
endif()
target_include_directories(pistache PUBLIC ${PISTACHE_INCLUDE})
set(include_install_dir ${CMAKE_INSTALL_INCLUDEDIR})
set(lib_install_dir ${CMAKE_INSTALL_LIBDIR})
set(bin_install_dir ${CMAKE_INSTALL_BINDIR})
if (BUILD_SHARED_LIBS)
add_library(pistache_shared SHARED $<TARGET_OBJECTS:pistache>)
target_link_libraries(pistache_shared PRIVATE Threads::Threads ${CMAKE_REQUIRED_LIBRARIES})
......@@ -51,7 +69,7 @@ endif ()
set(Pistache_OUTPUT_NAME "pistache")
if (BUILD_SHARED_LIBS)
set_target_properties(pistache_shared PROPERTIES
OUTPUT_NAME ${Pistache_OUTPUT_NAME}-${version}
OUTPUT_NAME ${Pistache_OUTPUT_NAME}-${VERSION}
SOVERSION ${SONAME_VERSION_MAJOR}.${SONAME_VERSION_MINOR}
)
endif ()
......@@ -59,50 +77,3 @@ endif ()
set_target_properties(pistache_static PROPERTIES
OUTPUT_NAME ${Pistache_OUTPUT_NAME}
)
if (PISTACHE_INSTALL)
set(Pistache_CMAKE_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/pistache")
set(Pistache_CONFIG_FILE "PistacheConfig.cmake")
set(Pistache_CONFIG_VERSION_FILE "PistacheConfigVersion.cmake")
if (BUILD_SHARED_LIBS)
install(
TARGETS pistache_shared
EXPORT PistacheTargets
ARCHIVE DESTINATION ${lib_install_dir}
LIBRARY DESTINATION ${lib_install_dir}
RUNTIME DESTINATION ${bin_install_dir}
INCLUDES DESTINATION ${include_install_dir})
endif ()
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/include/pistache"
DESTINATION ${include_install_dir}
FILES_MATCHING PATTERN "*.*h")
install(TARGETS pistache_static
EXPORT PistacheTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT PistacheTargets
DESTINATION ${Pistache_CMAKE_INSTALL_PATH}
EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${Pistache_CONFIG_FILE}.in"
"${CMAKE_CURRENT_BINARY_DIR}/${Pistache_CONFIG_FILE}"
INSTALL_DESTINATION ${Pistache_CMAKE_INSTALL_PATH}
PATH_VARS include_install_dir lib_install_dir
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${Pistache_CONFIG_VERSION_FILE}"
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
COMPATIBILITY AnyNewerVersion)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${Pistache_CONFIG_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${Pistache_CONFIG_VERSION_FILE}"
DESTINATION ${Pistache_CMAKE_INSTALL_PATH}
COMPONENT cmake-config
)
endif()
@PACKAGE_INIT@
set_and_check ( Pistache_INCLUDE_DIRS "@PACKAGE_include_install_dir@")
set_and_check ( Pistache_LIBRARIES "@PACKAGE_lib_install_dir@")
#Required for the static library
find_package(Threads REQUIRED)
if (@PISTACHE_USE_SSL@)
find_package(OpenSSL REQUIRED COMPONENTS SSL Crypto)
endif ()
include("${CMAKE_CURRENT_LIST_DIR}/PistacheTargets.cmake")
......@@ -54,4 +54,3 @@ if (PISTACHE_USE_SSL)
pistache_test(https_server_test)
endif (PISTACHE_USE_SSL)
curl_dep = dependency('libcurl', required: true)
gtest_main_dep = dependency('gtest', main: true, required: true, fallback: ['gtest', 'gtest_main_dep'])
valgrind = find_program('valgrind', required: false)
gcov = find_program('gcov', required: false)
cppcheck = find_program('cppcheck', required: false)
if cppcheck.found()
cppcheck_args = ['--enable=all','-DCPPCHECK','--suppress=*:third-party*','--suppress=*:tests*','--suppress=noExplicitConstructor:include/pistache/optional.h']
else
warning('Can\'t find Cppcheck')
endif
# TODO
curl_dep = dependency('libcurl')
gtest_main_dep = dependency('gtest', main: true, fallback: ['gtest', 'gtest_main_dep'])
pistache_test_files = [
'mime_test',
......@@ -39,7 +29,7 @@ pistache_test_files = [
'string_logger_test'
]
if get_option('PISTACHE_ENABLE_NETWORK_TESTS')
pistache_test_files += 'net_test'
pistache_test_files += 'net_test'
endif
if get_option('PISTACHE_USE_SSL')
pistache_test_files += 'https_server_test'
......@@ -63,3 +53,25 @@ foreach test_name : pistache_test_files
is_parallel: false
)
endforeach
cppcheck = find_program('cppcheck', required: false)
if cppcheck.found()
cppcheck_args = [
'--project=' + (meson.build_root()/'compile_commands.json'),
'--enable=all',
'-DCPPCHECK',
'--suppress=*:*tests/*',
'--suppress=*:*subprojects/*',
'--suppress=noExplicitConstructor:include/pistache/optional.h',
'--std=' + get_option('cpp_std')
]
run_target(
'cppcheck',
command: [
cppcheck,
cppcheck_args
]
)
else
warning('Can\'t find Cppcheck')
endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment