Skip to content

Commit

Permalink
Fixing static linking when SECURITY=OFF but SSL is needed (eProsima#1971
Browse files Browse the repository at this point in the history
)

* [11561] Fixing static linking when SECURITY=OFF but SSL is needed

* Assure redistributables to be quiet on quiet installations

* [11561] Updating CMake script to select the right OpenSSL source.

* [11561] Solving well known OpenSSL Windows dependency issue on static linking

* [11561] Adding OpenSSL assembly dependency to avoid dll hell

* [11561] Introducing a manifest template to autoupdate version numbers

* [11561] fixing openssl version parsing if no tweak is given

* [11561] addressing reviewers comments
  • Loading branch information
MiguelBarro authored Jun 4, 2021
1 parent 65f2c66 commit e80820c
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 33 deletions.
9 changes: 6 additions & 3 deletions cmake/packaging/Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@")
find_package(fastcdr REQUIRED)
find_package(foonathan_memory REQUIRED)
find_package(TinyXML2 QUIET)
@FASTRTPS_PACKAGE_OPT_DEPS@
@FASTRTPS_INSTALLER_DEPS_ANCILLARY@
@FASTRTPS_PACKAGE_UNIX_OPT_DEPS@

if(FASTDDS_STATIC)
# OpenSSL static libraries are not distributed with the installer
@FASTRTPS_PACKAGE_OPT_DEPS@
@FASTRTPS_INSTALLER_OPT_DEPS@
@FASTRTPS_PACKAGE_WIN32_OPT_DEPS@
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-static-targets.cmake)
else()
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-dynamic-targets.cmake OPTIONAL RESULT_VARIABLE DYNAMIC_TARGET_FILE)
# fallback to static linking if dynamic target is missing
if( NOT DYNAMIC_TARGET_FILE )
@FASTRTPS_INSTALLER_OPT_DEPS@
@FASTRTPS_PACKAGE_WIN32_OPT_DEPS@
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-static-targets.cmake)
endif()
endif()
Expand Down
58 changes: 32 additions & 26 deletions cmake/packaging/windows/InstallRedistributables.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -14,68 +14,74 @@

!include x64.nsh

Var X64VS2017Needed
Var I86VS2017Needed
Var X64VS2019Needed
Var I86VS2019Needed

Function InstallRedistributables

StrCpy $X64VS2017Needed "1"
StrCpy $I86VS2017Needed "1"
StrCpy $X64VS2019Needed "1"
StrCpy $I86VS2019Needed "1"

${If} ${RunningX64}
SetRegView 64
${EndIf}

# Check if it is necessary to install to x64VS2017
# Check if it is necessary to install to x64VS2019
${If} ${RunningX64}
${If} ${SectionIsSelected} ${libraries_x64Win64VS2017}
${If} ${SectionIsSelected} ${libraries_x64Win64VS2019}
${OrIf} ${SectionIsSelected} ${libraries_x64Win64VS2015}
ClearErrors
ReadRegStr $0 HKLM "SOFTWARE\Classes\Installer\Dependencies\Microsoft.VS.VC_RuntimeMinimumVSU_amd64,v14" "Version"
IfErrors 0 VC2017x64RedistInstalled
StrCpy $X64VS2017Needed "0"
IfErrors 0 VC2019x64RedistInstalled
StrCpy $X64VS2019Needed "0"
${EndIf}
${EndIf}

VC2017x64RedistInstalled:
VC2019x64RedistInstalled:

# Check if it is necessary to install to i86VS2017
${If} ${SectionIsSelected} ${libraries_i86Win32VS2017}
# Check if it is necessary to install to i86VS2019
${If} ${SectionIsSelected} ${libraries_i86Win32VS2019}
${OrIf} ${SectionIsSelected} ${libraries_i86Win32VS2015}
ClearErrors
ReadRegStr $0 HKLM "SOFTWARE\Classes\Installer\Dependencies\Microsoft.VS.VC_RuntimeMinimumVSU_x86,v14" "Version"
IfErrors 0 VC2017i86RedistInstalled
StrCpy $I86VS2017Needed "0"
IfErrors 0 VC2019i86RedistInstalled
StrCpy $I86VS2019Needed "0"
${EndIf}

VC2017i86RedistInstalled:
VC2019i86RedistInstalled:

