Skip to content

Commit e85b314

Browse files
committed
Cross compilation Dockerfile and CMake toolchains
- Added Dockerfile based on Ubuntu Noble - Build dependencies for cross compiling C/C++ - Added CMake toolchain files to set compilers and flags for cross compilation targets. - Added first draft for a CI based on GitHub actions to build, test and publish the docker image. - Uses unzipped source-code FMU from OpenModelica with some modifications, based on omc v1.26.0-dev.
0 parents  commit e85b314

File tree

268 files changed

+112209
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

268 files changed

+112209
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
3+
{
4+
"name": "def_container_crossbuild:latest",
5+
6+
"build": {
7+
"dockerfile": "../../Dockerfile"
8+
},
9+
10+
// Additional VSCode extensions
11+
"customizations": {
12+
"vscode": {
13+
"extensions": [
14+
"ms-vscode.cpptools-extension-pack"
15+
]
16+
}
17+
},
18+
19+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
20+
"remoteUser": "ubuntu"
21+
}

.gitattributes

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Mark the generated FMU_Interaction1 resources as generated/ignored for diffs
2+
# - linguist-generated=true: tells GitHub linguist this is generated code
3+
# - export-ignore: exclude from archive exports
4+
# - -diff: disable textual diffs for these files
5+
6+
# Match all files under the FMU_Interaction1 directory
7+
test/resources/FMU_Interaction1/** linguist-generated=true export-ignore -diff
8+
9+
# Also match the directory itself (some tools may reference the directory path)
10+
test/resources/FMU_Interaction1/ linguist-generated=true export-ignore -diff

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Set update schedule for GitHub Actions
2+
3+
version: 2
4+
updates:
5+
6+
- package-ecosystem: "github-actions"
7+
directory: "/"
8+
schedule:
9+
# Check for updates to GitHub Actions every week
10+
interval: "monthly"

.github/workflows/build.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Build Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- 'releases/**'
8+
pull_request:
9+
branches:
10+
- main
11+
- 'releases/**'
12+
13+
jobs:
14+
build:
15+
name: Build Docker image
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 60
18+
steps:
19+
- name: Check out the repo
20+
uses: actions/checkout@v5
21+
22+
- name: Extract metadata (tags, labels) for Docker
23+
id: meta
24+
uses: docker/metadata-action@v5
25+
with:
26+
# Use GitHub Container Registry (ghcr) so the image can be pushed from the workflow
27+
images: ghcr.io/OpenModelica/crossbuild
28+
29+
- name: Log in to GitHub Container Registry
30+
uses: docker/login-action@v2
31+
with:
32+
registry: ghcr.io
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Build and push Docker image
37+
id: build-image
38+
uses: docker/build-push-action@v6
39+
with:
40+
context: .
41+
file: ./Dockerfile
42+
push: true
43+
tags: ${{ steps.meta.outputs.tags }}
44+
45+
# Expose the image tag(s) produced by the metadata action as a job output so
46+
# downstream jobs can reference and pull the exact image.
47+
outputs:
48+
image: ${{ steps.meta.outputs.tags }}
49+
50+
51+
test-compile:
52+
name: Test Docker image across toolchains
53+
needs: build
54+
runs-on: ubuntu-latest
55+
strategy:
56+
fail-fast: false
57+
matrix:
58+
toolchain: ["i686-linux-gnu", "i686-w64-mingw32", "x86_64-linux-gnu", "x86_64-w64-mingw32"]
59+
timeout-minutes: 60
60+
steps:
61+
- name: Check out the repo
62+
uses: actions/checkout@v5
63+
64+
- name: Log in to GitHub Container Registry
65+
uses: docker/login-action@v2
66+
with:
67+
registry: ghcr.io
68+
username: ${{ github.actor }}
69+
password: ${{ secrets.GITHUB_TOKEN }}
70+
71+
- name: Pull image pushed by build job
72+
shell: bash
73+
run: |
74+
docker pull "${{ needs.build.outputs.image }}"
75+
76+
- name: Test cross-compilation for matrix toolchain
77+
shell: bash
78+
env:
79+
TOOLCHAIN: ${{ matrix.toolchain }}
80+
run: |
81+
# Strip potential .cmake suffix and construct toolchain file path inside container
82+
TOOLCHAIN_BASE="${TOOLCHAIN%%.cmake}"
83+
TOOLCHAIN_FILE="/work/toolchain/${TOOLCHAIN_BASE}.cmake"
84+
85+
docker run --rm \
86+
-v "${{ github.workspace }}":/work \
87+
-w /work \
88+
"${{ needs.build.outputs.image }}" \
89+
bash -lc "\
90+
cmake -S test/resources/FMU_Interaction1/sources \
91+
-B test/resources/FMU_Interaction1/sources/build_${TOOLCHAIN_BASE} \
92+
-DFMI_INTERFACE_HEADER_FILES_DIRECTORY=/work/test/resources/fmi \
93+
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} && \
94+
cmake --build test/resources/FMU_Interaction1/sources/build_${TOOLCHAIN_BASE} --target install && \
95+
test -f test/resources/FMU_Interaction1/binaries/linux64/Interaction1.so"

.github/workflows/publish.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Publish Docker Image
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
push_to_registry:
9+
name: Push Docker image to Docker Hub
10+
runs-on: ubuntu-latest
11+
timeout-minutes: 60
12+
steps:
13+
- name: Check out the repo
14+
uses: actions/checkout@v4
15+
16+
- name: Log in to Docker Hub
17+
uses: docker/login-action@v3
18+
with:
19+
username: ${{ secrets.DOCKERHUB_USERNAME }}
20+
password: ${{ secrets.DOCKERHUB_TOKEN }}
21+
22+
- name: Extract metadata (tags, labels) for Docker
23+
id: meta
24+
uses: docker/metadata-action@v5
25+
with:
26+
images: OpenModelica/crossbuild
27+
28+
- name: Build and push Docker image
29+
uses: docker/build-push-action@v6
30+
with:
31+
context: .
32+
file: ./Dockerfile
33+
push: true
34+
tags: ${{ steps.meta.outputs.tags }}
35+
labels: ${{ steps.meta.outputs.labels }}

.vscode/launch.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "(gdb) Launch omc",
9+
"type": "cppdbg",
10+
"request": "launch",
11+
"program": "/home/USER/workdir/OpenModelica/build_cmake/install_cmake/bin/omc",
12+
"args": [
13+
"genFMUResources.mos"
14+
],
15+
"stopAtEntry": false,
16+
"cwd": "${workspaceFolder}/test",
17+
"environment": [],
18+
"externalConsole": false,
19+
"MIMode": "gdb",
20+
"setupCommands": [
21+
{
22+
"description": "Enable pretty-printing for gdb",
23+
"text": "-enable-pretty-printing",
24+
"ignoreFailures": true
25+
},
26+
{
27+
"description": "Set Disassembly Flavor to Intel",
28+
"text": "-gdb-set disassembly-flavor intel",
29+
"ignoreFailures": true
30+
},
31+
{
32+
"description": "Ignore power-fail (SIGPWR) in GDB: don't stop or print; still pass to program",
33+
"text": "-interpreter-exec console \"handle SIGPWR nostop noprint pass\"",
34+
"ignoreFailures": true
35+
},
36+
{
37+
"description": "Ignore CPU time limit exceeded (SIGXCPU) in GDB: don't stop or print; still pass to program",
38+
"text": "-interpreter-exec console \"handle SIGXCPU nostop noprint pass\"",
39+
"ignoreFailures": true
40+
}
41+
]
42+
}
43+
]
44+
}

Dockerfile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
ARG DIST=ubuntu:noble
2+
3+
FROM ${DIST}
4+
5+
LABEL maintainer="AnHeuermann"
6+
LABEL description="Cross-compile C FMUs for Linux and Windows"
7+
8+
COPY toolchain/ /opt/cmake/toolchain/
9+
10+
# Install build dependencies
11+
RUN apt-get update && apt-get install -y --no-install-recommends \
12+
binutils-mingw-w64 \
13+
build-essential \
14+
ca-certificates \
15+
clang \
16+
cmake \
17+
curl \
18+
g++ \
19+
g++-multilib \
20+
gcc \
21+
gcc-multilib \
22+
git \
23+
make \
24+
mingw-w64 \
25+
pkg-config \
26+
unzip \
27+
&& rm -rf /var/lib/apt/lists/*

LICENSE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
The MIT License (MIT)
2+
=====================
3+
4+
Copyright © `2025` `Open Source Modelica Consortium (OSMC)`
5+
6+
Permission is hereby granted, free of charge, to any person
7+
obtaining a copy of this software and associated documentation
8+
files (the “Software”), to deal in the Software without
9+
restriction, including without limitation the rights to use,
10+
copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the
12+
Software is furnished to do so, subject to the following
13+
conditions:
14+
15+
The above copyright notice and this permission notice shall be
16+
included in all copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
19+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# OpenModelica Cross Compile Docker Image
2+
3+
[![Build Docker Image][gh-build-badge]][gh-build-workflow]
4+
[![Publish Docker Image][gh-publish-badge]][gh-publish-workflow]
5+
6+
The Docker image used to cross compile OpenModelica FMUs from Linux to target
7+
platforms and create multi-platform FMUs.
8+
9+
## Toolchains
10+
11+
| Toolchain file | OS | C | Note |
12+
|------------------------------------------|-----------------------|------------------------|---------|
13+
| [i686-linux-gnu][i686-linux-gnu] | x86-64 Linux 32-bit | gcc -m32 | |
14+
| [x86_64-linux-gnu][x86_64-linux-gnu] | x86-64 Linux 64-bit | gcc -m64 | |
15+
| [i686-w64-mingw32][i686-w64-mingw32] | x86-64 Windows 32-bit | i686-w64-mingw32-gcc | MINGW |
16+
| [x86_64-w64-mingw32][x86_64-w64-mingw32] | x86-64 Windows 64-bit | x86_64-w64-mingw32-gcc | MINGW |
17+
18+
## Versioning
19+
20+
The cross compilation image is versioned together with the version number of
21+
OpenModelica. So OpenModelica `v1.26.0` expects to use this image with tag
22+
`v1.26.0` for cross compiling Linux and Windows.
23+
24+
## Build
25+
26+
```bash
27+
export TAG=v1.26.0
28+
docker build --pull --no-cache --tag crossbuild:$TAG .
29+
```
30+
31+
## Example usage inside container
32+
33+
### Windows 32-bit
34+
35+
```bash
36+
cd path/to/FMU/sources/
37+
cmake -S . -B build_win32 -DCMAKE_TOOLCHAIN_FILE=/opt/cmake/toolchain/i686-w64-mingw32.cmake
38+
cmake --build build_win32 --target create_fmu
39+
```
40+
41+
### Windows 64-bit
42+
43+
```bash
44+
cd path/to/FMU/sources/
45+
cmake -S . -B build_win64 -DCMAKE_TOOLCHAIN_FILE=/opt/cmake/toolchain/x86_64-w64-mingw32.cmake
46+
cmake --build build_win64 --target create_fmu
47+
```
48+
49+
### Linux 32-bit
50+
51+
```bash
52+
cd path/to/FMU/sources/
53+
cmake -S . -B build_linux32 -DCMAKE_TOOLCHAIN_FILE=/opt/cmake/toolchain/i686-linux-gnu.cmake
54+
cmake --build build_linux32 --target create_fmu
55+
```
56+
57+
### Linux 64-bit
58+
59+
```bash
60+
cd path/to/FMU/sources/
61+
cmake -S . -B build_linux64 -DCMAKE_TOOLCHAIN_FILE=/opt/cmake/toolchain/x86_64-linux-gnu.cmake
62+
cmake --build build_linux64 --target create_fmu
63+
```
64+
65+
## Upload
66+
67+
The [publish.yml][gh-publish-file] workflow will build and
68+
upload the Docker image to
69+
[OpenModelica/crossbuild][docker-hub]
70+
for each release.
71+
72+
To do it manually run:
73+
74+
```bash
75+
export REGISTRY=openmodelica
76+
export TAG=v1.26.0
77+
docker login
78+
docker image tag crossbuild:$TAG $REGISTRY/crossbuild:$TAG
79+
docker push $REGISTRY/crossbuild:$TAG
80+
```
81+
82+
## License
83+
84+
The Dockerfile is licensed withthe MIT License, see
85+
[LICENSE.md][license].
86+
The C test files in test/resources are part of OpenModelica and licensed with
87+
PUBLIC LICENSE (OSMC-PL) VERSION 1.8, see
88+
[test/resources/OSMC-License.txt][osmc-license].
89+
90+
[gh-build-badge]: https://github.com/OpenModelica/crossbuild/actions/workflows/build.yml/badge.svg?branch=main
91+
[gh-build-workflow]: https://github.com/OpenModelica/crossbuild/actions/workflows/build.yml
92+
[gh-publish-badge]: https://github.com/OpenModelica/crossbuild/actions/workflows/publish.yml/badge.svg
93+
[gh-publish-workflow]: https://github.com/OpenModelica/crossbuild/actions/workflows/publish.yml
94+
[i686-linux-gnu]: ./toolchain/i686-linux-gnu.cmake
95+
[x86_64-linux-gnu]: ./toolchain/x86_64-linux-gnu.cmake
96+
[i686-w64-mingw32]: ./toolchain/i686-w64-mingw32.cmake
97+
[x86_64-w64-mingw32]: ./toolchain/x86_64-w64-mingw32.cmake
98+
[gh-publish-file]: ./.github/workflows/publish.yml
99+
[docker-hub]: https://hub.docker.com/repository/docker/OpenModelica/crossbuild
100+
[license]: ./LICENSE.md
101+
[osmc-license]: ./test/resources/OSMC-License.txt

test/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resources/*
2+
!resources/fmi/
3+
!resources/FMU_Interaction1/
4+
resources/FMU_Interaction1/binaries/
5+
resources/FMU_Interaction1/sources/build_*/
6+
!resources/OSMC-License.txt

0 commit comments

Comments
 (0)