Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor cmake to use modern feature #288

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
197 changes: 102 additions & 95 deletions CMakeLists.txt
Expand Up @@ -17,6 +17,9 @@
## under the License.
##

cmake_minimum_required(VERSION 3.4)
project(qpid-dispatch C)

# Set default build type. Must come before project() which sets default to ""
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE RelWithDebInfo CACHE string
Expand All @@ -27,28 +30,35 @@ if (CMAKE_BUILD_TYPE MATCHES "Deb|Cover")
endif (CMAKE_BUILD_TYPE MATCHES "Deb|Cover")
message(STATUS "Build type is \"${CMAKE_BUILD_TYPE}\"${has_debug_symbols}")

project(qpid-dispatch C)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")

# Build time switch to turn off memory pooling.
option(USE_MEMORY_POOL "Use per-thread memory pools" ON)
option(QD_MEMORY_STATS "Track memory pool usage statistics" ON)

file(STRINGS "${CMAKE_SOURCE_DIR}/VERSION.txt" QPID_DISPATCH_VERSION)

cmake_minimum_required(VERSION 2.6)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(FindPythonInterp)
include(FindPythonLibs)

find_package(PythonInterp REQUIRED)
find_package(PythonLibs REQUIRED)
if (PYTHONLIBS_FOUND)
if(NOT TARGET PythonLibs::PythonLibs)
add_library(PythonLibs::PythonLibs UNKNOWN IMPORTED)
set_target_properties(PythonLibs::PythonLibs PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}")
set_target_properties(PythonLibs::PythonLibs PROPERTIES
IMPORTED_LOCATION ${PYTHON_LIBRARIES})
endif()
endif()

# Find python-unittest2
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import unittest2"
RESULT_VARIABLE UNITTEST2_MISSING
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
RESULT_VARIABLE UNITTEST2_MISSING
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
enable_testing()
if(UNITTEST2_MISSING)
message(STATUS "WARNING: python-unittest2 is not installed. ***unit tests cannot be run***" )
Expand All @@ -60,20 +70,20 @@ endif(UNITTEST2_MISSING)


if (NOT PYTHONLIBS_FOUND)
message(FATAL_ERROR "Python Development Libraries are needed.")
message(FATAL_ERROR "Python Development Libraries are needed.")
endif (NOT PYTHONLIBS_FOUND)

set (SO_VERSION_MAJOR 2)
set (SO_VERSION_MINOR 0)
set (SO_VERSION "${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}")

if (NOT DEFINED LIB_SUFFIX)
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if ("${LIB64}" STREQUAL "TRUE" AND ${CMAKE_SIZEOF_VOID_P} STREQUAL "8")
set(LIB_SUFFIX 64)
else()
set(LIB_SUFFIX "")
endif()
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if ("${LIB64}" STREQUAL "TRUE" AND ${CMAKE_SIZEOF_VOID_P} STREQUAL "8")
set(LIB_SUFFIX 64)
else()
set(LIB_SUFFIX "")
endif()
endif()

set(INCLUDE_INSTALL_DIR include CACHE PATH "Include file directory")
Expand All @@ -93,11 +103,11 @@ set(RUN ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/run.py)

# define the configuration directory based on whether or not the install prefix is defined
if(NOT DEFINED SYSCONF_INSTALL_DIR)
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
set(SYSCONF_INSTALL_DIR "/etc")
else()
set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
endif()
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
set(SYSCONF_INSTALL_DIR "/etc")
else()
set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
endif()
endif()

set(QPID_DISPATCH_CONFDIR ${SYSCONF_INSTALL_DIR}/qpid-dispatch)
Expand All @@ -111,96 +121,93 @@ endif (NOT COMMAND add_compile_options)
##
## Find dependencies
##
find_library(pthread_lib pthread)
find_library(dl_lib dl)
find_library(rt_lib rt)
if (UNIX)
find_package(Glibc REQUIRED dl rt)
endif()
find_package(Threads REQUIRED)
find_package(Proton REQUIRED Core Proactor)

