Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
182 changes: 56 additions & 126 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,171 +1,104 @@
cmake_minimum_required(VERSION 3.15)
cmake_minimum_required(VERSION 3.20)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# ------------------------------------------------------------
# OS Detection (CMake native)
# ------------------------------------------------------------
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(OS_PREFIX "arch-darwin")
else()
set(OS_PREFIX "arch-linux")
endif()

# ------------------------------------------------------------
# Build type / PETSc configuration (Before project())
# ------------------------------------------------------------
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "Debug")
set(TARGET_PETSC_ARCH "${OS_PREFIX}-c-debug")
add_definitions(-DPETSC_USE_DEBUG)
else()
set(TARGET_PETSC_ARCH "${OS_PREFIX}-c-opt")
endif()
project(cfem LANGUAGES C CXX)

message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Requested PETSc Architecture: ${TARGET_PETSC_ARCH}")
message(STATUS "Compiler CXX: ${CMAKE_CXX_COMPILER}")

# LECTURE DEPUIS LE PRESET : On utilise ${PETSC_DIR}, pas $ENV{PETSC_DIR}
if(NOT PETSC_DIR)
message(FATAL_ERROR "PETSC_DIR is not defined. Please use the CMakePresets generated by setup_env_dev.sh")
endif()

set(PETSC_PATH "${PETSC_DIR}/${TARGET_PETSC_ARCH}")
set(ENV{PKG_CONFIG_PATH} "${PETSC_PATH}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")

find_package(PkgConfig REQUIRED)
# ==============================================================================
# IPO / LTO support detection
# ==============================================================================
include(CheckIPOSupported)

pkg_get_variable(PETSC_CXX_RAW petsc cxxcompiler)
pkg_get_variable(PETSC_PREFIX petsc prefix)
if(PETSC_CXX_RAW)
find_program(PETSC_CXX_ABS
NAMES ${PETSC_CXX_RAW}
HINTS
"${PETSC_PREFIX}/bin"
"${PETSC_DIR}/${TARGET_PETSC_ARCH}/bin"
)
check_ipo_supported(RESULT ipo_supported)

if(PETSC_CXX_ABS)
set(CMAKE_CXX_COMPILER ${PETSC_CXX_ABS})
message(STATUS "SUCCESS: Forcing CXX Compiler from PETSc: ${PETSC_CXX_ABS}")
else()
message(FATAL_ERROR "Absolute path not found for ${PETSC_CXX_RAW}.")
endif()
if(ipo_supported)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
message(STATUS "IPO/LTO enabled for Release builds")
else()
message(STATUS "IPO/LTO not supported by this toolchain")
endif()

