Skip to content

Commit

Permalink
Add FORCE value to THRIDPARTY (eProsima#1375)
Browse files Browse the repository at this point in the history
* Refs #9178: Added THIRDPARTY_UPDATE CMake option for all thirdparty libraries.

Signed-off-by: RaulSanchez <[email protected]>

* Refs #9178: Separated THIRDPARTY_UPDATE and THIRDPARTY CMake options.

Signed-off-by: RaulSanchez <[email protected]>

* Refs #9178: Updated macro for finding thirdparty libraries.

Signed-off-by: RaulSanchez <[email protected]>

* Refs #9178: Refactor cmake eprosima_find_package and eprosima_find_thirdparty, and add THIRDPARTY_FORCE

Signed-off-by: EduPonz <[email protected]>

* Refs #9178: Contemplate all thirdparty options in FindTinyXML2.cmake

Signed-off-by: EduPonz <[email protected]>

* Refs #9178: Remove THIRDPARTY_FORCE and support for ON/OFF/FORCE to THIRDPARTY and THIRDPARTY_

Signed-off-by: EduPonz <[email protected]>

* Refs #9178: Correct doumentation typos

Signed-off-by: EduPonz <[email protected]>

* Refs #9178: Address suggestions

Signed-off-by: EduPonz <[email protected]>

Co-authored-by: RaulSanchez <[email protected]>
  • Loading branch information
EduPonz and rsanchez15 authored Sep 24, 2020
1 parent 9ba5f5e commit 724fa57
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 61 deletions.
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ eprosima_find_package(fastcdr REQUIRED)
eprosima_find_thirdparty(Asio asio)
eprosima_find_thirdparty(TinyXML2 tinyxml2)
find_package(foonathan_memory REQUIRED)
message(STATUS "Found foonathan_memory: ${foonathan_memory_DIR}")
find_package(ThirdpartyBoost REQUIRED)

if(ANDROID)
Expand Down Expand Up @@ -266,7 +267,7 @@ if(EPROSIMA_BUILD AND NOT EPROSIMA_INSTALLER)
endif()

###############################################################################
# Tools default setup
# Tools default setup
###############################################################################
option(COMPILE_TOOLS "Build tools" ON)

Expand Down Expand Up @@ -300,7 +301,7 @@ if(COMPILE_EXAMPLES)
endif()

###############################################################################
# Tools
# Tools
###############################################################################

if(COMPILE_TOOLS)
Expand Down Expand Up @@ -448,10 +449,10 @@ if(EPROSIMA_INSTALLER)
endif()

if(INSTALL_TOOLS)
# Install tools
# Install tools
install(DIRECTORY ${PROJECT_SOURCE_DIR}/tools
DESTINATION tools/
COMPONENT tools
COMPONENT tools
PATTERN "tools/CMakeLists.txt" EXCLUDE
)

Expand Down
248 changes: 197 additions & 51 deletions cmake/common/eprosima_libraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,88 +12,234 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Macro to find cmake built thirdparty libraries.
#
# Arguments:
# :package: The name of the packge to find. Used for find_package(${package})
# :extra arguments: Arguments passed after ${package} are parsed with cmake_parse_arguments()
#
# Related CMake options:
# :THIRDPARTY: Activate the use of internal thirdparties [Defaults: OFF]. Set to ON if EPROSIMA_BUILD is set to ON.
# Possible values:
# * ON -> Use submodules only if package is not found elsewhere in the system.
# * OFF -> Do not use submodules.
# * FORCE -> Force the use submodules regarless of what is installed in the system.
# :THIRDPARTY_${package}: Specialization of THIRDPARTY for a specific ${package}. Same possibilities as THIRDPARTY.
# Unless specified otherwise, it has the same value as THIRDPARTY. Its value has preference over that of
# THIRDPARTY.
# :THIRDPARTY_UPDATE: Activate the auto-update of internal thirdparties [Defaults: ON]. Possible values: ON/OFF.
#
# The macro's procedure is as follows:
# 1. Try to find the package with find_package.
# 1.1. This step is not taken if THIRDPARTY_${package} is set to FORCE. This happens when the user specifically
# sets THIRDPARTY_${package} to FORCE, or when THIRDPARTY is set to FORCE and THIRDPARTY_${package} is
# unspecified (which means it takes the value of THIRDPARTY).
# 1.2. This step is not taken for the case of windows installer. That is if EPROSIMA_INSTALLER is set to ON.
# 2. If the package is not found in 1), and at least one of THIRDPARTY, THIRDPARTY_${package} is set
# to ON or FORCE, use the thirdparty version.
# 2.1. If THIRDPARTY_UPDATE is set to ON, then update the corresponding git submodule.
# 2.2. Add the subdirectory /thirdparty/${package}.
# 2.3. Set ${package}_FOUND to TRUE.
# 3. If the package was not found anywhere, then print a WARNING or FATAL_ERROR message depending on whether the
# package was required.
macro(eprosima_find_package package)
# Parse arguments.
set(options REQUIRED)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(FIND "${options}" "" "${multiValueArgs}" ${ARGN})

# Define a list of allowed values for the options THIRDPARTY and THIRDPARTY_${package}
set(ALLOWED_VALUES ON OFF FORCE)

# Create the THIRDPARTY variable defaulting to OFF
set(THIRDPARTY OFF CACHE STRING "Activate use of internal submodules.")
# Define list of values GUI will offer for the variable
set_property(CACHE THIRDPARTY PROPERTY STRINGS ON OFF FORCE)
# Check that specified value is allowed
if(NOT THIRDPARTY IN_LIST ALLOWED_VALUES)
message(FATAL_ERROR, "Wrong configuration of THIRDPARTY. Allowed values: ${ALLOWED_VALUES}")
endif()

if(NOT ${package}_FOUND)
# Create the THIRDPARTY_${package} variable defaulting to ${THIRDPARTY}. This way, we only need to check the value
# of THIRDPARTY_${package} from here on.
set(THIRDPARTY_${package} ${THIRDPARTY} CACHE STRING "Activate use of internal submodule ${package}.")
# Define list of values GUI will offer for the variable
set_property(CACHE THIRDPARTY_${package} PROPERTY STRINGS ON OFF FORCE)
# Check that specified value is allowed
if(NOT THIRDPARTY_${package} IN_LIST ALLOWED_VALUES)
message(FATAL_ERROR, "Wrong configuration of THIRDPARTY_${package}. Allowed values: ${ALLOWED_VALUES}")
endif()

# Parse arguments.
set(options REQUIRED)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(FIND "${options}" "" "${multiValueArgs}" ${ARGN})
option(THIRDPARTY_UPDATE "Activate the auto update of internal thirdparties" ON)

option(THIRDPARTY "Activate the use of internal thirdparties" OFF)
option(THIRDPARTY_UPDATE "Activate the auto update of internal thirdparties" ON)
# EPROSIMA_BUILD sets THIRDPARTY_${package} to ON if it was set to OFF
if(EPROSIMA_BUILD AND (THIRDPARTY_${package} STREQUAL "OFF"))
set(THIRDPARTY_${package} ON)
endif()

if(EPROSIMA_BUILD)
set(THIRDPARTY ON)
endif()
# 1. If THIRDPARTY_${package} is set to FORCE, don't try to find the library outside thirdparty.
# 2. For the case of Windows installer, we don't want to look for the package outside thirdparty. This way we
# use thirdparty, meaning we have more control over what is built.
if((NOT (THIRDPARTY_${package} STREQUAL "FORCE")) AND NOT EPROSIMA_INSTALLER)
# Try to quietly find the package outside thridparty first.
find_package(${package} QUIET)

option(THIRDPARTY_${package} "Activate the use of internal thirdparty ${package}" OFF)
# Show message if package is found here.
if(${package}_FOUND)
# Cannot state where the package is. Asio sets Asio_DIR to Asio_DIR-NOTFOUND even when found.
message(STATUS "Found ${package}")
endif()
endif()

if(NOT EPROSIMA_INSTALLER)
find_package(${package} QUIET)
# Use thirdparty if THIRDPARTY_${package} is set to FORCE, or if the package is not found elsewhere and
# THIRDPARTY_${package} is set to ON.
if((THIRDPARTY_${package} STREQUAL "FORCE") OR ((NOT ${package}_FOUND) AND (THIRDPARTY_${package} STREQUAL "ON")))
if(THIRDPARTY_UPDATE)
# Update submodule
message(STATUS "Updating submodule thirdparty/${package}")
execute_process(
COMMAND git submodule update --recursive --init "thirdparty/${package}"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE EXECUTE_RESULT
)
# A result different than 0 means that the submodule could not be updated.
if(NOT EXECUTE_RESULT EQUAL 0)
message(WARNING "Cannot configure Git submodule ${package}")
endif()
endif()

if(NOT ${package}_FOUND AND (THIRDPARTY OR THIRDPARTY_${package}))
# Check that the package is correctly initialized by looking for its CMakeLists.txt file.
set(SUBDIRECTORY_EXIST FALSE)
if(EXISTS "${PROJECT_SOURCE_DIR}/thirdparty/${package}/CMakeLists.txt")
set(SUBDIRECTORY_EXIST TRUE)
if(THIRDPARTY_UPDATE OR NOT EXISTS "${PROJECT_SOURCE_DIR}/thirdparty/${package}/CMakeLists.txt")
message(STATUS "${package} thirdparty is being updated...")
execute_process(
COMMAND git submodule update --recursive --init "thirdparty/${package}"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE EXECUTE_RESULT
)
if(NOT EXECUTE_RESULT EQUAL 0)
message(WARNING "Cannot configure Git submodule ${package}")
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/thirdparty/${package}/CMakeLists.txt")
set(SUBDIRECTORY_EXIST FALSE)
endif()
endif()
endif()
endif()

if(SUBDIRECTORY_EXIST)
foreach(opt_ ${FIND_OPTIONS})
set(${opt_} ON)
endforeach()
add_subdirectory(${PROJECT_SOURCE_DIR}/thirdparty/${package})
set(${package}_FOUND TRUE)
if(NOT IS_TOP_LEVEL)
set(${package}_FOUND TRUE PARENT_SCOPE)
endif()
# If the subdirectory exists, we can add it so it's built.
if(SUBDIRECTORY_EXIST)
foreach(opt_ ${FIND_OPTIONS})
set(${opt_} ON)
endforeach()
add_subdirectory(${PROJECT_SOURCE_DIR}/thirdparty/${package})
set(${package}_FOUND TRUE)
if(NOT IS_TOP_LEVEL)
set(${package}_FOUND TRUE PARENT_SCOPE)
endif()
message(STATUS "Found ${package}: ${PROJECT_SOURCE_DIR}/thirdparty/${package}")
endif()
endif()

if(${package}_FOUND)
message(STATUS "${package} library found...")
elseif(${FIND_REQUIRED})
message(FATAL_ERROR "${package} library not found...")
# If the package was found we have already shown a status message.
# if it was not found and it was required, throw an fatal error.
# if it was not found but it was not required, show a warning.
if(NOT ${package}_FOUND)
if(${FIND_REQUIRED})
message(FATAL_ERROR "${package} package NOT found")
else()
message(STATUS "${package} library not found...")
message(STATUS "${package} package NOT found")
endif()
endif()
endmacro()

# Macro to find all Fast DDS thirdparty libraries expect for Fast CDR (look at eprosima_find_package).
#
# Arguments:
# :package: The name of the packge to find. Used for find_package(${package})
# :thirdparty_name: The name of the package directory under thirdparty, i.e. thirdparty/${thirdparty_name}
#
# Related CMake options:
# :THIRDPARTY: Activate the use of internal thirdparties [Defaults: OFF]. Set to ON if EPROSIMA_BUILD is set to ON.
# Possible values:
# * ON -> Use submodules only if package is not found elsewhere in the system.
# * OFF -> Do not use submodules.
# * FORCE -> Force the use submodules regarless of what is installed in the system.
# :THIRDPARTY_${package}: Specialization of THIRDPARTY for a specific ${package}. Same possibilities as THIRDPARTY.
# Unless specified otherwise, it has the same value as THIRDPARTY. It's value has preference over that of
# THIRDPARTY.
# :THIRDPARTY_UPDATE: Activate the auto update of internal thirdparties [Defaults: ON]. Possible values: ON/OFF.
#
# The macro's procedure is as follows:
# 1. Try to find the package with find_package.
# 1.1. This step is not taken if THIRDPARTY_${package} is set to FORCE. This happens when the user specifically
# sets THIRDPARTY_${package} to FORCE, or when THIRDPARTY is set to FORCE and THIRDPARTY_${package} is
# unspecified (which means it takes the value of THIRDPARTY).
# 1.2. This step is not taken for the case of windows installer. That is if EPROSIMA_INSTALLER is set to ON and
# at least one of MSVC, MSVC_IDE is set to ON at the same time.
# 2. If the package is not found in 1), and at least one of THIRDPARTY, THIRDPARTY_${package} is set
# to ON or FORCE, use the thirdparty version.
# 2.1. If THIRDPARTY_UPDATE is set to ON, then update the corresponding git submodule.
# 2.2. Append the thirdparty source directory to CMAKE_PREFIX_PATH.
# 2.3. Try to find the package again.
# 3. If the package was not found anywhere, then print an FATAL_ERROR message.
macro(eprosima_find_thirdparty package thirdparty_name)
if(NOT (EPROSIMA_INSTALLER AND (MSVC OR MSVC_IDE)))
# Define a list of allowed values for the options THIRDPARTY and THIRDPARTY_${package}
set(ALLOWED_VALUES ON OFF FORCE)

# Create the THIRDPARTY variable defaulting to OFF
set(THIRDPARTY OFF CACHE STRING "Activate use of internal submodules.")
# Define list of values GUI will offer for the variable
set_property(CACHE THIRDPARTY PROPERTY STRINGS ON OFF FORCE)
# Check that specified value is allowed
if(NOT THIRDPARTY IN_LIST ALLOWED_VALUES)
message(FATAL_ERROR, "Wrong configuration of THIRDPARTY. Allowed values: ${ALLOWED_VALUES}")
endif()

# Create the THIRDPARTY_${package} variable defaulting to ${THIRDPARTY}. This way, we only need to check the value
# of THIRDPARTY_${package} from here on.
set(THIRDPARTY_${package} ${THIRDPARTY} CACHE STRING "Activate use of internal submodule ${package}.")
# Define list of values GUI will offer for the variable
set_property(CACHE THIRDPARTY_${package} PROPERTY STRINGS ON OFF FORCE)
# Check that specified value is allowed
if(NOT THIRDPARTY_${package} IN_LIST ALLOWED_VALUES)
message(FATAL_ERROR, "Wrong configuration of THIRDPARTY_${package}. Allowed values: ${ALLOWED_VALUES}")
endif()

option(THIRDPARTY_UPDATE "Activate the auto update of internal thirdparties" ON)

option(THIRDPARTY_${package} "Activate the use of internal thirdparty ${package}" OFF)
# EPROSIMA_BUILD sets THIRDPARTY_${package} to ON if it was set to OFF
if(EPROSIMA_BUILD AND (THIRDPARTY_${package} STREQUAL "OFF"))
set(THIRDPARTY_${package} ON)
endif()

# 1. If THIRDPARTY_${package} is set to FORCE, don't try to find the library outside thirdparty.
# 2. For the case of Windows installer, we don't want to look for the package outside thirdparty. This way we
# use thirdparty, meaning we have more control over what is built.
if((NOT (THIRDPARTY_${package} STREQUAL "FORCE")) AND (NOT (EPROSIMA_INSTALLER AND (MSVC OR MSVC_IDE))))
# Try to quietly find the package outside thridparty first.
find_package(${package} QUIET)

if(THIRDPARTY OR THIRDPARTY_${package})
# Show message if package is found here.
if(${package}_FOUND)
# Cannot state where the package is. Asio sets Asio_DIR to Asio_DIR-NOTFOUND even when found.
message(STATUS "Found ${package}")
endif()
endif()

# Use thirdparty if THIRDPARTY_${package} is set to FORCE, or if the package is not found elsewhere and
# THIRDPARTY_${package} is set to ON.
if((THIRDPARTY_${package} STREQUAL "FORCE") OR ((NOT ${package}_FOUND) AND (THIRDPARTY_${package} STREQUAL "ON")))
if(THIRDPARTY_UPDATE)
# Update submodule
message(STATUS "Updating submodule thirdparty/${thirdparty_name}")
execute_process(
COMMAND git submodule update --recursive --init "thirdparty/${thirdparty_name}"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE EXECUTE_RESULT
)

if(EXECUTE_RESULT EQUAL 0)
else()
# A result different than 0 means that the submodule could not be updated.
if(NOT EXECUTE_RESULT EQUAL 0)
message(FATAL_ERROR "Cannot configure Git submodule ${package}")
endif()
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name})
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}/${thirdparty_name})
endif()

