From 9c367b50bc6304697ad597ec3cc71a0a5693df4a Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Mon, 1 Feb 2021 15:20:20 +0000 Subject: [PATCH] pkg-config, PIE, API breakages fixes (#23) * Update protolib to pick up new fixes * CMake: restore SONAME_VERSION to 1 * CMake: generate pkg-config file * CMake: set -fvisibility=hidden and POSITION_INDEPENDENT_CODE Need to build everything with fPIC, and also hide symbols by default, since public ones are explicitly marked as such. * Revert public API incompatible changes NormSetId and NormCountCompletedObjects were part of the public API in released versions, so they cannot be just removed without breaking API/ABI compatibility. NormSendCommandTo is a private symbol, but was marked for export by mistake. * Add BUILD_STATIC_LIBS option to allow building both static and shared objects CMake does not support this out of the box, so it has to be implemented manually. It results in the libnorm build being repeated twice, as there's no object sharing. --- CMakeLists.txt | 34 +++++++++++++++++++++++++++++++--- include/normApi.h | 6 +++--- norm.pc.in | 3 ++- protolib | 2 +- src/common/normApi.cpp | 7 +------ 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index deebaab..ad707a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,10 @@ cmake_policy(SET CMP0077 NEW) # set the project name project(norm VERSION 1.5.8) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(COMMON src/common) option(NORM_BUILD_EXAMPLES "Enables building of the examples in /examples." OFF) @@ -121,12 +125,26 @@ target_compile_options(norm PUBLIC ${PLATFORM_FLAGS}) target_include_directories(norm PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(norm PUBLIC $ $) -if(BUILD_SHARED_LIBS AND WIN32) - target_compile_definitions(norm PUBLIC NORM_USE_DLL) +if(BUILD_SHARED_LIBS) + set_target_properties(norm PROPERTIES SOVERSION 1) + if(WIN32) + target_compile_definitions(norm PUBLIC NORM_USE_DLL) + endif() +endif() + +if(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS) + add_library(norm-static STATIC ${PLATFORM_SOURCE_FILES} ${COMMON_SOURCE_FILES} ${PUBLIC_HEADER_FILES}) + target_link_libraries(norm-static PRIVATE protokit::protokit) + target_compile_definitions(norm-static PUBLIC ${PLATFORM_DEFINITIONS}) + target_compile_options(norm-static PUBLIC ${PLATFORM_FLAGS}) + target_include_directories(norm-static PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(norm-static PUBLIC $ $) + set_target_properties(norm-static PROPERTIES OUTPUT_NAME "norm" PREFIX "lib") + set(NORM_STATIC "norm-static") endif() # Install target -install( TARGETS norm protokit EXPORT normTargets +install( TARGETS norm ${NORM_STATIC} protokit EXPORT normTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -142,6 +160,16 @@ install( EXPORT normTargets install(FILES include/normApi.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +# Create pkg-config file norm.pc +# TODO: once waf is removed, norm.pc.in can be edited to use the variables CMake sets directly, and +# remove these re-definitions +set(VERSION ${PROJECT_VERSION}) +set(PREFIX ${CMAKE_INSTALL_PREFIX}) +set(LIBDIR ${CMAKE_INSTALL_LIBDIR}) +set(STATIC_LIBS "libprotokit.a") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/norm.pc.in ${CMAKE_CURRENT_BINARY_DIR}/norm.pc @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/norm.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + # Create a ConfigVersion.cmake file include(CMakePackageConfigHelpers) write_basic_package_version_file( diff --git a/include/normApi.h b/include/normApi.h index 281f80e..1279a8e 100644 --- a/include/normApi.h +++ b/include/normApi.h @@ -338,9 +338,9 @@ bool NormPresetObjectInfo(NormSessionHandle sessionHandle, // FEC O UINT16 segmentSize, UINT16 numData, UINT16 numParity); -// non-public on purpose -//NORM_API_LINKAGE -//void NormSetId(NormSessionHandle sessionHandle, NormNodeId normId); + +NORM_API_LINKAGE +void NormSetId(NormSessionHandle sessionHandle, NormNodeId normId); // This does not affect the rx_socket binding if already bound (sender or receiver already started) // (i.e., just affects where NORM packets are sent) diff --git a/norm.pc.in b/norm.pc.in index d824ab6..4f07d89 100644 --- a/norm.pc.in +++ b/norm.pc.in @@ -1,6 +1,6 @@ prefix=@PREFIX@ exec_prefix=${prefix} -libdir=@LIBDIR@ +libdir=${prefix}/@LIBDIR@ includedir=${prefix}/include Name: norm @@ -8,4 +8,5 @@ Version: @VERSION@ Description: NACK-Oriented Reliable Multicast (NORM) library Libs: -L${libdir} -lnorm Libs.private: @STATIC_LIBS@ +Requires.private: @REQUIRES_PRIVATE@ Cflags: -I${includedir} diff --git a/protolib b/protolib index 702e909..6609240 160000 --- a/protolib +++ b/protolib @@ -1 +1 @@ -Subproject commit 702e909945446275f0313846e988612883fca94a +Subproject commit 66092403ffeda703ad5e563be068db345f111a3c diff --git a/src/common/normApi.cpp b/src/common/normApi.cpp index a1a592d..ef172b7 100644 --- a/src/common/normApi.cpp +++ b/src/common/normApi.cpp @@ -739,8 +739,7 @@ void NormInstance::Shutdown() notify_pool.Destroy(); } // end NormInstance::Shutdown() -/* -This function doesn't make sense? +// This function doesn't make sense? UINT32 NormInstance::CountCompletedObjects(NormSession* session) { UINT32 result = 0UL; @@ -756,7 +755,6 @@ UINT32 NormInstance::CountCompletedObjects(NormSession* session) } return result; } // end NormInstance::CountCompletedObjects() -*/ ////////////////////////////////////////////////////////////////////////// // NORM API FUNCTION IMPLEMENTATIONS @@ -2313,7 +2311,6 @@ void NormCancelCommand(NormSessionHandle sessionHandle) // This one is not part of the public API (for NormSocket use currently) -NORM_API_LINKAGE bool NormSendCommandTo(NormSessionHandle sessionHandle, const char* cmdBuffer, unsigned int cmdLength, @@ -3064,7 +3061,6 @@ void NormNodeRelease(NormNodeHandle nodeHandle) // is done so that this current approach is not very costly) // -/* // Not sure why this function exists. It just counts the number // of RX_OBJECT_COMPLETED events currently in notification queue // which is a temporary and transitory thing??? @@ -3081,4 +3077,3 @@ UINT32 NormCountCompletedObjects(NormSessionHandle sessionHandle) } return result; } // end NormCountCompletedObjects() -*/