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
20 changes: 14 additions & 6 deletions 03_building_and_packaging/cmake_demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ Example code is in [`building-and-packaging/material/examples/cmake`](https://gi
## CMake "Hello World"

- Look at and explain `CMakeLists.txt`.
- `cmake --help-command-list`, `cmake --help-command add_executable`
- `mkdir build && cd build && cmake ..`
- Standard to create `build` directory, don't call `cmake` in root directory.
- In case of doubt, you can always just delete complete folder.
- And you can have multiple build folders.
- Explain and look at files:
- `Makefile`: lengthier than you think, many targets, search for `helloworld`
- `CMakeCache.txt`: stores values of variables, used by GUIs for example
- `cmake_install.cmake`: a file used by CPack internally, ignore it
- `CMakeFiles`: even much more things that are not so important right now
- `make` and `./helloworld`
- `make clean`
- Makefiles are created by default, one can also create other things: `cmake --help`
- A bit more modern: From project root call:
- `cmake -S. -Bbuild`
- `cmake --build build` (independent of generator)

## Multiple files

Expand Down Expand Up @@ -70,7 +76,7 @@ int main()
- add_executable(helloworld "${SRC_FILES}")
```

- Build static lib `libHelloWorld.a`, that's the default
- Build static lib `libsse.a`, that's the default
- Build shared lib by `cmake -DBUILD_SHARED_LIBS=ON ..`, don't change in `CMakeLists.txt`, but stick to standards
- Define CMake variables with `-D`, we will come back to this later
- Now, let's use the library:
Expand All @@ -96,7 +102,7 @@ int main()
`main.cpp`:

```diff
+ #include "precice/SolverInterface.hpp"
+ #include "precice/Tooling.hpp"
...
sse();
+ std::cout << precice::getVersionInformation() << std::endl;
Expand All @@ -107,15 +113,17 @@ sse();
`CMakeLists.txt`:

```diff
find_package(precice REQUIRED CONFIG)
find_package(precice 3 REQUIRED CONFIG)
target_link_libraries(helloworld PRIVATE precice::precice)
```

- `cmake ..` and `make` and `./helloworld`
- `find_package` works if dependency is "cmake-ready"
- `3` is the major version we look for.
- There is a ["module" and a "config" mode](https://cmake.org/cmake/help/latest/command/find_package.html)
- "module" mode
- Is there a `Findprecice.cmake` module in CMake? Some are shipped with CMake. But this doesn't scale.
- Find out which: `cmake --help-module-list | grep "Find"`
- Is there a `Findprecice.cmake` module elsewhere? We could ship one with our helloworld program. But these modules often out-of-date.
- "config" mode (here the case, the newer/better way of doing things)
- Is there a `preciceCongfig.cmake`? A file installed by preCICE. Scales and up-to-date.
Expand All @@ -135,8 +143,6 @@ target_link_libraries("${PROJECT_NAME}" PRIVATE precice)
- Use variables to talk to CMake.
- Let's try to make preCICE an optional dependency of our code (not really everybody has preCICE installed, sadly).

`CMakeLists.txt`:

`main.cpp`:

```c++
Expand All @@ -145,7 +151,9 @@ target_link_libraries("${PROJECT_NAME}" PRIVATE precice)
#endif
```

and around header.
and around header (double negating is also the standard way to do things here).

`CMakeLists.txt`:

```cmake
option(ENABLE_PRECICE "Enable use of preCICE." ON)
Expand Down
38 changes: 12 additions & 26 deletions 03_building_and_packaging/cmake_exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,40 @@ In this exercise, we need to fight. Not everything always works smoothly. This i

To get an independent and reproducible environment as common ground, we use and, thus repeat, Docker.

Deadline: **Thursday, December 1st, 2022, 9:00**
Deadline: **Thursday, November 27th, 2024, 9:00**

## Overview

- The goal of the exercise is to open a pull request from a fork of [the CMake exercise repository](https://github.com/Simulation-Software-Engineering/cmake-exercise-wt2223). Please name your pull request `Add building and container recipes` and assign yourself. In the pull request description, please explain what we need to do to test your code.
- Your should add a `Dockerfile` and a `CMakeLists.txt`, besides some minor changes in `main.cpp` like commenting in some code parts. It should be possible to create an executable container from your pull request. Inside the container, one should be able to directly build the C++ code (`main.cpp`) using CMake. Use as many of the currently commented-out additional files, which induce additional dependencies.
- The goal of the exercise is to open a pull request from a fork of [the CMake exercise repository](https://github.com/Simulation-Software-Engineering/cmake-exercise-wt2425). Please name your pull request `Add building and container recipes` and assign yourself.
- Your pull request should add a `Dockerfile` and a `CMakeLists.txt`, besides some minor changes in `main.cpp`, such as commenting in some code parts.
- From your pull request, it should be possible to create an executable container. After running the container, it should be possible to `cd` into `cmake-exercise` and then run the `build_and_run.sh` script.
- Use as many of the currently commented-out additional files, which induce additional dependencies.

## First Steps

1. Fork and clone the repository, have a look at the `main.cpp` and the `README.md`.
2. Build `main.cpp` manually (e.g. `g++ main.cpp -o main`) and run the executable (`./main`).
3. Build a Docker image, run a container (in interactive mode), and repeat steps 1 and 2 within the container.
4. Look into and use the `build_and_run.sh` script.

## Repository Structure

The bare `main.cpp` uses several additions, which are located in the following subdirectories, each containing a `cpp` and a `hpp` file with the same name.

- `flatset` adds a function to create and modify a flat set using [Boost Container](https://www.boost.org/doc/libs/1_80_0/doc/html/container.html) and outputs the set. This example is adapted from a [cppsecrets blog post](http://cppsecrets.com/article.php?id=2834).
- `filesystem` adds a function to inspect and output the current directory using [Boost Filesystem](https://www.boost.org/doc/libs/1_75_0/libs/filesystem/doc/index.htm). This example is adapted from [tutorial 4](https://www.boost.org/doc/libs/1_80_0/libs/filesystem/example/tut4.cpp) of Boost Filesystem.
- `flatset` adds a function to create and modify a flat set using [Boost Container](https://www.boost.org/doc/libs/1_86_0/doc/html/container.html) and outputs the set. This example is adapted from a [cppsecrets blog post](http://cppsecrets.com/article.php?id=2834).
- `filesystem` adds a function to inspect and output the current directory using [Boost Filesystem](https://www.boost.org/doc/libs/1_86_0/libs/filesystem/doc/index.htm). This example is adapted from [tutorial 4](https://www.boost.org/doc/libs/1_86_0/libs/filesystem/example/tut4.cpp) of Boost Filesystem.
- `fem` defines a class to solve the Poisson problem with the finite-element method (FEM) using [deal.II](https://www.dealii.org/). Output is written to a file `solution.vtk`, which can be visualized with, for example, [Paraview](https://www.paraview.org/). This example is adapted from the [tutorial step 3](https://dealii.org/current/doxygen/deal.II/step_3.html) of deal.II.
- `yamlParser` adds a function to parse a simple yaml file using [yaml-cpp](https://github.com/jbeder/yaml-cpp) and to output the value of the key `version`. The folder also contains an example file `config.yml`.

Further resources:

- `inittimezone`: A bash script that comes handy when inheriting from Ubuntu Docker images. More information on what to do with it below.

## CMake

Please choose a meaningful project name. As target name, use `main`. We recommend to follow best practice and create a `build` directory at the root level from which `cmake ..` is called.

## Docker Setup

The code and all dependencies should run in a Docker container based on the `ubuntu:22.04` image. As by now, you already know how to set up a basic Docker container, we do no longer provide detailed instructions. We recommend to build the Dockerfile incrementally. Start with a rather empty one and install dependencies manually in the interactive mode. Take notes of the commands you use, so you can integrate them into the Dockerfile afterwards and rebuild your image.

To prevent the image from asking the timezone in some dialog, use ...

```docker
COPY inittimezone /usr/local/bin/inittimezone
RUN inittimezone
```

... **before** you install new packages. Otherwise the Docker image creation will be stuck at a point that requires user interaction while it is not possible to interact with the process. You might need make `inittimezone` executable first: `chmod +x inittimezone`.
The code and all dependencies should run in a Docker container based on the `ubuntu:24.04` image. As by now, you already know how to set up a basic Docker container, we do no longer provide detailed instructions. We recommend building the Dockerfile incrementally. Start with a rather empty one and install dependencies manually in the interactive mode. Take notes of the commands you use, so you can integrate them into the Dockerfile afterwards and rebuild your image.

Some standard packages available on Aptitude might come handy:

- `build-essential`
- `cmake`
- `git`
- `unzip`
- `wget`
- `vim`

Expand All @@ -60,5 +46,5 @@ Some standard packages available on Aptitude might come handy:
Add dependencies one by one: Comment in the parts of `main.cpp` that are connected to a specific dependency. Then, install the dependency and extend the `CMakeLists.txt`. Verify that you can build and run the executable. If everything works, go on and include the next dependency.

- Maybe start with the boost dependencies. Boost Container is a header-only dependency, Boost Filesystem needs to be linked. Both are available in `libboost-all-dev`. There is a CMake module to [find boost libraries](https://cmake.org/cmake/help/latest/module/FindBoost.html).
- deal.II is available in `libdeal.ii-dev`. deal.II uses some fancy [CMake macros](https://www.dealii.org/current/users/cmake_user.html).
- yaml-cpp is an optional bonus task. For some arbitrary reason, we are not happy with the latest release of the software (which would be available through Aptitude), but we want to use the current `master` branch [directly from GitHub](https://github.com/jbeder/yaml-cpp). Get it via `git clone`, and build and install (`make install`) it yourself. Do not forget to add the necessary instructions to the Dockerfile. Sometimes containers behave weirdly: If libraries in `/usr/local/lib` are not found by CMake, please add the path to the environment variable `LD_LIBRARY_PATH`.
- deal.II is available in `libdeal.ii-dev`. deal.II uses some specific [CMake macros](https://www.dealii.org/current/users/cmake_user.html).
- yaml-cpp is an optional bonus task. For some arbitrary reason, we are not happy with the latest release of the software (which would be available through Aptitude), but we want to use exactly version `v0.6.3` [directly from GitHub](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.3). Get the sources with [wget](https://linuxize.com/post/wget-command-examples/) and build and install (`make install`) it yourself. Do not forget to add the necessary instructions to the Dockerfile. If libraries in `/usr/local/lib` are not found by CMake, please add the path to the environment variable `LD_LIBRARY_PATH`.
9 changes: 5 additions & 4 deletions 03_building_and_packaging/cmake_slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ slideOptions:

## Learning Goals of This Unit

- Understand the motivation of learning CMake.
- Explain the motivation of learning CMake.
- Work with CMake as a user of a project following good practices (using variables, specifying locations of dependencies).
- Develop simple CMake projects (executable vs. library, dependencies) and know how to learn more.

Expand All @@ -54,7 +54,7 @@ slideOptions:

## Are There Alternatives?

> Yes, `autotools`, `scons`, ...
> Yes, `autotools`, `scons`, `meson`, `bazel`, ...

---

Expand All @@ -67,9 +67,9 @@ slideOptions:
## At Least Some Reasons Why CMake is Great?

- CMake can generate files for many build systems: Make, ninja, VSCode project, Eclipse project, ...
- Many **GUIs** and **TUIs**: `ccmake`, `cmake-gui`, integration in probably nearly all IDEs, ...
- Many **GUIs** and **TUIs**: `ccmake`, `cmake-gui`, integration with IDEs, ...
- CMake is **cross-platform**: you can ideally use same CMake file in all OS (easy to distinguish platform-specific things).
- CMake build directory independent of project source directory (build multiple versions with different dependencies, different build types, etc.)
- CMake build directory independent of project source directory (build multiple versions with different dependencies, build types, ...)
- CMake respects choices in user environment (e.g. user defines cpp compiler through `CXX`).
- Wide language support

Expand Down Expand Up @@ -168,3 +168,4 @@ slideOptions:
- [An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/)
- [Professional CMake](https://crascit.com/professional-cmake/), an up-to-date (non-public) book
- [CMake Cookbook](https://github.com/dev-cafe/cmake-cookbook)
- [Code Refinery CMake course](https://coderefinery.github.io/cmake-workshop/)
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
From ubuntu:22.04

COPY inittimezone /usr/local/bin/inittimezone

# Run inittimezone and install a few dependencies
RUN apt-get -qq update && \
inittimezone && \
apt-get -qq -y install \
build-essential \
g++ \
vim
FROM ubuntu:24.04

ADD print_my_environment_variable.sh .
CMD ["/bin/bash"]

This file was deleted.

15 changes: 7 additions & 8 deletions 03_building_and_packaging/linux_fundamentals_demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Example code is in [`building-and-packaging/material/examples/shared-and-static-
- Run `ldd` on `main-shared` and `main-static`.
- There will several libraries linked to `main-shared`.
- When using `ldd` on `main-static`, we get the message `not a dynamic executable`.
- Easier to grasp: `libtree -v main-shared`, [libtree](https://github.com/haampie/libtree)
- Run `ls -lah` to show different executable sizes:

```bash
Expand All @@ -30,14 +31,11 @@ Example code is in [`building-and-packaging/material/examples/shared-and-static-

- `/`: primary root
- `/home`: contains user's home directories
- `/bin`: executables important for the system/OS
- `/sbin`: executables important for the system/OS to be executed by the super user
- `/usr/`: second hierarchy level containing things not required by the OS:
- `/usr/lib/`
- `/usr/bin/`, `/usr/sbin/`
- `/usr/include/`
- `/usr/local`: third level hierarchy level containing packages built manually
- ...and more directories. Details and meaning can be found on [homepage of FHS](https://refspecs.linuxfoundation.org/fhs.shtml).
- `/bin`: executables installed by package manager
- `/sbin`: executables installed by package manager, executed by the super user
- `/lib`: libraries installed by package manager
- `/usr/`: historic reasons, often today simply symbolic links
- `/usr/local`: third level hierarchy level containing packages installed manually

## Environment Variables

Expand All @@ -49,6 +47,7 @@ Example code is in [`building-and-packaging/material/examples/environment-variab
- `ls`
- `ls usr`
- `ls usr/local`
- `echo $PATH`
- Show all environment variables: `env`
- Show script `print_my_environment_variable.sh`
- Use script:
Expand Down
5 changes: 3 additions & 2 deletions 03_building_and_packaging/linux_fundamentals_slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ SlideOptions:

## Filesystem Hierarchy Standard

- Defines filesystem layout and location of common files on Linux
<img src="https://raw.githubusercontent.com/Simulation-Software-Engineering/Lecture-Material/main/03_building_and_packaging/figs/filesystem_hierarchy_structure/fig.png" width=100%; style="margin-left:auto; margin-right:auto; padding-top: 25px; padding-bottom: 25px">
- Defines filesystem layout on Linux
<img src="https://raw.githubusercontent.com/Simulation-Software-Engineering/Lecture-Material/main/03_building_and_packaging/figs/filesystem_hierarchy_structure/fig.png" width=80%; style="margin-left:auto; margin-right:auto; padding-top: 25px; padding-bottom: 25px">
- Often symbolic links between 1st and 2nd hierarchy: `bin -> usr/bin`
- [Official homepage of FHS](https://refspecs.linuxfoundation.org/fhs.shtml)

---
Expand Down
14 changes: 2 additions & 12 deletions 03_building_and_packaging/make_demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@ Example code is in [`building-and-packaging/material/examples/make`](https://git

Show `main.cpp` and build by hand `g++ -o helloworld main.cpp`

```cpp
#include <iostream>

int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
```

## Single Rule Example

- Remove `helloworld`.
Expand Down Expand Up @@ -64,13 +54,12 @@ helloworld : main.cpp sse.o
- Run `make`, only builds `sse.o`
- By default, first target is built.
- `make helloworld` to build specific target
- phony target (a helper target, doesn't correspond to a file)

```diff
+ all : helloworld sse.o
```

- Why does Make not just build directly build all targets? We could want to do different things with different targets.
- Why does Make not just directly build all targets? We could want to do different things with different targets.
- `all` typically comes first.
- Add `clean` target, has no dependency.

Expand All @@ -81,6 +70,7 @@ helloworld : main.cpp sse.o

- Run `make clean`
- `mkdir clean` and `make clean` confuses Make.
- phony target (a helper target, doesn't correspond to a file)

```
+ .PHONY : all clean
Expand Down
6 changes: 3 additions & 3 deletions 03_building_and_packaging/make_slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ slideOptions:

## Learning Goals of This Unit

- Understand the basic functionality of makefiles (timestamps, dependencies, update rules).
- Explain the basic functionality of makefiles (timestamps, dependencies, update rules).
- Read simple makefiles and know where to look for additional material for complex makefiles.
- Write simple makefiles for small projects.

Expand All @@ -50,7 +50,7 @@ Introduce `Hello-World` example
- A build system
- The / a go-to solution for small (research) projects (e.g., latex document, processing data, ...), though also used in big projects ([Linux kernel](https://github.com/torvalds/linux))
- A building block for CMake
- Nice non-expert introduction in [py-RSE book, chapter 9](https://merely-useful.tech/py-rse/automate.html)
- Nice non-expert introduction in [py-RSE book, chapter 9](https://third-bit.com/py-rse/automate.html)
- [GNU Make](https://www.gnu.org/software/make/): standard implementation of Make for Linux and macOS

---
Expand Down Expand Up @@ -82,7 +82,7 @@ Introduce `Hello-World` example
- Wildcards
- ... but becomes quickly [very hard to read](https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html).
- Not covered because CMake does this for us.
- But nicely documented in [py-RSE chapter 9](https://merely-useful.tech/py-rse/automate.html).
- But nicely documented in [py-RSE chapter 9](https://third-bit.com/py-rse/automate.html).

---

Expand Down
Loading