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

Static build support #1864

Merged
merged 4 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .azure/templates/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ steps:
} else {
Write-Host "###vso[task.setvariable variable=build_tool_options;]-j 4"
}
choco install -y openssl
#choco install -y openssl
condition: eq(variables['Agent.OS'], 'Windows_NT')
name: setup_windows
- task: Cache@2
Expand Down Expand Up @@ -90,12 +90,23 @@ steps:
cd iceoryx/build
[[ "${AGENT_OS}" == 'Darwin' ]] && BUILD_TOOL_OPTIONS="-j 4"
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_BUILD_SHARED_LIBS=on \
-DCMAKE_BUILD_SHARED_LIBS=${SHAREDLIBS:-on} \
-DCMAKE_INSTALL_PREFIX=install \
${GENERATOR:+-G} "${GENERATOR}" -A "${PLATFORM}" -T "${TOOLSET}" ../iceoryx_meta
cmake --build . --config ${BUILD_TYPE} --target install -- ${BUILD_TOOL_OPTIONS}
condition: eq(variables['iceoryx'], 'on')
name: install_iceoryx
- bash: |
set -e -x
mkdir build-sharedlibs
cd build-sharedlibs
cmake -DCMAKE_INSTALL_PREFIX=install \
-DWERROR=on \
${GENERATOR:+-G} "${GENERATOR}" -A "${PLATFORM}" -T "${TOOLSET}" ..
${SCAN_BUILD} cmake --build . --config ${BUILD_TYPE} --target install -- ${BUILD_TOOL_OPTIONS}
cmake --build . --config ${BUILD_TYPE} --target package -- ${BUILD_TOOL_OPTIONS}
condition: eq(variables['sharedlibs'], 'off')
name: nonstatic_build_script
- bash: |
set -e -x
mkdir build
Expand All @@ -106,9 +117,16 @@ steps:
# Azure sometimes adds a spurious ' to BUILD_TOOL_OPTIONS
BUILD_TOOL_OPTIONS="-j 4"
fi
crosscompiling=
if [[ "${SHAREDLIBS:-on}" == "off" ]] ; then
prefix_path="${BUILD_SOURCESDIRECTORY}/build-sharedlibs/install:${prefix_path}"
crosscompiling="-DCMAKE_CROSSCOMPILING=1 -DCMAKE_SYSTEM_NAME=${AGENT_OS}"
fi
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_INSTALL_PREFIX=install \
-DCMAKE_PREFIX_PATH="${prefix_path//:/;}" \
-DBUILD_SHARED_LIBS=${SHAREDLIBS:-on} \
${crosscompiling} \
-DANALYZER=${ANALYZER:-off} \
-DSANITIZER=${SANITIZER:-none} \
-DENABLE_SSL=${SSL:-on} \
Expand Down Expand Up @@ -158,6 +176,7 @@ steps:
${GENERATOR:+-G} "${GENERATOR}" -A "${PLATFORM}" -T "${TOOLSET}" "${INSTALLPREFIX}/share/CycloneDDS/examples/helloworld"
cmake --build . --config ${BUILD_TYPE} -- ${BUILD_TOOL_OPTIONS}
${SHELL} ../../scripts/sanity_helloworld.bash
condition: ne(variables['sharedlibs'], 'off')
name: sanity_hello_world
displayName: Sanity check Hello World
- bash: |
Expand Down
25 changes: 24 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
cmake_minimum_required(VERSION 3.16)
project(CycloneDDS VERSION 0.11.0 LANGUAGES C)
# C++ is only for Iceoryx plugin
project(CycloneDDS VERSION 0.11.0 LANGUAGES C CXX)

# Set a default build type if none was specified
set(default_build_type "RelWithDebInfo")
Expand All @@ -29,6 +30,28 @@ else()
set(not_crosscompiling ON)
endif()

# By default we do shared libraries (we really prefer shared libraries because of the
# plugins for IDLC, security, PSMX, ...)
#
# For static builds, we recommend doing a regular shared library build first, then
# building the static Cyclone library with CMAKE_CROSSCOMPILING set. This avoids the
# dynamic linking in IDLC of something involving the static library, and that in turn
# avoids a position-dependent/position-independent mess.
#
# Note that on Linux that mess can be partially resolved by defining
#
# CMAKE_POSITION_INDEPENDENT_CODE=1
#
# resulting in a PIC static library, but that is in turn incompatible with the
# system-provided static libraries for OpenSSL. So much easier to avoid it for the rare
# case where it is needed.
#
# It appears that on macOS, all code is position independent and it'll work regardless.
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
if(NOT BUILD_SHARED_LIBS AND NOT CMAKE_CROSSCOMPILING)
message(WARNING "It is probably best to build a static library as-if cross compiling (e.g., use -DCMAKE_CROSSCOMPILING=1 -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCMAKE_PREFIX_PATH=<path to shared-library build>)")
endif()

