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

[LinearSolver.Direct] Fix metis dependency #4450

Merged
merged 17 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 4 additions & 3 deletions Sofa/Component/LinearSolver/Direct/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ set(SOURCE_FILES
${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/TypedMatrixLinearSystem[BTDMatrix].cpp
)

sofa_find_package(metis QUIET) # Unix users can have an installed version of metis
if(NOT metis_FOUND)
find_package(Metis 5.1.0 EXACT QUIET)
if(NOT Metis_FOUND)
message(STATUS "${PROJECT_NAME}: using built-in metis library")
option(METIS-GKLIB_GKRAND "enable GKRAND support" ON) #GKRAND support allows the portability of random number generation across different architectures
add_subdirectory(extlibs/metis-5.1.0)
endif()

sofa_set_01(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_METIS VALUE TRUE)

# make sure you have threads for AsyncSparseLDLSolver
Expand All @@ -71,7 +72,7 @@ sofa_find_package(Sofa.Component.LinearSolver.Iterative REQUIRED) # Only for Mat

add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${WRAPPER_FILES})
target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Core Sofa.Component.LinearSolver.Iterative)
target_link_libraries(${PROJECT_NAME} PUBLIC metis)
target_link_libraries(${PROJECT_NAME} PUBLIC metis::metis)
target_link_libraries(${PROJECT_NAME} PUBLIC Threads::Threads)

sofa_create_package_with_targets(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xGNU" OR "x${CMAKE_CXX_COMPILER_ID}" ST
add_compile_options(-fPIC)
endif()

add_library(${PROJECT_NAME} STATIC ${metis_sources} ${GKlib_sources})
add_library(${PROJECT_NAME} SHARED ${metis_sources} ${GKlib_sources})
# add an alias to fully qualified name to unify interface with other cmake config files
add_library(metis::metis ALIAS metis)
target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GKlib>")
target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libmetis>")

Expand All @@ -30,6 +32,9 @@ endif()
if(WIN32)
# remove warnings about deprecation (CRT,etc)
target_compile_options(${PROJECT_NAME} PRIVATE "/wd4996")

# Automatically export all symbols (and create .lib)
set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()

sofa_create_package_with_targets(
Expand Down
108 changes: 108 additions & 0 deletions Sofa/framework/Config/cmake/Modules/FindMetis.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Find the metis headers and libraries
# Behavior is to first look for config files, such as the one installed by some package
# managers who provides their own cmake files.
# Most of them and official sources does not provide cmake finders, so if no config files
# were found, this tries to find the library by looking at headers / lib file.
#
# Defines:
# Metis_FOUND : True if metis is found
# Metis_FOUND : True if metis is found
#
# Provides both targets metis and metis::metis.
# Target metis::metis is just an alias to metis.
# We chose to create an alias to provide a unified interface usable whatever the package manager
# was used to provide the library, as some package managers (such vcpkg) defines only short name
# for the target, whereas others (such as conan) defines a fully qualified name.

find_package(metis NO_MODULE QUIET)

if(NOT Metis_FIND_VERSION)
if(NOT Metis_FIND_VERSION_MAJOR)
set(Metis_FIND_VERSION_MAJOR 0)
endif(NOT Metis_FIND_VERSION_MAJOR)
if(NOT Metis_FIND_VERSION_MINOR)
set(Metis_FIND_VERSION_MINOR 0)
endif(NOT Metis_FIND_VERSION_MINOR)
if(NOT Metis_FIND_VERSION_PATCH)
set(Metis_FIND_VERSION_PATCH 0)
endif(NOT Metis_FIND_VERSION_PATCH)
set(Metis_FIND_VERSION "${Metis_FIND_VERSION_MAJOR}.${Metis_FIND_VERSION_MINOR}.${Metis_FIND_VERSION_PATCH}")
endif()

macro(_metis_check_version)
if(EXISTS "${Metis_INCLUDE_DIR}/metis.h")
file(READ "${Metis_INCLUDE_DIR}/metis.h" _metis_version_header)
endif()

string(REGEX MATCH "define[ \t]+METIS_VER_MAJOR[ \t]+([0-9]+)" _metis_major_version_match "${_metis_version_header}")
set(Metis_VERSION_MAJOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+METIS_VER_MINOR[ \t]+([0-9]+)" _metis_minor_version_match "${_metis_version_header}")
set(Metis_VERSION_MINOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+METIS_VER_SUBMINOR[ \t]+([0-9]+)" _metis_patch_version_match "${_metis_version_header}")
set(Metis_VERSION_PATCH "${CMAKE_MATCH_1}")

set(Metis_VERSION ${Metis_VERSION_MAJOR}.${Metis_VERSION_MINOR}.${Metis_VERSION_PATCH})
set(Metis_VERSION_OK TRUE)
if(${Metis_VERSION} VERSION_LESS ${Metis_FIND_VERSION})
set(Metis_VERSION_OK FALSE)
message(SEND_ERROR "Metis version ${Metis_VERSION} found in ${Metis_INCLUDE_DIR}, "
"but at least version ${Metis_FIND_VERSION} is required")
endif()
if(${Metis_FIND_VERSION_EXACT} AND NOT ${Metis_VERSION} VERSION_EQUAL ${Metis_FIND_VERSION})
set(Metis_VERSION_OK FALSE)
message(SEND_ERROR "Metis version ${Metis_VERSION} found in ${Metis_INCLUDE_DIR}, "
"but exact version ${Metis_FIND_VERSION} is required")
endif()
# message(STATUS "Metis version found: ${Metis_VERSION} in ${Metis_INCLUDE_DIR}, ${Metis_FIND_VERSION} was required ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to message or not? If not, please remove this line

endmacro()

if(TARGET metis)
set(Metis_FOUND TRUE) # only metis_FOUND has been set
if(Metis_INCLUDE_DIR AND NOT DEFINED Metis_VERSION)
_metis_check_version()
endif()
set(Metis_FOUND ${Metis_VERSION_OK})
add_library(metis::metis ALIAS metis)
else()

if(NOT Metis_INCLUDE_DIR)
find_path(Metis_INCLUDE_DIR
NAMES metis.h
PATH_SUFFIXES include
)
endif()

if(NOT Metis_LIBRARY)
find_library(Metis_LIBRARY
NAMES metis
PATH_SUFFIXES lib
)
endif()

if(Metis_INCLUDE_DIR AND Metis_LIBRARY)
_metis_check_version()
set(Metis_FOUND ${Metis_VERSION_OK})
endif()

if(Metis_FOUND)
set(Metis_LIBRARIES ${Metis_LIBRARY})
set(Metis_INCLUDE_DIRS ${Metis_INCLUDE_DIR})

if(NOT Metis_FIND_QUIETLY)
message(STATUS "Found Metis: ${Metis_LIBRARIES} (version ${Metis_VERSION} from ${Metis_INCLUDE_DIR}/metis.h)")
endif()

if(NOT TARGET metis)
add_library(metis INTERFACE IMPORTED)
set_property(TARGET metis PROPERTY INTERFACE_LINK_LIBRARIES "${Metis_LIBRARIES}")
set_property(TARGET metis PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Metis_INCLUDE_DIR}")
endif()
add_library(metis::metis ALIAS metis)
else()
endif()
mark_as_advanced(Metis_INCLUDE_DIR Metis_LIBRARY)
endif()

if(NOT Metis_FOUND AND Metis_FIND_REQUIRED)
message(FATAL_ERROR "Cannot find metis")
endif()
Loading