StrCmp $X64VS2017Needed "1" notinstall2017x64 install2017x64
StrCmp $X64VS2019Needed "1" notinstall2019x64 install2019x64

install2017x64:
messageBox MB_YESNO|MB_ICONQUESTION "$(^Name) needs Visual Studio 2017 x64 Redistributable packages.$\nDo you want to download and install them?" IDNO notinstall2017x64
install2019x64:
messageBox MB_YESNO|MB_ICONQUESTION "$(^Name) needs Visual Studio 2019 x64 Redistributable packages.$\nDo you want to download and install them?" IDNO notinstall2019x64

NSISdl::download https://aka.ms/vs/15/release/VC_redist.x64.exe $TEMP\VC_redist.x64.exe
Pop $R0 ; Get the return value
StrCmp $R0 "success" 0 +3
ExecWait "$TEMP\VC_redist.x64.exe"
StrCmp $R0 "success" 0 +6
IfSilent +1 +3
ExecWait '"$TEMP\VC_redist.x64.exe" /install /quiet'
Goto notinstall2019x64
ExecWait "$TEMP\VC_redist.x64.exe"
Goto +2
MessageBox MB_OK "VC_redist.x64.exe download failed: $R0"

notinstall2017x64:
notinstall2019x64:

StrCmp $I86VS2017Needed "1" notinstall2017i86 install2017i86
StrCmp $I86VS2019Needed "1" notinstall2019i86 install2019i86

install2017i86:
messageBox MB_YESNO|MB_ICONQUESTION "$(^Name) needs Visual Studio 2017 Win32 Redistributable packages.$\nDo you want to download and install them?" IDNO notinstall2017i86
install2019i86:
messageBox MB_YESNO|MB_ICONQUESTION "$(^Name) needs Visual Studio 2019 Win32 Redistributable packages.$\nDo you want to download and install them?" IDNO notinstall2019i86

NSISdl::download https://aka.ms/vs/15/release/VC_redist.x86.exe $TEMP\VC_redist.x86.exe
Pop $R0 ; Get the return value
StrCmp $R0 "success" 0 +3
ExecWait "$TEMP\VC_redist.x86.exe"
StrCmp $R0 "success" 0 +6
IfSilent +1 +3
ExecWait '"$TEMP\VC_redist.x86.exe" /install /quiet'
Goto notinstall2019i86
ExecWait "$TEMP\VC_redist.x86.exe"
Goto +2
MessageBox MB_OK "VC_redist.x86.exe download failed: $R0"

notinstall2017i86:
notinstall2019i86:

FunctionEnd
18 changes: 18 additions & 0 deletions cmake/packaging/windows/fastrtps.manifest.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
name="Fast-DDS"
type="win32"
version="@FASTDDS_CANONICAL_VERSION@"
/>
<description>eProsima Fast DDS is the most complete open source dds middleware for real time embedded architectures and operating systems.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
name="OpenSSL.Fast-DDS"
type="win32"
version="@OPENSSL_CANONICAL_VERSION@"
/>
</dependentAssembly>
</dependency>
</assembly>
1 change: 0 additions & 1 deletion fastrtps.repos
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ repositories:
type: git
url: https://github.com/eProsima/IDL-Parser.git
version: master

69 changes: 66 additions & 3 deletions src/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ if((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER AND IS_TOP_LEVEL)
generate_msvc_libraries(i86Win32VS2017)
generate_msvc_libraries(x64Win64VS2017)
elseif(NOT EPROSIMA_INSTALLER)

#Create library
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_source_files})
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
Expand Down Expand Up @@ -456,13 +457,55 @@ elseif(NOT EPROSIMA_INSTALLER)
target_link_libraries(${PROJECT_NAME} ${PRIVACY} fastcdr foonathan_memory
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}
${TINYXML2_LIBRARY}
$<$<BOOL:${LINK_SSL}>:OpenSSL::SSL$<SEMICOLON>OpenSSL::Crypto>
$<$<BOOL:${LINK_SSL}>:OpenSSL::SSL$<SEMICOLON>OpenSSL::Crypto$<$<BOOL:${WIN32}>:$<SEMICOLON>crypt32.lib>>
$<$<BOOL:${WIN32}>:iphlpapi$<SEMICOLON>Shlwapi>
${THIRDPARTY_BOOST_LINK_LIBS}
PRIVATE eProsima_atomic
)

