From 5a6d4e801fdbd4eddd1dd37911a1ac51a243dbd5 Mon Sep 17 00:00:00 2001 From: itchinda Date: Mon, 1 Jun 2026 11:58:26 -0400 Subject: [PATCH] CHORE(CORE): Pre-requisite prior to tackle the assembly module. --- CMakeLists.txt | 182 +++++++++++----------------------- CMakePresets.json | 9 +- CMakeUserPresets.example.json | 40 +++++++- apps/CMakeLists.txt | 29 +----- scripts/setup_env_dev.sh | 14 ++- tests/CMakeLists.txt | 2 + 6 files changed, 117 insertions(+), 159 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4039e1e..a5efd4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + $<$:-O3 -flto -fopenmp-simd -march=native -ffp-contract=fast -fno-math-errno> + $<$:-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 + $<$:NDEBUG TEUCHOS_DEBUG_OFF> + $<$: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( @@ -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() \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json index fe5945e..11fe2ce 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -2,7 +2,7 @@ "version": 3, "cmakeMinimumRequired": { "major": 3, - "minor": 15, + "minor": 20, "patch": 0 }, "configurePresets": [ @@ -10,7 +10,12 @@ "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", diff --git a/CMakeUserPresets.example.json b/CMakeUserPresets.example.json index d61a7bf..1a73406 100644 --- a/CMakeUserPresets.example.json +++ b/CMakeUserPresets.example.json @@ -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" + } } ] } \ No newline at end of file diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index d400314..4d26202 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -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) diff --git a/scripts/setup_env_dev.sh b/scripts/setup_env_dev.sh index d91efa5..c574eca 100755 --- a/scripts/setup_env_dev.sh +++ b/scripts/setup_env_dev.sh @@ -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 # ------------------------------------------------------------ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c7aa0d9..cdd14b4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,5 @@ +include(GoogleTest) + add_executable(unit_tests test_main.cpp wrappers/test_petsc_wrappers.cpp