# ------------------------------------------------------------
# Project Initialization
# ------------------------------------------------------------
project(cfem LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# ==============================================================================
# HPC Optimization Target (Modern CMake)
# ==============================================================================
add_library(cfem_hpc_flags INTERFACE)

# Flags spécifiques
# set(CMAKE_CXX_FLAGS_ASAN "-O1 -g -fsanitize=address -fno-omit-frame-pointer" CACHE STRING "For intense debug/segmentation fault/ illegal memory acces")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto -fopenmp-simd -march=native -ffp-contract=fast -fno-math-errno -DNDEBUG -DTEUCHOS_DEBUG_OFF" CACHE STRING "Flags for pure performance (HPC)" FORCE)
# Release flags
target_compile_options(cfem_hpc_flags INTERFACE
$<$<CONFIG:Release>:-O3 -flto -fopenmp-simd -march=native -ffp-contract=fast -fno-math-errno>
$<$<CONFIG:Debug>:-O0 -g -fno-omit-frame-pointer>
)

if(TARGET_PETSC_ARCH STREQUAL "${OS_PREFIX}-c-debug")
set(APP_PROJECT_NAME cfem_app_dev)
else()
set(APP_PROJECT_NAME cfem_app_opt)
endif()
# Debug macros management (PETSc, Teuchos, NDEBUG)
target_compile_definitions(cfem_hpc_flags INTERFACE
$<$<CONFIG:Release>:NDEBUG TEUCHOS_DEBUG_OFF>
$<$<CONFIG:Debug>:PETSC_USE_DEBUG>
)

# ------------------------------------------------------------
# PETSc & MPI
# ------------------------------------------------------------
pkg_search_module(PETSC REQUIRED IMPORTED_TARGET GLOBAL petsc)
# ==============================================================================
# Dependencies
# ==============================================================================

if(TARGET PkgConfig::PETSC)
find_library(PETSC_MPI_LIB NAMES mpi HINTS "${PETSC_PATH}/lib" NO_DEFAULT_PATH)

if(NOT TARGET PkgConfig::petsc)
add_library(PkgConfig::petsc ALIAS PkgConfig::PETSC)
endif()
# PETSc
if(NOT DEFINED PETSC_DIR OR NOT DEFINED PETSC_ARCH)
message(FATAL_ERROR "PETSC_DIR and PETSC_ARCH must be defined via CMakePresets.")
endif()

target_link_libraries(PkgConfig::PETSC INTERFACE
${PETSC_LIBRARIES}
${PETSC_MPI_LIB}
)
set(PETSC_PATH "${PETSC_DIR}/${PETSC_ARCH}")
set(ENV{PKG_CONFIG_PATH} "${PETSC_PATH}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")

# Make sure the path to libpetsc.so is known
target_link_directories(PkgConfig::PETSC INTERFACE "${PETSC_PATH}/lib")
target_include_directories(PkgConfig::PETSC INTERFACE ${PETSC_INCLUDE_DIRS})
find_package(PkgConfig REQUIRED)
pkg_search_module(PETSC REQUIRED IMPORTED_TARGET GLOBAL petsc)

message(STATUS "PETSc MPI library forced: ${PETSC_MPI_LIB}")
endif()
# MPI
find_library(PETSC_MPI_LIB NAMES mpi HINTS "${PETSC_PATH}/lib" NO_DEFAULT_PATH)
target_link_libraries(PkgConfig::PETSC INTERFACE ${PETSC_MPI_LIB})

# ------------------------------------------------------------
# Math Dependencies (GMP, MPFR, MPC) - MUST BE BEFORE SYMENGINE
# ------------------------------------------------------------
# Math Libraries (GMP, MPFR, MPC)
find_library(GMP_LIB NAMES gmp REQUIRED)
find_library(MPFR_LIB NAMES mpfr REQUIRED)
find_library(MPC_LIB NAMES mpc REQUIRED)

message(STATUS "Found GMP: ${GMP_LIB}")

# ------------------------------------------------------------
# Find SymEngine
# ------------------------------------------------------------
# SymEngine_DIR is provided by the CMakePresets
# SymEngine
find_package(SymEngine REQUIRED CONFIG)

if(SymEngine_FOUND)
message(STATUS "Found SymEngine version: ${SymEngine_VERSION}")

if(TARGET symengine)
target_link_libraries(symengine INTERFACE ${GMP_LIB} ${MPFR_LIB})
target_link_libraries(symengine INTERFACE ${GMP_LIB} ${MPFR_LIB} ${MPC_LIB})
add_library(SymEngine::libsymengine ALIAS symengine)
elseif(TARGET libsymengine)
target_link_libraries(libsymengine INTERFACE ${GMP_LIB} ${MPFR_LIB})
target_link_libraries(libsymengine INTERFACE ${GMP_LIB} ${MPFR_LIB} ${MPC_LIB})
add_library(SymEngine::libsymengine ALIAS libsymengine)
endif()
endif()

# ------------------------------------------------------------
# Find LLVM
# ------------------------------------------------------------
# Once SymEngine is found, we need LLVM. SymEngine is statically linked.
# LLVM
find_package(LLVM REQUIRED CONFIG)
if(LLVM_FOUND)
llvm_map_components_to_libnames(llvm_libs
core mcjit orcjit native ipo bitreader target mc support
)
set(LLVM_SYSTEM_LIBS z zstd dl pthread m ffi tinfo)
llvm_map_components_to_libnames(llvm_libs core mcjit orcjit native ipo bitreader target mc support)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "LLVM include dirs: ${LLVM_INCLUDE_DIRS}")
endif()

# ------------------------------------------------------------
# Find OpenMP
# ------------------------------------------------------------
# OpenMP
find_package(OpenMP REQUIRED)
if(OpenMP_CXX_FOUND)
message(STATUS "Found OpenMP")
endif()

if(OpenMP_CXX_FOUND)
message(STATUS "Found OpenMP: ${OpenMP_CXX_FLAGS}")

add_library(cfem_openmp_interface INTERFACE)

target_link_libraries(cfem_openmp_interface INTERFACE OpenMP::OpenMP_CXX)

target_compile_definitions(cfem_openmp_interface INTERFACE WITH_OPENMP)
endif()

# ------------------------------------------------------------
# Modular Libraries & Applications
# ------------------------------------------------------------
# ==============================================================================
# Subdirectories
# ==============================================================================
add_subdirectory(libs)
add_subdirectory(apps)

# ------------------------------------------------------------
# Testing / GoogleTest
# ------------------------------------------------------------
# ==============================================================================
# Testing (GoogleTest)
# ==============================================================================
include(CTest)

