
* Add instructions for Android Co-authored-by: eboasson <eb@ilities.com> Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
274 lines
9.7 KiB
CMake
274 lines
9.7 KiB
CMake
#
|
|
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
|
#
|
|
# This program and the accompanying materials are made available under the
|
|
# terms of the Eclipse Public License v. 2.0 which is available at
|
|
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
|
# v. 1.0 which is available at
|
|
# http://www.eclipse.org/org/documents/edl-v10.php.
|
|
#
|
|
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
#
|
|
include(CheckCSourceCompiles)
|
|
include(CheckLibraryExists)
|
|
include(GenerateDummyExportHeader)
|
|
|
|
# Lightweight IP stack can be used on non-embedded targets too, but the
|
|
# runtime must be instructed to use it instead of the native stack. Of course
|
|
# for embedded targets there is no "native" stack and the runtime module must
|
|
# always be instructed to use an "alternative" stack.
|
|
option(WITH_LWIP "Use lightweight IP stack" OFF)
|
|
option(WITH_DNS "Enable domain name lookups" ON)
|
|
option(WITH_FREERTOS "Build for FreeRTOS" OFF)
|
|
|
|
function(check_runtime_feature SOURCE_FILE)
|
|
get_target_property(_defs ddsrt INTERFACE_COMPILE_DEFINITIONS)
|
|
foreach(_def ${_defs})
|
|
set(_strdefs "${_strdefs} -D${_def}")
|
|
endforeach()
|
|
|
|
# Generate dummy export header required by feature tests.
|
|
generate_dummy_export_header(
|
|
ddsrt
|
|
BASE_NAME dds
|
|
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/cmake/include/dds/export.h")
|
|
set(_strincs "${CMAKE_CURRENT_BINARY_DIR}/cmake/include")
|
|
|
|
get_target_property(_incs ddsrt INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(_inc ${_incs})
|
|
set(_strincs "${_strincs};${_inc}")
|
|
endforeach()
|
|
|
|
if(_strincs)
|
|
set(_strincs "-DINCLUDE_DIRECTORIES:STRING=${_strincs}")
|
|
endif()
|
|
|
|
set(expr "cmake_([_a-zA-Z0-9]+)=([_a-zA-Z0-9]+)")
|
|
try_compile(
|
|
foo "${CMAKE_BINARY_DIR}"
|
|
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}"
|
|
CMAKE_FLAGS "${_strincs}"
|
|
COMPILE_DEFINITIONS "${_strdefs}"
|
|
OUTPUT_VARIABLE output)
|
|
string(REGEX MATCHALL "${expr}" matches "${output}")
|
|
foreach(match ${matches})
|
|
string(REGEX REPLACE "${expr}" "\\1" option "${match}")
|
|
string(REGEX REPLACE "${expr}" "\\2" value "${match}")
|
|
set(${option} ${value} PARENT_SCOPE)
|
|
endforeach()
|
|
endfunction()
|
|
|
|
if(WITH_FREERTOS)
|
|
set(system_name freertos)
|
|
elseif(APPLE)
|
|
set(system_name darwin)
|
|
elseif(ANDROID)
|
|
# FIXME: Not correct, but will do for the short-term. A better way would be
|
|
# fallback to linux, and then posix.
|
|
set(system_name linux)
|
|
else()
|
|
string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name)
|
|
endif()
|
|
|
|
# A better choice is to use a so-called object library for ddsrt, but it was
|
|
# not possible to use target_link_libraries with object libraries until CMake
|
|
# 3.12. At the time of this writing most long-term stable distributions still
|
|
# ship an older version, so an interface library with public sources is used
|
|
# as a workaround for now.
|
|
add_library(ddsrt INTERFACE)
|
|
|
|
foreach(opt WITH_LWIP WITH_DNS WITH_FREERTOS)
|
|
if(${opt})
|
|
target_compile_definitions(ddsrt INTERFACE DDSRT_${opt}=1)
|
|
else()
|
|
target_compile_definitions(ddsrt INTERFACE DDSRT_${opt}=0)
|
|
endif()
|
|
endforeach()
|
|
|
|
target_include_directories(
|
|
ddsrt INTERFACE
|
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
|
|
|
|
# Generate version header.
|
|
configure_file("include/dds/version.h.in" "include/dds/version.h")
|
|
target_sources(
|
|
ddsrt INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include/dds/version.h")
|
|
|
|
if(WIN32)
|
|
configure_file("include/getopt.h.in" "include/getopt.h" COPYONLY)
|
|
list(APPEND headers "${CMAKE_CURRENT_BINARY_DIR}/include/getopt.h")
|
|
list(APPEND sources "${CMAKE_CURRENT_SOURCE_DIR}/src/getopt.c")
|
|
endif()
|
|
|
|
set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
|
set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
|
|
|
list(APPEND headers
|
|
"${include_path}/dds/ddsrt/avl.h"
|
|
"${include_path}/dds/ddsrt/fibheap.h"
|
|
"${include_path}/dds/ddsrt/hopscotch.h"
|
|
"${include_path}/dds/ddsrt/thread_pool.h"
|
|
"${include_path}/dds/ddsrt/log.h"
|
|
"${include_path}/dds/ddsrt/retcode.h"
|
|
"${include_path}/dds/ddsrt/attributes.h"
|
|
"${include_path}/dds/ddsrt/endian.h"
|
|
"${include_path}/dds/ddsrt/arch.h"
|
|
"${include_path}/dds/ddsrt/misc.h"
|
|
"${include_path}/dds/ddsrt/mh3.h"
|
|
"${include_path}/dds/ddsrt/io.h"
|
|
"${include_path}/dds/ddsrt/process.h"
|
|
"${include_path}/dds/ddsrt/strtod.h"
|
|
"${include_path}/dds/ddsrt/strtol.h"
|
|
"${include_path}/dds/ddsrt/types.h"
|
|
"${include_path}/dds/ddsrt/countargs.h"
|
|
"${include_path}/dds/ddsrt/static_assert.h"
|
|
"${include_path}/dds/ddsrt/circlist.h")
|
|
|
|
list(APPEND sources
|
|
"${source_path}/bswap.c"
|
|
"${source_path}/io.c"
|
|
"${source_path}/log.c"
|
|
"${source_path}/retcode.c"
|
|
"${source_path}/strtod.c"
|
|
"${source_path}/strtol.c"
|
|
"${source_path}/mh3.c"
|
|
"${source_path}/avl.c"
|
|
"${source_path}/expand_envvars.c"
|
|
"${source_path}/fibheap.c"
|
|
"${source_path}/hopscotch.c"
|
|
"${source_path}/thread_pool.c"
|
|
"${source_path}/xmlparser.c"
|
|
"${source_path}/circlist.c")
|
|
|
|
# Not every target offers the same set of features. For embedded targets the
|
|
# set of features may even be different between builds. e.g. a FreeRTOS build
|
|
# could use the lightweight IP stack, but later change to FreeRTOS+TCP.
|
|
#
|
|
# Most features and target specific settings can be determined at compile time
|
|
# by a combination of pre-defined macros. However, some features require input
|
|
# from the build system. e.g. that the target operating system is FreeRTOS or
|
|
# that the network stack to be used is lwIP as opposed to the target native
|
|
# network stack. In order to mix-and-match various compilers, architectures,
|
|
# operating systems, etc input from the build system is required.
|
|
foreach(feature atomics cdtors environ heap ifaddrs random rusage
|
|
sockets string sync threads time md5 process netstat)
|
|
if(EXISTS "${include_path}/dds/ddsrt/${feature}.h")
|
|
list(APPEND headers "${include_path}/dds/ddsrt/${feature}.h")
|
|
file(GLOB_RECURSE
|
|
files
|
|
CONFIGURE_DEPENDS
|
|
"${include_path}/dds/ddsrt/${feature}/*.h")
|
|
list(APPEND headers ${files})
|
|
|
|
# Do not add any sources if a feature is not offered by the target. The
|
|
# headers will define any macros needed by the source code by combining
|
|
# build system exports and pre-defined macros. To determine if a certain
|
|
# feature is offered by the target and whether or not to compile any
|
|
# source files, that information must be made available to CMake.
|
|
#
|
|
# Tests that export the required information can be written in
|
|
# cmake/${feature}.c. A test consists of a source file that includes the
|
|
# required header files and results in a specifically crafted compiler
|
|
# error that is picked up by CMake. By default, if a file named after the
|
|
# feature does not exist in cmake, the feature is expected to be
|
|
# implemented for all targets.
|
|
string(TOUPPER "${feature}" feature_uc)
|
|
set(HAVE_${feature_uc} TRUE)
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${feature}.c")
|
|
check_runtime_feature("cmake/${feature}.c")
|
|
endif()
|
|
|
|
if(HAVE_${feature_uc})
|
|
# Code that is more-or-less the same for all targets can placed in
|
|
# src/<feature>.c. An example would be ddsrt_freeifaddrs.
|
|
if(EXISTS "${source_path}/${feature}.c")
|
|
list(APPEND sources "${source_path}/${feature}.c")
|
|
endif()
|
|
set(system_exists FALSE)
|
|
|
|
# Headers that must remain private but are required by other runtime
|
|
# source files must be located in src/<feature>/dds/ddsrt.
|
|
if(IS_DIRECTORY "${source_path}/${feature}/include")
|
|
file(GLOB_RECURSE
|
|
files
|
|
CONFIGURE_DEPENDS
|
|
"${source_path}/${feature}/include/*.h")
|
|
list(APPEND headers ${files})
|
|
target_include_directories(
|
|
ddsrt INTERFACE
|
|
"$<BUILD_INTERFACE:${source_path}/${feature}/include/>")
|
|
endif()
|
|
|
|
# Allow custom implementations for a feature. e.g. lwip as opposed to
|
|
# windows or posix.
|
|
set(_system_name "${system_name}")
|
|
if(NOT HAVE_${feature_uc} MATCHES "[tT][rR][uU][eE]")
|
|
set(_system_name "${HAVE_${feature_uc}}")
|
|
endif()
|
|
|
|
foreach(system ${_system_name} posix)
|
|
if(IS_DIRECTORY "${source_path}/${feature}/${system}")
|
|
file(GLOB_RECURSE
|
|
files
|
|
CONFIGURE_DEPENDS
|
|
"${source_path}/${feature}/${system}/*.c")
|
|
list(APPEND sources ${files})
|
|
set(system_exists TRUE)
|
|
endif()
|
|
# Break as soon a system-specific headers or sources are found.
|
|
if(system_exists)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
else()
|
|
message(STATUS "Feature ${feature} disabled")
|
|
endif()
|
|
else()
|
|
message(FATAL_ERROR "Feature ${feature} does not exist")
|
|
endif()
|
|
endforeach()
|
|
|
|
target_sources(ddsrt INTERFACE ${sources} ${headers})
|
|
|
|
set(HAVE_MULTI_PROCESS ${HAVE_MULTI_PROCESS} PARENT_SCOPE)
|
|
|
|
if(NOT WITH_FREERTOS)
|
|
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
|
find_package(Threads REQUIRED)
|
|
target_link_libraries(ddsrt INTERFACE Threads::Threads)
|
|
endif()
|
|
|
|
if(WIN32)
|
|
target_link_libraries(ddsrt INTERFACE ws2_32 iphlpapi bcrypt)
|
|
elseif(UNIX)
|
|
check_library_exists(c clock_gettime "" HAVE_CLOCK_GETTIME)
|
|
if(NOT HAVE_CLOCK_GETTIME)
|
|
# Before glibc 2.17, clock_gettime was in librt.
|
|
check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME_RT)
|
|
if(HAVE_CLOCK_GETTIME_RT)
|
|
set(HAVE_CLOCK_GETTIME TRUE)
|
|
target_link_libraries(ddsrt INTERFACE rt)
|
|
endif()
|
|
endif()
|
|
|
|
if(NOT HAVE_CLOCK_GETTIME)
|
|
message(FATAL_ERROR "clock_gettime is not available")
|
|
endif()
|
|
endif()
|
|
|
|
if(${CMAKE_C_COMPILER_ID} STREQUAL "SunPro")
|
|
target_link_libraries(ddsrt INTERFACE socket nsl)
|
|
endif()
|
|
|
|
if(BUILD_TESTING)
|
|
add_subdirectory(tests)
|
|
endif()
|
|
|
|
install(
|
|
DIRECTORY
|
|
"include/"
|
|
${CMAKE_CURRENT_BINARY_DIR}/include/
|
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
|
COMPONENT dev
|
|
FILES_MATCHING PATTERN "*.h")
|