# By default don't treat warnings as errors, else anyone building it with a different compiler that
# just happens to generate a warning, as well as anyone adding or modifying something and making a
# small mistake would run into errors. CI builds can be configured differently.
Expand Down
6 changes: 6 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ jobs:
# generator: 'MinGW Makefiles'
# cc: 'C:/msys64/mingw64/bin/gcc.exe'
# cxx: 'C:/msys64/mingw64/bin/g++.exe'
'Ubuntu 22.04 LTS with default GCC (Release, Iceoryx, Static, x86_64)':
image: ubuntu-22.04
idlc_xtests: off
build_type: Release
sharedlibs: off
iceoryx: on

steps:
- template: /.azure/templates/build-test.yml
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ if(BUILD_IDLC)
add_subdirectory(idl)
endif()
add_subdirectory(security)
add_subdirectory(core)
if(ENABLE_ICEORYX)
add_subdirectory(psmx_iox)
endif()
add_subdirectory(core)
26 changes: 21 additions & 5 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@
#
include (GenerateExportHeader)

if (BUILD_SHARED_LIBS OR NOT DEFINED BUILD_SHARED_LIBS)
add_library(ddsc SHARED "")
else()
add_library(ddsc)
endif()
add_library(ddsc)

if(BUILD_TESTING)
set_property(TARGET ddsc PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
Expand Down Expand Up @@ -66,6 +62,26 @@ include(cdr/CMakeLists.txt)
include(ddsi/CMakeLists.txt)
include(ddsc/CMakeLists.txt)

# The not-so-elegant inclusion of all configured plug-ins for static builds. At least it
# keeps most of the dirty things in one place.
if(NOT BUILD_SHARED_LIBS)
get_property(plugin_list GLOBAL PROPERTY cdds_plugin_list)
if(plugin_list)
list(JOIN plugin_list "," plugin_commasep)
target_compile_options(ddsc PRIVATE "-DPLUGINS=${plugin_commasep}")
target_link_libraries(ddsc PRIVATE ${plugin_list})
foreach(plugin ${plugin_list})
set(propname ${plugin}_symbols)
get_property(plugin_symbols GLOBAL PROPERTY ${propname})
list(JOIN plugin_symbols "," plugin_symbols_commasep)
target_compile_options(ddsc PRIVATE "-DPLUGIN_SYMBOLS_${plugin}=${plugin_symbols_commasep}")
endforeach()
endif()
if(ENABLE_SSL)
target_link_libraries(ddsc PUBLIC security_openssl)
endif()
endif()

add_coverage(ddsc)
target_link_libraries(ddsc PRIVATE "$<BUILD_INTERFACE:ddsrt>")
target_compile_definitions(
Expand Down
7 changes: 1 addition & 6 deletions src/core/cdr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ else()
include(Generate)
include(GenerateExportHeader)

if (BUILD_SHARED_LIBS OR NOT DEFINED BUILD_SHARED_LIBS)
add_library(cdr SHARED "")
else()
add_library(cdr)
endif()

add_library(cdr)
add_library(${PROJECT_NAME}::cdr ALIAS cdr)

target_sources(cdr PRIVATE ${srcs_cdr} ${hdrs_private_cdr} ${CMAKE_CURRENT_LIST_DIR}/../../ddsrt/src/bswap.c)
Expand Down
3 changes: 1 addition & 2 deletions src/core/ddsc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ install(
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT dev)

# TODO: improve test inclusion.
if((BUILD_TESTING) AND (BUILD_IDLC) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
if((BUILD_TESTING) AND ((NOT DEFINED MSVC_VERSION) OR (MSVC_VERSION GREATER "1800")))
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/tests")
endif()
6 changes: 3 additions & 3 deletions src/core/ddsc/src/dds_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ static dds_return_t dds_write_impl_psmxloan_serdata (struct dds_writer *wr, cons
dds_loaned_sample_unref (loan);
return DDS_RETCODE_BAD_PARAMETER;
}
break;
return DDS_RETCODE_OK;
case DDS_LOAN_ORIGIN_KIND_HEAP:
if (wr->m_endpoint.psmx_endpoints.length == 0)
{
Expand Down Expand Up @@ -718,9 +718,9 @@ static dds_return_t dds_write_impl_psmxloan_serdata (struct dds_writer *wr, cons
return DDS_RETCODE_OUT_OF_RESOURCES;
}
}
break;
return DDS_RETCODE_OK;
}
return DDS_RETCODE_OK;
return DDS_RETCODE_ERROR;
}
else if (use_only_psmx && sertype->is_memcpy_safe)
{
Expand Down
71 changes: 49 additions & 22 deletions src/core/ddsc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
include(CUnit)
include(Generate)

idlc_generate(TARGET RoundTrip FILES RoundTrip.idl)
idlc_generate(TARGET Space FILES Space.idl WARNINGS no-implicit-extensibility)
Expand Down Expand Up @@ -100,9 +101,25 @@ set(ddsc_test_sources
"test_oneliner.h"
"cdrstream.c"
"serdata_keys.c"
"psmx.c"
)

# PSMX tests are tricky in a static build: we have a PSMX plugin that is based on Cyclone
# so we can test the interface even when Iceoryx is not available, but supporting that
# plugin is too complicated in a static build: it introduces a circular dependency and
# that's too hard for me in CMake.
#
# On most platforms (Linux, Windows, macOS) we could still load it dynamically but that
# fails to work because the shared library then includes its own copy of Cyclone DDS and
# then the access to the application readers that the plugin needs is no longer possible
# because they live in the other copy of the library.
#
# Fortunately, running them with Iceoryx doesn't suffer from this. If we simply skip
# these tests in a static build without Iceoryx and then we ensure the static build on CI
# uses Iceoryx, we should be good.
if(BUILD_SHARED_LIBS OR (ENABLE_ICEORYX AND NOT DEFINED ENV{COLCON}))
list(APPEND ddsc_test_sources "psmx.c")
endif()

if(ENABLE_LIFESPAN)
list(APPEND ddsc_test_sources "lifespan.c")
endif()
Expand Down Expand Up @@ -222,23 +239,24 @@ target_link_libraries(oneliner PRIVATE RoundTrip Space ddsc)


# PSMX implementation with Cyclone as transport, for testing
if (BUILD_SHARED_LIBS)
idlc_generate(TARGET psmx_cdds_data FILES psmx_cdds_data.idl)
set(psmx_cdds_sources
"psmx_cdds_impl.c"
"psmx_cdds_impl.h")
add_library(psmx_cdds SHARED ${psmx_cdds_sources})
target_include_directories(
psmx_cdds PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
target_link_libraries(psmx_cdds PRIVATE ddsc psmx_cdds_data)

idlc_generate(TARGET psmx_cdds_data FILES psmx_cdds_data.idl)
set(psmx_cdds_sources
"psmx_cdds_impl.c"
"psmx_cdds_impl.h")
add_library(psmx_cdds SHARED ${psmx_cdds_sources})
target_include_directories(
psmx_cdds PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../ddsi/include>")
target_link_libraries(psmx_cdds PRIVATE ddsc psmx_cdds_data)

generate_export_header(psmx_cdds BASE_NAME PSMX_CDDS EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_cdds/export.h")
generate_export_header(psmx_cdds BASE_NAME PSMX_CDDS EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/psmx_cdds/export.h")

install(TARGETS psmx_cdds
install(TARGETS psmx_cdds
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()

# If Iceoryx is available, then also run all PSMX tests using Iceoryx. Colcon complicates
# things too much and it doesn't affect Cyclone's CI run anyway.
Expand Down Expand Up @@ -285,14 +303,23 @@ kill -0 `cat ctest_fixture_iox_roudi.pid`")
set_tests_properties(stop_roudi PROPERTIES FIXTURES_CLEANUP iox)
set_tests_properties(start_roudi stop_roudi PROPERTIES RESOURCE_LOCK iox_lock)

# Construct Iceoryx-variants of all PSMX tests
# Construct Iceoryx-variants of all PSMX tests if building shared libraries, map them to
# Iceoryx in a static build (because I don't know how to delete tests!)
get_property(test_names DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY TESTS)
list(FILTER test_names INCLUDE REGEX "^CUnit_ddsc_psmx_[A-Za-z_0-9]+$")
foreach(fullname ${test_names})
string(REGEX REPLACE "^CUnit_ddsc_psmx_(.*)" "\\1" shortname "${fullname}")
add_test(NAME ${fullname}_iox COMMAND cunit_ddsc -s ddsc_psmx -t ${shortname})
set_tests_properties(${fullname}_iox PROPERTIES FIXTURES_REQUIRED iox)
set_tests_properties(${fullname}_iox PROPERTIES RESOURCE_LOCK iox_lock)
set_tests_properties(${fullname}_iox PROPERTIES ENVIRONMENT "CDDS_PSMX_NAME=iox;LD_LIBRARY_PATH=$<TARGET_FILE_DIR:psmx_iox>:$ENV{LD_LIBRARY_PATH}")
endforeach()
if(BUILD_SHARED_LIBS)
foreach(fullname ${test_names})
string(REGEX REPLACE "^CUnit_ddsc_psmx_(.*)" "\\1" shortname "${fullname}")
add_test(NAME ${fullname}_iox COMMAND cunit_ddsc -s ddsc_psmx -t ${shortname})
set_tests_properties(${fullname}_iox PROPERTIES FIXTURES_REQUIRED iox)
set_tests_properties(${fullname}_iox PROPERTIES RESOURCE_LOCK iox_lock)
set_tests_properties(${fullname}_iox PROPERTIES ENVIRONMENT "CDDS_PSMX_NAME=iox;LD_LIBRARY_PATH=$<TARGET_FILE_DIR:psmx_iox>:$ENV{LD_LIBRARY_PATH}")
endforeach()
else()
foreach(fullname ${test_names})
set_tests_properties(${fullname} PROPERTIES FIXTURES_REQUIRED iox)
set_tests_properties(${fullname} PROPERTIES RESOURCE_LOCK iox_lock)
set_tests_properties(${fullname} PROPERTIES ENVIRONMENT "CDDS_PSMX_NAME=iox")
endforeach()
endif()
endif()
5 changes: 5 additions & 0 deletions src/ddsrt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ set(headers
set(sources
"${source_dir}/src/atomics.c"
"${source_dir}/src/avl.c"
"${source_dir}/src/dynlib.c"
"${source_dir}/src/bits.c"
"${source_dir}/src/bswap.c"
"${source_dir}/src/io.c"
Expand Down Expand Up @@ -318,6 +319,10 @@ if(BUILD_TESTING)
set(DDS_ALLOW_NESTED_DOMAIN 1)
endif()

if (NOT BUILD_SHARED_LIBS)
set(DDS_IS_STATIC_LIBRARY 1)
endif()

configure_file(include/dds/config.h.in include/dds/config.h)
configure_file(include/dds/features.h.in include/dds/features.h)
configure_file(include/dds/version.h.in include/dds/version.h)
Expand Down
6 changes: 3 additions & 3 deletions src/ddsrt/include/dds/ddsrt/countargs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

#define DDSRT_COUNT_ARGS_MSVC_WORKAROUND(x) x

/** @brief Returns the number of arguments provided (at most 10) */
#define DDSRT_COUNT_ARGS(...) DDSRT_COUNT_ARGS1 (__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1,0)
/** @brief Returns the number of arguments provided (at most 20) */
#define DDSRT_COUNT_ARGS(...) DDSRT_COUNT_ARGS1 (__VA_ARGS__, 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define DDSRT_COUNT_ARGS1(...) DDSRT_COUNT_ARGS_MSVC_WORKAROUND (DDSRT_COUNT_ARGS_ARGN (__VA_ARGS__))
#define DDSRT_COUNT_ARGS_ARGN(a,b,c,d,e,f,g,h,i,j,n,...) n
#define DDSRT_COUNT_ARGS_ARGN(a,b,c,d,e,f,g,h,i,j, k,l,m,n,o,p,q,r,s,t, N,...) N

#endif
21 changes: 21 additions & 0 deletions src/ddsrt/include/dds/ddsrt/dynlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ ddsrt_dlopen(
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;

dds_return_t
ddsrt_platform_dlopen(
const char *name,
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;

/**
* @brief Close the library.
*
Expand All @@ -86,6 +92,10 @@ dds_return_t
ddsrt_dlclose(
ddsrt_dynlib_t handle);

dds_return_t
ddsrt_platform_dlclose(
ddsrt_dynlib_t handle);

/**
* @brief Get the memory address of a symbol.
*
Expand All @@ -111,6 +121,12 @@ ddsrt_dlsym(
const char *symbol,
void **address);

dds_return_t
ddsrt_platform_dlsym(
ddsrt_dynlib_t handle,
const char *symbol,
void **address);

/**
* @brief Get the most recent library related error.
*
Expand Down Expand Up @@ -138,6 +154,11 @@ ddsrt_dlerror(
char *buf,
size_t buflen);

dds_return_t
ddsrt_platform_dlerror(
char *buf,
size_t buflen);

#if defined (__cplusplus)
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/ddsrt/include/dds/features.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@
/* Not for general use, specificly for testing psmx Cyclone DDS plugin */
#cmakedefine DDS_ALLOW_NESTED_DOMAIN 1

/* Not intended for general use, whether building a static library, specifically testing psmx and security */
#cmakedefine DDS_IS_STATIC_LIBRARY 1

#endif
Loading
Loading