Skip to content

Commit c0f989a

Browse files
authored
[Config] Add new macro for fetching dependencies (#5550)
* Introduce new macro for fetching external dependencies * Use macro in code base * remove unused macro * Fix CImg * Avoid fetching when CMake is disconnected * Add Local dir mechanism * WIP, use the macro for plugins * Finalize use of the macro for plugins
1 parent d67d1cd commit c0f989a

7 files changed

Lines changed: 125 additions & 121 deletions

File tree

Sofa/GUI/Common/CMakeLists.txt

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,14 @@ find_package(cxxopts 3.1 QUIET)
55
if(NOT cxxopts_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES)
66
message("Sofa.GUI.Common: DEPENDENCY cxxopts NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching cxxopts...")
77

8-
include(FetchContent)
9-
FetchContent_Declare(cxxopts
8+
set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "")
9+
set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "")
10+
set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "")
11+
12+
sofa_fetch_dependency(cxxopts
1013
GIT_REPOSITORY https://github.com/jarro2783/cxxopts
1114
GIT_TAG v3.1.1
1215
)
13-
14-
FetchContent_GetProperties(cxxopts)
15-
if(NOT cxxopts_POPULATED)
16-
FetchContent_Populate(cxxopts)
17-
18-
set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "")
19-
set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "")
20-
set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "")
21-
message("Sofa.GUI.Common: adding subdirectory ${cxxopts_SOURCE_DIR}")
22-
23-
add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR})
24-
endif()
2516
elseif (NOT cxxopts_FOUND)
2617
message(FATAL_ERROR "Sofa.GUI.Common: DEPENDENCY cxxopts NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install libcxxopts-dev (version>=3.1.0), or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.")
2718
endif()