message(STATUS "Found Proton: ${Proton_LIBRARIES} (found version \"${Proton_VERSION}\")" )

## Optional dependencies
include(FindLibWebSockets)
find_package(LibWebSockets)
option(USE_LIBWEBSOCKETS "Use libwebsockets for WebSocket support" ${LIBWEBSOCKETS_FOUND})

##
## Find Valgrind
##
find_program(VALGRIND_EXECUTABLE valgrind DOC "Location of the valgrind program")
mark_as_advanced(VALGRIND_EXECUTABLE)
find_package_handle_standard_args(VALGRIND DEFAULT_MSG VALGRIND_EXECUTABLE)
option(USE_VALGRIND "Use valgrind when running tests" OFF)

if (USE_VALGRIND)
if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows" AND USE_VALGRIND)
##
## Find Valgrind
##
find_program(VALGRIND_EXECUTABLE valgrind DOC "Location of the valgrind program")
mark_as_advanced(VALGRIND_EXECUTABLE)
find_package_handle_standard_args(VALGRIND DEFAULT_MSG VALGRIND_EXECUTABLE)

if (CMAKE_BUILD_TYPE MATCHES "Coverage")
message(WARNING "Building for coverage analysis; disabling valgrind run-time error detection")
else ()
set(TEST_RUNNER "${VALGRIND_EXECUTABLE} --quiet --leak-check=full --show-leak-kinds=definite --errors-for-leak-kinds=definite --error-exitcode=42 --suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.supp")
endif ()
endif()