find_package(${package} REQUIRED QUIET)
# Prepend CMAKE_PREFIX_PATH with the package thirdparty directory. The second path is needed for asio, since the
# directory is "thirdparty/asio/asio"
set(CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name} ${CMAKE_PREFIX_PATH})
set(CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}/${thirdparty_name} ${CMAKE_PREFIX_PATH})
find_package(${package} REQUIRED)
endif()

# If the package was not found throw an error.
if(NOT ${package}_FOUND)
message(FATAL_ERROR "Cannot find package ${package}")
endif()
endmacro()
18 changes: 12 additions & 6 deletions cmake/modules/FindTinyXML2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@

option(TINYXML2_FROM_SOURCE "Integrate TinyXML2 source code inside Fast RTPS" OFF)

if(NOT (TINYXML2_FROM_SOURCE OR THIRDPARTY))
# Option for evaluating whether we are looking in for tinyxml2 in submodule
set(TINYXML2_FROM_THIRDPARTY OFF)
if (
(THIRDPARTY_TinyXML2 STREQUAL "ON") OR
(THIRDPARTY_TinyXML2 STREQUAL "FORCE")
)
set(TINYXML2_FROM_THIRDPARTY ON)
endif()

if(NOT (TINYXML2_FROM_SOURCE OR TINYXML2_FROM_THIRDPARTY))
find_package(TinyXML2 CONFIG QUIET)
endif()

if(TinyXML2_FOUND AND NOT THIRDPARTY)
if(TinyXML2_FOUND AND NOT TINYXML2_FROM_THIRDPARTY)
message(STATUS "Found TinyXML2: ${TinyXML2_DIR}")
if(NOT TINYXML2_LIBRARY)
# in this case, we're probably using TinyXML2 version 5.0.0 or greater
Expand All @@ -20,11 +29,8 @@ if(TinyXML2_FOUND AND NOT THIRDPARTY)
endif()
endif()
else()
if(THIRDPARTY OR ANDROID)
if(TINYXML2_FROM_THIRDPARTY OR ANDROID)
set(TINYXML2_FROM_SOURCE ON)
endif()

if(THIRDPARTY OR ANDROID)
find_path(TINYXML2_INCLUDE_DIR NAMES tinyxml2.h NO_CMAKE_FIND_ROOT_PATH)
else()
find_path(TINYXML2_INCLUDE_DIR NAMES tinyxml2.h)
Expand Down

0 comments on commit 724fa57

Please sign in to comment.