Sofa/framework/Config/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,12 @@ endif()
241241
option(SOFA_TRACY "Compile SOFA with the Tracy profiler client" OFF)
242242
if (SOFA_TRACY)
243243
set(SOFA_TRACY_VERSION v0.11.1)
244-
include(FetchContent)
245244
option(TRACY_STATIC "Whether to build Tracy as a static library" OFF)
246-
FetchContent_Declare (
245+
sofa_fetch_dependency (
247246
tracy
248247
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
249248
GIT_TAG ${SOFA_TRACY_VERSION}
250-
GIT_SHALLOW TRUE
251-
GIT_PROGRESS TRUE
252249
)
253-
FetchContent_MakeAvailable (tracy)
254250
target_link_libraries(${PROJECT_NAME} PUBLIC TracyClient )
255251
message(STATUS "SOFA is compiled with the Tracy profiler client. Use the Tracy server ${SOFA_TRACY_VERSION}.")
256252
endif()

Sofa/framework/Config/cmake/SofaMacrosConfigure.cmake

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -173,68 +173,31 @@ macro(sofa_add_generic directory name type)
173173
endif()
174174
endmacro()
175175

176-
### Macro to help external projects management
177-
# It produces the correct naming for cmake flag generation and the actual name of the project
178-
macro(get_name_from_source_dir)
179-
get_filename_component(ProjectId ${CMAKE_CURRENT_LIST_DIR} NAME)
180-
string(REPLACE "\." "_" fixed_name ${ProjectId})
181-
string(TOUPPER ${fixed_name} fixed_name)
182-
183-
set(inner-project-name ${ProjectId})
184-
set(inner-project-name-upper ${fixed_name})
185-
endmacro()
186176

187-
### External projects management
188-
# Thanks to http://crascit.com/2015/07/25/cmake-gtest/
189-
#
190-
# Use this macro (subdirectory or plugin version) to add out-of-repository projects.
191-
# Usage:
192-
# 1. Add repository configuration in MyProjectDir/ExternalProjectConfig.cmake.in
193-
# 2. Call sofa_add_subdirectory_external(MyProjectDir MyProjectName [ON,OFF] [FETCH_ONLY])
194-
# or sofa_add_plugin_external(MyProjectDir MyProjectName [ON,OFF] [FETCH_ONLY])
195-
# ON,OFF = execute the fetch by default + enable the fetched plugin (if calling sofa_add_plugin_external)
196-
# FETCH_ONLY = do not "add_subdirectory" the fetched repository
197-
# See plugins/SofaHighOrder for example
198-
#
199-
function(sofa_add_generic_external name type)
200-
set(optionArgs FETCH_ONLY)
201-
set(oneValueArgs DEFAULT_VALUE WHEN_TO_SHOW VALUE_IF_HIDDEN GIT_REF GIT_REPOSITORY)
202-
set(multiValueArgs)
203-
cmake_parse_arguments("ARG" "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
177+
macro(sofa_fetch_dependency name)
204178

205-
string(TOLOWER ${type} type_lower)
179+
set(oneValueArgs GIT_TAG GIT_REPOSITORY FETCH_ENABLED )
180+
set(multiValueArgs "")
181+
set(options DONT_BUILD)
182+
cmake_parse_arguments("ARG" "${options}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
206183

207-
# Default value for fetch activation and for plugin activation (if adding a plugin)
208-
set(active OFF)
209-
if(${ARG_DEFAULT_VALUE})
210-
set(active ON)
211-
endif()
212-
213-
set(directory "${CMAKE_CURRENT_LIST_DIR}/${name}")
184+
# Setup fetch directory
185+
set(fetched_dir "${CMAKE_BINARY_DIR}/external_directories/fetched/${name}" )
186+
set(build_directory "${CMAKE_BINARY_DIR}/external_directories/fetched/${name}-build")
214187

215188
# Create option
216189
string(REPLACE "\." "_" fixed_name ${name})
217-
string(TOUPPER ${PROJECT_NAME}_FETCH_${fixed_name} fetch_enabled)
218190
string(TOUPPER ${fixed_name} upper_name)
219-
if(NOT "${ARG_WHEN_TO_SHOW}" STREQUAL "" AND NOT "${ARG_VALUE_IF_HIDDEN}" STREQUAL "")
220-
cmake_dependent_option(${fetch_enabled} "Fetch/update ${name} repository." ${active} "${ARG_WHEN_TO_SHOW}" ${ARG_VALUE_IF_HIDDEN})
221-
else()
222-
option(${fetch_enabled} "Fetch/update ${name} repository." ${active})
223-
endif()
224-
225-
# Setup fetch directory
226-
set(fetched_dir "${CMAKE_BINARY_DIR}/external_directories/fetched/${name}" )
227-
file(RELATIVE_PATH relative_path "${CMAKE_SOURCE_DIR}" "${directory}")
228-
191+
set(${upper_name}_GIT_REPOSITORY "${ARG_GIT_REPOSITORY}" CACHE STRING "Repository address" )
192+
set(${upper_name}_GIT_TAG "${ARG_GIT_TAG}" CACHE STRING "Branch or commit SHA to checkout" )
229193
set(${upper_name}_LOCAL_DIRECTORY "" CACHE STRING "Absolute path to a local folder containing the cloned repository")
230194

231-
# Fetch
232-
if(${fetch_enabled})
233-
set(${upper_name}_GIT_REPOSITORY "${ARG_GIT_REPOSITORY}" CACHE STRING "Repository address" )
234-
set(${upper_name}_GIT_TAG "${ARG_GIT_REF}" CACHE STRING "Branch or commit SHA to checkout" )
195+
set(${fixed_name}_SOURCE_DIR "${fetched_dir}" CACHE STRING "" FORCE )
235196

236-
message("${name}: Fetching ${type_lower} in ${fetched_dir}")
237-
message(STATUS "${name}: Checkout reference ${${upper_name}_GIT_TAG} from repository ${${upper_name}_GIT_REPOSITORY} ")
197+
if( "${${upper_name}_LOCAL_DIRECTORY}" STREQUAL "" AND NOT FETCHCONTENT_FULLY_DISCONNECTED AND NOT FETCHCONTENT_UPDATES_DISCONNECTED AND NOT "${ARG_FETCH_ENABLED}" STREQUAL "OFF")
198+
# Fetch
199+
message("Fetching dependency ${name} in ${fetched_dir}")
200+
message(STATUS "Checkout reference ${${upper_name}_GIT_TAG} from repository ${${upper_name}_GIT_REPOSITORY} ")
238201

239202
#Generate temporary folder to store project that will fetch the sources
240203
if(NOT EXISTS ${fetched_dir}-temp)
@@ -271,19 +234,85 @@ function(sofa_add_generic_external name type)
271234
file(APPEND "${fetched_dir}-temp/logs.txt" "${build_logs}")
272235

273236
if(NOT generate_exitcode EQUAL 0 OR NOT build_exitcode EQUAL 0)
274-
message(SEND_ERROR "Failed to fetch external repository ${name}." "\nSee logs in ${fetched_dir}/logs.txt")
237+
message(SEND_ERROR "Failed to fetch external repository ${name}." "\nSee logs in ${fetched_dir}-temp/logs.txt")
275238
endif()
276239
elseif (NOT ${upper_name}_LOCAL_DIRECTORY STREQUAL "")
277240
if(EXISTS ${${upper_name}_LOCAL_DIRECTORY})
278241
message("${name}: Using local directory ${${upper_name}_LOCAL_DIRECTORY}.")
279242
set(fetched_dir "${${upper_name}_LOCAL_DIRECTORY}")
280-
281243
else ()
282244
message(SEND_ERROR "${name}: Specified directory ${${upper_name}_LOCAL_DIRECTORY} doesn't exist." "\nPlease provide a directory containing the fetched project, or use option ${fetch_enabled} to automatically fetch it.")
283-
284245
endif ()
285246
endif()
286247

248+
249+
# Add
250+
if(NOT ARG_DONT_BUILD AND EXISTS "${fetched_dir}/.git" AND IS_DIRECTORY "${fetched_dir}/.git")
251+
set(${fixed_name}_BUILD_DIR "${build_directory}" CACHE STRING "" FORCE)
252+
add_subdirectory("${fetched_dir}" "${build_directory}")
253+
message(STATUS "Adding subproject ${name} from sources at ${${fixed_name}_SOURCE_DIR}")
254+
elseif(NOT ARG_DONT_BUILD AND NOT ${upper_name}_LOCAL_DIRECTORY STREQUAL "")
255+
message(SEND_ERROR "Directory ${${upper_name}_LOCAL_DIRECTORY} given in ${upper_name}_LOCAL_DIRECTORY doesn't seem to be a right github repository.")
256+
elseif (NOT ARG_DONT_BUILD AND FETCHCONTENT_FULLY_DISCONNECTED OR FETCHCONTENT_UPDATES_DISCONNECTED)
257+
message(SEND_ERROR "FETCHCONTENT_FULLY_DISCONNECTED or FETCHCONTENT_UPDATES_DISCONNECTED is ON but the dependency hasn't been fetched correctly before. Please reconnect fetching mechanism or provide a local directory by setting ${upper_name}_LOCAL_DIRECTORY.")
258+
endif()
259+
endmacro()
260+
261+
262+
263+
### External projects management
264+
# Thanks to http://crascit.com/2015/07/25/cmake-gtest/
265+
#
266+
# Use this macro (subdirectory or plugin version) to add out-of-repository projects.
267+
# Usage:
268+
# 1. Add repository configuration in MyProjectDir/ExternalProjectConfig.cmake.in
269+
# 2. Call sofa_add_subdirectory_external(MyProjectDir MyProjectName [ON,OFF] [FETCH_ONLY])
270+
# or sofa_add_plugin_external(MyProjectDir MyProjectName [ON,OFF] [FETCH_ONLY])
271+
# ON,OFF = execute the fetch by default + enable the fetched plugin (if calling sofa_add_plugin_external)
272+
# FETCH_ONLY = do not "add_subdirectory" the fetched repository
273+
# See plugins/SofaHighOrder for example
274+
#
275+
function(sofa_add_generic_external name type)
276+
set(optionArgs FETCH_ONLY)
277+
set(oneValueArgs DEFAULT_VALUE WHEN_TO_SHOW VALUE_IF_HIDDEN GIT_REF GIT_REPOSITORY)
278+
set(multiValueArgs)
279+
cmake_parse_arguments("ARG" "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
280+
281+
string(TOLOWER ${type} type_lower)
282+
283+
# Default value for fetch activation and for plugin activation (if adding a plugin)
284+
set(active OFF)
285+
if(${ARG_DEFAULT_VALUE})
286+
set(active ON)
287+
endif()
288+
289+
# Create option
290+
string(REPLACE "\." "_" fixed_name ${name})
291+
string(TOUPPER ${fixed_name} upper_name)
292+
string(TOUPPER ${PROJECT_NAME}_FETCH_${fixed_name} fetch_enabled)
293+
294+
if(NOT "${ARG_WHEN_TO_SHOW}" STREQUAL "" AND NOT "${ARG_VALUE_IF_HIDDEN}" STREQUAL "")
295+
cmake_dependent_option(${fetch_enabled} "Fetch/update ${name} repository." ${active} "${ARG_WHEN_TO_SHOW}" ${ARG_VALUE_IF_HIDDEN})
296+
else()
297+
option(${fetch_enabled} "Fetch/update ${name} repository." ${active})
298+
endif()
299+
300+
sofa_fetch_dependency("${name}"
301+
GIT_TAG "${ARG_GIT_REF}"
302+
GIT_REPOSITORY "${ARG_GIT_REPOSITORY}"
303+
FETCH_ENABLED "${${fetch_enabled}}"
304+
DONT_BUILD
305+
)
306+
307+
# Setup fetch directory
308+
if(NOT "${${upper_name}_LOCAL_DIRECTORY}" STREQUAL "")
309+
set(fetched_dir "${${upper_name}_LOCAL_DIRECTORY}" )
310+
else ()
311+
set(fetched_dir "${CMAKE_BINARY_DIR}/external_directories/fetched/${name}" )
312+
endif ()
313+
set(directory "${CMAKE_CURRENT_LIST_DIR}/${name}")
314+
file(RELATIVE_PATH relative_path "${CMAKE_SOURCE_DIR}" "${directory}")
315+
287316
# Add
288317
if(EXISTS "${fetched_dir}/.git" AND IS_DIRECTORY "${fetched_dir}/.git")
289318
if(NOT ARG_FETCH_ONLY AND "${type}" MATCHES ".*directory.*")

Sofa/framework/Config/cmake/SofaMacrosUtils.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ function(sofa_get_all_targets var)
5151
__get_all_targets_recursive(targets ${source_dir})
5252
set(${var} ${targets} PARENT_SCOPE)
5353
endfunction()
54+

Sofa/framework/Testing/CMakeLists.txt

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,37 @@ find_package(GTest QUIET)
1010
if(NOT GTest_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES)
1111
message("${PROJECT_NAME}: DEPENDENCY googletest NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching googletest...")
1212

13-
include(FetchContent)
14-
FetchContent_Declare(googletest
13+
set(BUILD_GMOCK OFF CACHE INTERNAL "")
14+
set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
15+
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) # rely on SOFA macros
16+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
17+
set(gtest_disable_pthreads OFF CACHE BOOL "" FORCE)
18+
19+
message("${PROJECT_NAME}: adding subdirectory ${googletest_SOURCE_DIR}")
20+
21+
sofa_fetch_dependency(googletest
1522
GIT_REPOSITORY https://github.com/google/googletest
1623
GIT_TAG v1.14.0
1724
)
1825

19-
FetchContent_GetProperties(googletest)
20-
if(NOT googletest_POPULATED)
21-
FetchContent_Populate(googletest)
22-
23-
set(BUILD_GMOCK OFF CACHE INTERNAL "")
24-
set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
25-
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) # rely on SOFA macros
26-
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
27-
set(gtest_disable_pthreads OFF CACHE BOOL "" FORCE)
28-
29-
message("${PROJECT_NAME}: adding subdirectory ${googletest_SOURCE_DIR}")
30-
31-
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
32-
33-
target_compile_options(gtest_main PRIVATE "-DGTEST_LINKED_AS_SHARED_LIBRARY=0")
34-
target_compile_options(gtest PRIVATE "-DGTEST_CREATE_SHARED_LIBRARY=1")
35-
36-
install(DIRECTORY ${googletest_SOURCE_DIR}/googletest/include/gtest DESTINATION include/extlibs/GTest/ COMPONENT headers)
37-
target_include_directories(gtest PUBLIC "$<INSTALL_INTERFACE:include/extlibs/GTest/>")
38-
39-
include(SofaMacros)
40-
sofa_create_package_with_targets(
41-
PACKAGE_NAME GTest
42-
PACKAGE_VERSION 1.14.0
43-
TARGETS gtest AUTO_SET_TARGET_PROPERTIES
44-
INCLUDE_SOURCE_DIR "include"
45-
INCLUDE_INSTALL_DIR "extlibs/GTest"
46-
)
47-
48-
set_target_properties(gtest PROPERTIES FOLDER Testing)
49-
set_target_properties(gtest_main PROPERTIES FOLDER Testing)
50-
endif()
26+
target_compile_options(gtest_main PRIVATE "-DGTEST_LINKED_AS_SHARED_LIBRARY=0")
27+
target_compile_options(gtest PRIVATE "-DGTEST_CREATE_SHARED_LIBRARY=1")
28+
29+
install(DIRECTORY ${googletest_SOURCE_DIR}/googletest/include/gtest DESTINATION include/extlibs/GTest/ COMPONENT headers)
30+
target_include_directories(gtest PUBLIC "$<INSTALL_INTERFACE:include/extlibs/GTest/>")
31+
32+
include(SofaMacros)
33+
sofa_create_package_with_targets(
34+
PACKAGE_NAME GTest
35+
PACKAGE_VERSION 1.14.0
36+
TARGETS gtest AUTO_SET_TARGET_PROPERTIES
37+
INCLUDE_SOURCE_DIR "include"
38+
INCLUDE_INSTALL_DIR "extlibs/GTest"
39+
)
40+
41+
set_target_properties(gtest PROPERTIES FOLDER Testing)
42+
set_target_properties(gtest_main PROPERTIES FOLDER Testing)
43+
5144
elseif (NOT GTest_FOUND)
5245
message(FATAL_ERROR "${PROJECT_NAME}: DEPENDENCY googletest NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install googletest, or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.")
5346
endif()

applications/plugins/CImgPlugin/CMakeLists.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,14 @@ sofa_find_package(CImg QUIET)
2525
if(NOT CImg_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES)
2626
message("CImgPlugin: DEPENDENCY CImg NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching CImg...")
2727

28-
include(FetchContent)
29-
FetchContent_Declare(CImg
28+
sofa_fetch_dependency(CImg
3029
GIT_REPOSITORY https://github.com/GreycLab/CImg
3130
GIT_TAG v.3.3.2
31+
DONT_BUILD
3232
)
3333

34-
FetchContent_GetProperties(CImg)
35-
if(NOT CImg_POPULATED)
36-
FetchContent_Populate(CImg)
37-
set(CIMG_DIR ${cimg_SOURCE_DIR})
38-
sofa_find_package(CImg REQUIRED)
39-
endif()
34+
set(CIMG_DIR ${CImg_SOURCE_DIR})
35+
sofa_find_package(CImg REQUIRED)
4036
elseif (NOT CImg_FOUND)
4137
message(FATAL_ERROR "CImgPlugin: DEPENDENCY CImg NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install cimg-dev, or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.")
4238
endif()

applications/plugins/SofaMatrix/CMakeLists.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ sofa_find_package(Eigen3 REQUIRED)
99

1010
find_package(metis 5.1.0 EXACT QUIET)
1111
if(NOT metis_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES)
12-
message("SofaMatrix: DEPENDENCY metis NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching metis...")
13-
include(FetchContent)
14-
FetchContent_Declare(metis
12+
message("${PROJECT_NAME}: DEPENDENCY metis NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching metis...")
13+
sofa_fetch_dependency(metis
1514
GIT_REPOSITORY https://github.com/sofa-framework/METIS
1615
GIT_TAG v5.1.0-ModernInstall
1716
)
18-
FetchContent_MakeAvailable(metis)
1917
elseif (NOT metis_FOUND)
20-
message(FATAL_ERROR "SofaMatrix: DEPENDENCY metis NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install metis (version=5.1.0), or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.")
18+
message(FATAL_ERROR "Sofa.Metis: DEPENDENCY metis NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install metis (version=5.1.0), or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.")
2119
endif()
2220

2321

0 commit comments

Comments
 (0)