diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2fa0494 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.16) +project(cmake_exercise) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# --- Find Dependencies --- +find_package(Boost REQUIRED COMPONENTS filesystem) +find_package(deal.II REQUIRED) +find_package(yaml-cpp REQUIRED) +find_package(MPI REQUIRED) +find_package(OpenMP REQUIRED) + +# --- Define the Executable --- +add_executable(main + main.cpp + flatset/flatset.cpp + filesystem/filesystem.cpp + fem/fem.cpp + yamlParser/yamlParser.cpp +) + +# --- Link Libraries --- +# 1. Setup deal.II (Handles Trilinos, PETSc, TBB, etc.) +deal_ii_setup_target(main) + +# 2. Link other libraries (Using plain style to match deal.II) +target_link_libraries(main + Boost::filesystem + yaml-cpp + MPI::MPI_CXX + OpenMP::OpenMP_CXX +) + +# --- Include Directories --- +target_include_directories(main PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + /usr/include/trilinos + /usr/include/petsc +) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5c546bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:24.04 + +# Prevent interactive prompts during installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install all dependencies including the tricky ones (Trilinos, PETSc, TBB, MPI, Kokkos) +RUN apt-get update && apt-get install -y \ + build-essential \ + cmake \ + git \ + wget \ + unzip \ + vim \ + libboost-all-dev \ + libdeal.ii-dev \ + mpi-default-dev \ + libkokkos-dev \ + libtrilinos-epetra-dev \ + libtrilinos-epetraext-dev \ + libtrilinos-teuchos-dev \ + libtrilinos-aztecoo-dev \ + libtrilinos-amesos-dev \ + libtrilinos-ifpack-dev \ + libtrilinos-ml-dev \ + libpetsc-real-dev \ + libtbb-dev \ + && rm -rf /var/lib/apt/lists/* + +# Manual install of yaml-cpp 0.6.3 +WORKDIR /tmp +RUN wget https://github.com/jbeder/yaml-cpp/archive/refs/tags/yaml-cpp-0.6.3.zip +RUN unzip yaml-cpp-0.6.3.zip +RUN cd yaml-cpp-yaml-cpp-0.6.3 && \ + mkdir build && cd build && \ + cmake .. -DYAML_BUILD_SHARED_LIBS=ON && \ + make -j4 && \ + make install + +# Set environment variables +ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +WORKDIR /cmake-exercise \ No newline at end of file diff --git a/README.md b/README.md index 9e27f1f..1b6d97b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,60 @@ # Let's Fight With CMake, Docker, and Some Dependencies +# CMake Exercise: Dependency Management with Docker -Repository for the [CMake exercise](https://github.com/Simulation-Software-Engineering/Lecture-Material/blob/main/03_building_and_packaging/cmake_exercise.md). +This repository contains the solution for the CMake exercise. It demonstrates how to manage complex C++ dependencies (Deal.II, MPI, PETSc, Trilinos, TBB, Boost, and yaml-cpp) using a reproducible Docker environment. + +## Overview + +The project compiles a C++ application that performs: +1. **FEM Simulation:** Solves a Poisson problem using Deal.II. +2. **Flatset Manipulation:** Uses Boost Container. +3. **Filesystem Inspection:** Uses Boost Filesystem. +4. **YAML Parsing:** Uses a manually built version of `yaml-cpp`. + +## Prerequisites + +- Docker + +## How to Build and Run + +1. **Build the Docker Image:** + ```bash + docker build -t cmake-exercise . + ``` + +2. **Run the Container:** + ```bash + # Linux/Mac + docker run -it -v $(pwd):/cmake-exercise cmake-exercise bash + + # Windows PowerShell + docker run -it -v ${PWD}:/cmake-exercise cmake-exercise bash + ``` + +3. **Compile and Run (inside the container):** + The repository includes a helper script to build and execute the program: + ```bash + ./build_and_run.sh + ``` + +4. **Test YAML Parser:** + To manually test the YAML parser functionality: + ```bash + ./build/main yamlParser/config.yml + ``` + +## Dependencies + +The `Dockerfile` handles the installation of: +- `build-essential`, `cmake`, `git`, `wget`, `unzip`, `vim` +- `libboost-all-dev` +- `libdeal.ii-dev` +- `mpi-default-dev` +- `libkokkos-dev` +- `libtrilinos-*` packages +- `libpetsc-real-dev` +- `libtbb-dev` +- `yaml-cpp` (v0.6.3 built from source) + + +Repository for the [CMake exercise](https://github.com/Simulation-Software-Engineering/Lecture-Material/blob/main/03_building_and_packaging/cmake_exercise.md). \ No newline at end of file diff --git a/main.cpp b/main.cpp index 7588360..ba913dc 100644 --- a/main.cpp +++ b/main.cpp @@ -1,39 +1,39 @@ -//#include "fem/fem.hpp" -//#include "flatset/flatset.hpp" -//#include "filesystem/filesystem.hpp" -//#include "yamlParser/yamlParser.hpp" +#include "fem/fem.hpp" +#include "flatset/flatset.hpp" +#include "filesystem/filesystem.hpp" +#include "yamlParser/yamlParser.hpp" #include int main(int argc, char *argv[]) { std::cout << "Let's fight with CMake, Docker, and some dependencies!" << std::endl << std::endl; - //std::cout << "Solve Poisson problem with FEM using deal.II" << std::endl; - //Fem fem; - //fem.run(); - //std::cout << std::endl; + std::cout << "Solve Poisson problem with FEM using deal.II" << std::endl; + Fem fem; + fem.run(); + std::cout << std::endl; - //std::cout << "Modify a flat set using boost container" << std::endl; - //modifyAndPrintSets(); - //std::cout << std::endl; + std::cout << "Modify a flat set using boost container" << std::endl; + modifyAndPrintSets(); + std::cout << std::endl; - //std::cout << "Inspect the current directory using boost filesystem" << std::endl; - //inspectDirectory(); - //std::cout << std::endl; + std::cout << "Inspect the current directory using boost filesystem" << std::endl; + inspectDirectory(); + std::cout << std::endl; - //if ( argc == 2 ) - //{ - // const std::string yamlFile( argv[1] ); - // std::cout << "Parse some yaml file with yaml-cpp" << std::endl; - // std::cout << " " << yamlFile << std::endl; - // parseConfig( yamlFile ); - //} - //else - //{ - // std::cout << "To parse a yaml file please specify file on command line" << std::endl; - // std::cout << " ./main YAMLFILE" << std::endl; - //} + if ( argc == 2 ) + { + const std::string yamlFile( argv[1] ); + std::cout << "Parse some yaml file with yaml-cpp" << std::endl; + std::cout << " " << yamlFile << std::endl; + parseConfig( yamlFile ); + } + else + { + std::cout << "To parse a yaml file please specify file on command line" << std::endl; + std::cout << " ./main YAMLFILE" << std::endl; + } return 0; }