option(USE_SANITIZERS "Compile with sanitizers (ASan, UBSan, TSan); incompatible with Valgrind" OFF)
if (USE_SANITIZERS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined")
add_compile_options(-g)
add_compile_options(-fno-omit-frame-pointer)
endif (USE_SANITIZERS)

option(USE_TSAN "Compile with ThreadSanitizer (TSan); incompatible with Valgrind" OFF)
if (USE_TSAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
add_compile_options(-g)
add_compile_options(-fno-omit-frame-pointer)
endif (USE_TSAN)
if (NOT USE_VALGRIND AND (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU"))
option(USE_SANITIZERS "Compile with sanitizers (ASan, UBSan, TSan); incompatible with Valgrind" OFF)
if (USE_SANITIZERS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined")
endif (USE_SANITIZERS)

option(USE_TSAN "Compile with ThreadSanitizer (TSan); incompatible with Valgrind" OFF)
if (USE_TSAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
endif (USE_TSAN)

if (USE_SANITIZERS OR USE_TSAN)
add_compile_options(-g)
add_compile_options(-fno-omit-frame-pointer)
endif()
endif()

##
## Include directories used by all sub-directories.
##
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/include
${Proton_Proactor_INCLUDE_DIRS}
${Proton_Core_INCLUDE_DIRS}
${PYTHON_INCLUDE_PATH}
)

if (NOT CMAKE_SYSTEM_NAME STREQUAL SunOS)
add_compile_options(-Werror)
add_compile_options(-Wall)
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wpedantic HAS_PEDANTIC_FLAG)
if (HAS_PEDANTIC_FLAG)
if (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
add_compile_options(-Werror)
add_compile_options(-Wall)
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wpedantic HAS_PEDANTIC_FLAG)
if (HAS_PEDANTIC_FLAG)
add_compile_options(-Wpedantic)
endif(HAS_PEDANTIC_FLAG)
add_compile_options(-std=gnu99)
add_compile_options(-pthread)
if (CMAKE_BUILD_TYPE MATCHES "Coverage")
set (CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage")
set (CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage")
set (CMAKE_MODULE_LINKER_FLAGS_COVERAGE "--coverage")
set (CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage")
mark_as_advanced(
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_MODULE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
make_directory(${CMAKE_BINARY_DIR}/coverage_results)
add_custom_target(coverage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/coverage_results
COMMAND ${CMAKE_SOURCE_DIR}/bin/record-coverage.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
endif(CMAKE_BUILD_TYPE MATCHES "Coverage")
else (NOT CMAKE_SYSTEM_NAME STREQUAL SunOS)
add_compile_options(-xc99)
add_compile_options(-errwarn=%all)
add_compile_options(-lpthread)
endif (NOT CMAKE_SYSTEM_NAME STREQUAL SunOS)

if (CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wno-gnu-statement-expression)
endif(HAS_PEDANTIC_FLAG)
add_compile_options(-std=gnu99)

if (CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wno-gnu-statement-expression)
endif()

if (CMAKE_BUILD_TYPE MATCHES "Coverage")
set (CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage")
set (CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage")
set (CMAKE_MODULE_LINKER_FLAGS_COVERAGE "--coverage")
set (CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage")
mark_as_advanced(
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_MODULE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
make_directory(${CMAKE_BINARY_DIR}/coverage_results)
add_custom_target(coverage
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/coverage_results
COMMAND ${CMAKE_SOURCE_DIR}/bin/record-coverage.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
endif(CMAKE_BUILD_TYPE MATCHES "Coverage")

if (NOT (USE_SANITIZERS OR USE_TSAN))
set(CATCH_UNDEFINED "-Wl,-z,defs")
endif()

elseif (CMAKE_C_COMPILER_ID MATCHES "SunPro")
add_compile_options(-xc99)
add_compile_options(-errwarn=%all)
add_compile_options(-lpthread)

elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
# empty for now
endif()

if (NOT (USE_SANITIZERS OR USE_TSAN))
set(CATCH_UNDEFINED "-Wl,-z,defs")
endif ()

##
## Header file installation
Expand All @@ -213,9 +220,9 @@ install(FILES etc/sasl2/qdrouterd.conf DESTINATION ${SYSCONF_INSTALL_DIR}/sasl2)

# Tools
install(PROGRAMS
${CMAKE_CURRENT_SOURCE_DIR}/tools/qdstat
${CMAKE_CURRENT_SOURCE_DIR}/tools/qdmanage
DESTINATION bin)
${CMAKE_CURRENT_SOURCE_DIR}/tools/qdstat
${CMAKE_CURRENT_SOURCE_DIR}/tools/qdmanage
DESTINATION bin)


# Doc files
Expand Down
80 changes: 80 additions & 0 deletions cmake/Modules/FindGlibc.cmake
@@ -0,0 +1,80 @@
# Try to find glibc-devel
# Once done, this will define
#
# GLIBC_FOUND - system has glibc-devel
# GLIBC_LIBRARIES - libraries needed to use glibc
# GLIBC_DL_LIBRARY - libraries needed to use dl
# GLIBC_RT_LIBRARY - libraries needed to use rt

include(FindPackageHandleStandardArgs)

if(GLIBC_LIBRARIES)
set(GLIBC_FIND_QUIETLY TRUE)
else()
find_library(
GLIBC_DL_LIBRARY
NAMES dl
HINTS ${GLIBC_ROOT_DIR}
PATH_SUFFIXES ${LIBRARY_PATH_PREFIX})

find_library(
GLIBC_RT_LIBRARY
NAMES rt
HINTS ${GLIBC_ROOT_DIR}
PATH_SUFFIXES ${LIBRARY_PATH_PREFIX})

# Math library
find_library(
GLIBC_M_LIBRARY
NAMES m
HINTS ${GLIBC_ROOT_DIR}
PATH_SUFFIXES ${LIBRARY_PATH_PREFIX})

find_package_handle_standard_args(Glibc-dl DEFAULT_MSG
GLIBC_DL_LIBRARY)
find_package_handle_standard_args(Glibc-rt DEFAULT_MSG
GLIBC_RT_LIBRARY)
find_package_handle_standard_args(Glibc-m DEFAULT_MSG
GLIBC_M_LIBRARY)

find_package_handle_standard_args(Glibc DEFAULT_MSG
GLIBC_DL_LIBRARY
GLIBC_RT_LIBRARY
GLIBC_M_LIBRARY)

if (Glibc_FOUND)
set(GLIBC_LIBRARIES
${GLIBC_M_LIBRARY}
${GLIBC_DL_LIBRARY}
${GLIBC_RT_LIBRARY})

mark_as_advanced(GLIBC_DL_LIBRARY GLIBC_RT_LIBRARY)

if(NOT TARGET Glibc::m)
add_library(Glibc::m UNKNOWN IMPORTED)
set_target_properties(Glibc::m PROPERTIES
IMPORTED_LOCATION ${GLIBC_M_LIBRARY})
endif()

if(NOT TARGET Glibc::rt)
add_library(Glibc::rt UNKNOWN IMPORTED)
set_target_properties(Glibc::rt PROPERTIES
IMPORTED_LOCATION ${GLIBC_RT_LIBRARY})
endif()

if(NOT TARGET Glibc::dl)
add_library(Glibc::dl UNKNOWN IMPORTED)
set_target_properties(Glibc::dl PROPERTIES
IMPORTED_LOCATION ${GLIBC_DL_LIBRARY})
endif()

if(NOT TARGET Glibc::Glibc)
add_library(Glibc::Glibc UNKNOWN IMPORTED)
set_target_properties(Glibc::Glibc PROPERTIES
#INTERFACE_LINK_LIBRARIES Glibc::m Glibc::rt Glibc::dl
IMPORTED_LOCATION ${GLIBC_M_LIBRARY}
IMPORTED_LOCATION ${GLIBC_DL_LIBRARY}
IMPORTED_LOCATION ${GLIBC_RT_LIBRARY})
endif()
endif()
endif()
Expand Up @@ -39,8 +39,8 @@ find_library(LIBWEBSOCKETS_LIBRARIES

find_path(LIBWEBSOCKETS_INCLUDE_DIRS
NAMES libwebsockets.h
HINTS ${LIBWEBSOCKETS_INCLUDEDIR} ${LIBWEBSOCKETS_ROOT}/include ${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/include
HINTS ${LIBWEBSOCKETS_INCLUDEDIR} "${LIBWEBSOCKETS_ROOT}/include" "${CMAKE_INSTALL_PREFIX}/include"
PATHS "/usr/include"
)

if(LIBWEBSOCKETS_INCLUDE_DIRS AND EXISTS "${LIBWEBSOCKETS_INCLUDE_DIRS}/lws_config.h")
Expand All @@ -56,11 +56,21 @@ if (LIBWEBSOCKETS_VERSION_STRING AND (LIBWEBSOCKETS_VERSION_STRING VERSION_LESS
message(STATUS "Found libwebsockets version ${LIBWEBSOCKETS_VERSION_STRING} but need at least ${lws_required}")
else()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
LIBWEBSOCKETS DEFAULT_MSG LIBWEBSOCKETS_VERSION_STRING LIBWEBSOCKETS_LIBRARIES LIBWEBSOCKETS_INCLUDE_DIRS)
find_package_handle_standard_args(LIBWEBSOCKETS DEFAULT_MSG
LIBWEBSOCKETS_VERSION_STRING
LIBWEBSOCKETS_LIBRARIES
LIBWEBSOCKETS_INCLUDE_DIRS)
endif()

if(NOT LIBWEBSOCKETS_FOUND)
if(LIBWEBSOCKETS_FOUND)
if(NOT TARGET WebSockets::WebSockets)
add_library(WebSockets::WebSockets UNKNOWN IMPORTED)
set_target_properties(WebSockets::WebSockets PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LIBWEBSOCKETS_INCLUDE_DIRS}")
set_target_properties(WebSockets::WebSockets PROPERTIES
IMPORTED_LOCATION ${LIBWEBSOCKETS_LIBRARIES})
endif()
else()
unset(LIBWEBSOCKETS_LIBRARIES)
unset(LIBWEBSOCKETS_INCLUDE_DIRS)
unset(LIBWEBSOCKETS_VERSION_STRING)
Expand Down