cyclonedds/src/ddsrt/CMakeLists.txt
Jeroen Koekkoek 45a5030683
Add instructions for Android (#506)
* Add instructions for Android

Co-authored-by: eboasson <eb@ilities.com>
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2020-05-06 12:53:56 +02:00

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")