if(MSVC OR MSVC_IDE)

# On installed binaries use manifest to specify dependencies
if(INSTALLER_PLATFORM AND OPENSSL_FOUND)

# Get Fast-DDS version suitable manifest format
set(FASTDDS_CANONICAL_VERSION ${fastrtps_VERSION})

if( NOT FASTDDS_CANONICAL_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$")
message(FATAL_ERROR "Fast-DDS version number ${fastrtps_VERSION} must include major, minor and patch.")
endif()

if( NOT fastrtps_VERSION_TWEAK)
set(FASTDDS_CANONICAL_VERSION "${FASTDDS_CANONICAL_VERSION}.0")
endif()

# Get OpenSSL version suitable manifest format
execute_process( COMMAND PowerShell -NoLogo -Command "&{ param([string]$original)
if ($original -notmatch '\\d+$')
{ $res = $original.Substring(0,$original.length-1) + '.' +
([int]$original[$original.length-1]-[int][char]'a'+1); }
else { while(($original -split '\\.').count -le 3)
{ $original += '.0'; } $res = $original; } $res }" -original ${OPENSSL_VERSION}
OUTPUT_VARIABLE OPENSSL_CANONICAL_VERSION
)
string(STRIP ${OPENSSL_CANONICAL_VERSION} OPENSSL_CANONICAL_VERSION)

# replace the values in the manifest template
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/packaging/windows/fastrtps.manifest.in"
"${CMAKE_CURRENT_BINARY_DIR}/fastrtps.manifest"
@ONLY
)

file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/fastrtps.manifest" MANIFEST_FILE_PATH)
target_link_options(${PROJECT_NAME} PRIVATE "/MANIFEST:EMBED" "/MANIFESTINPUT:${MANIFEST_FILE_PATH}")

unset(WINDOWS_SOURCE_DIR)
unset(FASTDDS_CANONICAL_VERSION)
unset(OPENSSL_CANONICAL_VERSION)
unset(MANIFEST_FILE_PATH)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES RELEASE_POSTFIX -${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
set_target_properties(${PROJECT_NAME} PROPERTIES RELWITHDEBINFO_POSTFIX -${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX d-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
Expand Down Expand Up @@ -678,8 +721,28 @@ elseif(NOT EPROSIMA_INSTALLER)
endif()

# Add fastrtps dependencies in its CMake config file.
if(LINK_SSL AND NOT INSTALLER_PLATFORM)
set(FASTRTPS_PACKAGE_OPT_DEPS "find_package(OpenSSL REQUIRED)")
if(LINK_SSL)
if(INSTALLER_PLATFORM)
# OpenSSL dependency is only propagated on static linking
# We must use the deployed OpenSSL binaries to prevent compatibility issues
set(FASTRTPS_INSTALLER_DEPS_ANCILLARY "\
function(find_fastdds_deployed_openssl)\n\
if(OPENSSL_FOUND AND NOT(OPENSSL_VERSION STREQUAL \"${OPENSSL_VERSION}\") )\n\
message(WARNING \"OpenSSL already loaded. Version \${OPENSSL_VERSION} differs from version ${OPENSSL_VERSION}, used in Fast-DDS binaries building, ABI issues may arise\")\n\
endif()\n\
set(OPENSSL_USE_STATIC_LIBS TRUE)\n\
set(OPENSSL_ROOT_DIR \"\${PACKAGE_PREFIX_DIR}/lib/${INSTALLER_PLATFORM}\")\n\
find_package(OpenSSL REQUIRED)\n\
endfunction()"
)
set(FASTRTPS_INSTALLER_OPT_DEPS "find_fastdds_deployed_openssl()")
elseif(WIN32)
# windows from sources only requires OpenSSL on static libraries
set(FASTRTPS_PACKAGE_WIN32_OPT_DEPS "find_package(OpenSSL REQUIRED)")
else()
# linux from sources requires OpenSSL always
set(FASTRTPS_PACKAGE_UNIX_OPT_DEPS "find_package(OpenSSL REQUIRED)")
endif()
endif()

configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/packaging/Config.cmake.in
Expand Down

0 comments on commit e80820c

Please sign in to comment.