if(BUILD_TESTING)
include(FetchContent)
FetchContent_Declare(
Expand All @@ -176,23 +109,20 @@ if(BUILD_TESTING)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

include(GoogleTest)
add_subdirectory(tests)
endif()

# ==============================================================================
# Git Hooks Configuration
# ==============================================================================
# Automatically configure Git to use the custom hooks directory if it exists
if(EXISTS "${CMAKE_SOURCE_DIR}/.githooks")
execute_process(
COMMAND git config core.hooksPath .githooks
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE GIT_HOOKS_RESULT
OUTPUT_QUIET
ERROR_QUIET
OUTPUT_QUIET ERROR_QUIET
)
if(GIT_HOOKS_RESULT EQUAL 0)
message(STATUS "Git hooks correctly configured to use .githooks/")
endif()
endif()
endif()
9 changes: 7 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 15,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "base",
"hidden": true,
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/build_${presetName}"
"binaryDir": "${sourceDir}/build_${presetName}",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_CXX_STANDARD": "20",
"CMAKE_CXX_STANDARD_REQUIRED": "ON"
}
},
{
"name": "shared-release",
Expand Down
40 changes: 36 additions & 4 deletions CMakeUserPresets.example.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,55 @@
//************************************************************************
// --- CFEM++ Library
// ---
// --- Copyright 2024-2026 Ismaël Tchinda Ngueyong et al.
// --- ALL RIGHTS RESERVED
// ---
// --- This software is protected by international copyright laws.
// --- Use, distribution, or modification of this software in any form,
// --- source or binary, for personal, academic, or non-commercial
// --- purposes is permitted free of charge, provided that this
// --- copyright notice and this permission notice appear in all
// --- copies and supporting documentation.
// ---
// --- The authors and contributors provide this code "as is" without
// --- any express or implied warranty. In no event shall they be
// --- held liable for any damages arising from the use of this software.
//************************************************************************

{
"version": 3,
"configurePresets": [
{
"name": "user-paths",
"hidden": true,
"description": "REPLACE THE PATHS BELOW WITH YOUR OWN LOCAL INSTALLATION PATHS",
"environment": {
"MY_PETSC_DIR": "/path/to/your/petsc/installation"
},
"cacheVariables": {
"PETSC_DIR": "/PATH/TO/YOUR/PETSC/INSTALLATION",
"SymEngine_DIR": "/PATH/TO/YOUR/SYMENGINE/build_${presetName}"
"PETSC_DIR": "$env{MY_PETSC_DIR}",
"SymEngine_DIR": "/path/to/your/symengine/build_release"
}
},
{
"name": "debug",
"inherits": ["shared-debug", "user-paths"],
"displayName": "My Local Debug"
"displayName": "Local Debug",
"description": "Note: Change 'arch-linux-c-debug' to 'arch-darwin-c-debug' if you are on macOS",
"cacheVariables": {
"CMAKE_C_COMPILER": "$env{MY_PETSC_DIR}/arch-linux-c-debug/bin/mpicc",
"CMAKE_CXX_COMPILER": "$env{MY_PETSC_DIR}/arch-linux-c-debug/bin/mpicxx"
}
},
{
"name": "release",
"inherits": ["shared-release", "user-paths"],
"displayName": "My Local Release"
"displayName": "Local Release",
"description": "Note: Change 'arch-linux-c-opt' to 'arch-darwin-c-opt' if you are on macOS",
"cacheVariables": {
"CMAKE_C_COMPILER": "$env{MY_PETSC_DIR}/arch-linux-c-opt/bin/mpicc",
"CMAKE_CXX_COMPILER": "$env{MY_PETSC_DIR}/arch-linux-c-opt/bin/mpicxx"
}
}
]
}
29 changes: 5 additions & 24 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
# apps/CMakeLists.txt

# Define the main simulation executable
# add_executable(${APP_PROJECT_NAME}
# main.cpp
# )

# Link against the solver library
# This automatically pulls in fem, mesh, wrappers, and PETSc
# target_link_libraries(${APP_PROJECT_NAME}
# PRIVATE
# cfem_solvers
# cfem_utils
# cfem_mesh
# cfem_fields
# cfem_exporter
# cfem_expressions
# cfem_petsc_wrappers
# # --- LA RÉSOLUTION DU PROBLÈME EST ICI ---
# SymEngine::libsymengine
# ${llvm_libs}
# dl # Souvent requis par LLVM sur Linux
# z # Souvent requis par LLVM sur Linux
# )
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(APP_PROJECT_NAME cfem_app_dev)
else()
set(APP_PROJECT_NAME cfem_app_opt)
endif()

add_executable(${APP_PROJECT_NAME} main.cpp)

Expand Down
14 changes: 11 additions & 3 deletions scripts/setup_env_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -311,17 +311,25 @@ else
{
"name": "debug",
"inherits": ["shared-debug", "user-paths"],
"displayName": "My Local Debug"
"displayName": "My Local Debug",
"cacheVariables": {
"CMAKE_C_COMPILER": "$PETSC_DIR/${OS_PREFIX}-c-debug/bin/mpicc",
"CMAKE_CXX_COMPILER": "$PETSC_DIR/${OS_PREFIX}-c-debug/bin/mpicxx"
}
},
{
"name": "release",
"inherits": ["shared-release", "user-paths"],
"displayName": "My Local Release"
"displayName": "My Local Release",
"cacheVariables": {
"CMAKE_C_COMPILER": "$PETSC_DIR/${OS_PREFIX}-c-opt/bin/mpicc",
"CMAKE_CXX_COMPILER": "$PETSC_DIR/${OS_PREFIX}-c-opt/bin/mpicxx"
}
}
]
}
EOF
echo -e "${GREEN}[OK] Presets generated.${NC}"
echo -e "${GREEN}[OK] Presets generated with MPI compilers.${NC}"
fi

# ------------------------------------------------------------
Expand Down
Loading
Loading