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
66 changes: 66 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
FROM ubuntu:24.04

# Install apt dependencies
ARG DEBIAN_FRONTEND=noninteractive
ARG NODE_MAJOR=20
RUN apt-get update -qq \
&& apt-get install -y \
curl \
cmake \
ccache \
libsdl2-dev \
g++ \
gdb \
git \
libpng-dev \
ninja-build \
sudo \
python3-pip \
python3-venv \
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/*

# Install nodejs based dependencies
RUN curl -sL https://deb.nodesource.com/setup_${NODE_MAJOR}.x -o nodesource_setup.sh \
&& bash nodesource_setup.sh \
&& apt-get update -qq \
&& apt-get install -y nodejs \
&& npm install -g \
lv_font_conv@1.5.2 \
&& rm nodesource_setup.sh \
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/*

# Install Python dependencies
RUN pip install --break-system-packages \
wheel \
Pillow \
&& pip cache purge

# The user ubuntu already exists set its password to ubuntu and add to sudo group for developing in devcontainer
RUN usermod -aG sudo ubuntu \
&& echo "ubuntu:ubuntu" | chpasswd

# Persist bash history across container rebuilds
# Reference: https://code.visualstudio.com/remote/advancedcontainers/persist-bash-history
ARG USERNAME=ubuntu
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
&& mkdir /commandhistory \
&& touch /commandhistory/.bash_history \
&& chown -R $USERNAME /commandhistory \
&& echo "$SNIPPET" >> "/home/$USERNAME/.bashrc"

USER ubuntu
Copy link
Collaborator

Choose a reason for hiding this comment

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

I should have tried this earlier. But still. Adding the USER ubuntu line breaks the container for me when using podman

I get the following:

$ podman run --rm -it -v ${PWD}:/sources infinisim-build
CMake Error: Unable to (re)create the private pkgRedirects directory:
/sources/build/CMakeFiles/pkgRedirects

Removing the USER ubuntu line everything builds fine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@NeroBurner I am not familiar with podman, I have only used Docker so far. I guess you have a permission issue. You bind mount the sources into the container, which will keep the UID and GID from your local user. Everything inside the container runs as the ubuntu user, which likely has a different UID and GID than the local user. So the processes inside the container can't write to /sources due to missing permissions.
The dev container implementation automatically updates the UID/GID from the container user to match the local one (see the updateRemoteUserUID property in devcontainer.json), but when using just podman as a container engine, you will have to specify that explicitly (I guess, at least for Docker you would have to). Again, I have not used Podman, but it seems it supports that with --userns/--uidmap/--gidmap.

Copy link
Collaborator

Choose a reason for hiding this comment

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

podman runs in userland without the need of a docker-daemon running as root. And as such some permissions are restricted.

When running inside the container (without the USER ubuntu) with podman the shown user is root. But the resulting binaries of the bind mount (the build dir) have the host user as owner.

So I'd like to remove the USER ubuntu part of the Dockerfile and update the README.md with --user $(id -u):$(id -g) for docker users.

could you try that out if that would work (as I don't have docker installed)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have tested the following after removing the USER ubuntu from the Dockerfile (all without a user ubuntu on my local machine):

  1. Rebuilding the dev container with VsCode, building InfiniSim inside the container
    -> The binaries are owned by the local user and can be run outside of the container as well.
  2. Building InfiniSim from command line with docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinisim-build
    -> Same result as in 1.
  3. Build the container in CLion and build InfiniSim in the IDE
    -> Same result as in 1.

Good results and all use cases still work.

Copy link
Collaborator

Choose a reason for hiding this comment

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

awesome! thanks for checking! 🙇

would you be willing to open a PR and update the readme and docker container? if not it's also OK as you were already very helpful!

Copy link
Contributor Author

@dariusarnold dariusarnold Jun 19, 2025

Choose a reason for hiding this comment

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

Yes, I can do that.

Edit: Done, please check #178


# Section for interactive compilation during docker run

WORKDIR /sources
# Directory if InfiniTime source code
ENV InfiniTime_DIR="/sources/InfiniTime"
# Passed to CMake generate step
ENV GENERATE_ARGS=""
# Passed to CMake build step
ENV BUILD_ARGS=""
# Build directory
ENV BUILD_DIRECTORY="build"

CMD ["bash", "-c", "cmake -S . -B ${BUILD_DIRECTORY} -G Ninja -DInfiniTime_DIR=${InfiniTime_DIR} ${GENERATE_ARGS} \
&& cmake --build ${BUILD_DIRECTORY} ${BUILD_ARGS}"]
35 changes: 35 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// For format details, see https://aka.ms/devcontainer.json.
{
"name": "InfiniSim Dev Container",
"build": {
"dockerfile": "Dockerfile"
},

// Configure tool-specific properties.
"customizations": {
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cmake-tools",
"notskm.clang-tidy",
"mjohns.clang-format",
"timonwong.shellcheck"
]
}
},

"mounts": [
// Local volume to store bash history across rebuilds
"source=infinisim-bashhistory,target=/commandhistory,type=volume"
// Uncomment and modify path to mount external InfiniTime source into the container
//,"source=/home/example/git/InfiniTime,target=/workspaces/InfiniTime,type=bind,consistency=cached"
],

// Sudo password "ubuntu"
"remoteUser": "ubuntu"
// This might be needed when you do not have a local user called ubuntu but your dev container implementation
// tries to find it in the local /etc/passwd and fails to build your container.
// The default is true.
//,"updateRemoteUserUID": false
}
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ The following configuration settings can be added to the first `cmake -S . -B bu
Ex: `-DENABLE_USERAPPS="Apps::Timer, Apps::Alarm"`.
The default list of user applications will be selected if this variable is not set.

### Build with Docker

You can also build the simulator using Docker.
This is useful if you don't want to install all the dependencies on your system.
First build the Docker image:
```sh
docker build -t infinisim-build .devcontainer
```

Afterwards you can build the simulator with:
```sh
docker run --rm -it -v ${PWD}:/sources infinisim-build
```

By default this builds the simulator using the InfiniTime files from the submodule in your `${PWD}`.
If you want to use a different repository, you got to mount it and pass the path to the `INFINITIME_DIR` variable:
```sh
docker run --rm -it -v ${PWD}:/sources -v ${PWD}/../InfiniTime:/infinitime -e INFINITIME_DIR=/infinitime infinisim-build
```

Other CMake generation and build arguments can be passed to the `GENERATE_ARGS` and `BUILD_ARGS` variables:
```sh
docker run --rm -it -v ${PWD}:/sources -e GENERATE_ARGS=-DENABLE_USERAPPS="Apps::Timer,Apps::Alarm" -e BUILD_ARGS=-j16 infinisim-build
```


## Run Simulator

When the build was successful the simulator binary can be started with
Expand Down