Skip to content

Commit a987489

Browse files
committed
Switch MinGW building to CMake
Automatically grabs and compiles libpng, and avoids having hacky lines in our Makefile (the compiler specification *should* be orthogonal to the build target!) Also move the MinGW package install to the `install_deps.sh` script, to move logic off of the YAML.
1 parent e2a4908 commit a987489

10 files changed

Lines changed: 129 additions & 57 deletions

File tree

.github/scripts/install_deps.sh

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,34 @@
22
# This script requires `sh` instead of `bash` because the latter is not always installed on FreeBSD.
33
set -eu
44

5-
case "${1%-*}" in
5+
USAGE="Usage: $0 <os> [additional toolset]"
6+
7+
OS="${1:?$USAGE}"
8+
shift
9+
TOOLSET="${1-}"
10+
shift 2>/dev/null || : # That argument is optional.
11+
if [ $# -ne 0 ]; then
12+
echo >&2 "$USAGE"
13+
exit 1
14+
fi
15+
16+
case "${OS%-*}" in
617
ubuntu)
18+
pkgs=bison
19+
case "$TOOLSET" in
20+
mingw32)
21+
pkgs="$pkgs dpkg-dev mingw-w64-tools libz-mingw-w64-dev g++-mingw-w64-i686-win32"
22+
TOOLSET= ;;
23+
mingw64)
24+
pkgs="$pkgs dpkg-dev mingw-w64-tools libz-mingw-w64-dev g++-mingw-w64-x86-64-win32"
25+
TOOLSET= ;;
26+
'' | lcov)
27+
pkgs="$pkgs libpng-dev $TOOLSET"
28+
TOOLSET= ;;
29+
esac
730
sudo apt-get -qq update
8-
sudo apt-get install -yq bison libpng-dev pkg-config
31+
#shellcheck disable=SC2086 # (This word splitting is intentional.)
32+
sudo apt-get install -yq $pkgs
933
;;
1034
macos)
1135
# macOS bundles GNU Make 3.81, which doesn't support synced output.
@@ -30,6 +54,11 @@ case "${1%-*}" in
3054
;;
3155
esac
3256

57+
if [ -n "$TOOLSET" ]; then
58+
printf >&2 'Unknown toolset `%s` for OS `%s`\n' "$TOOLSET" "$OS"
59+
exit 1
60+
fi
61+
3362
echo "PATH=($PATH)" | sed 's/:/\n /g'
3463
bison --version
3564
make --version

.github/workflows/analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ jobs:
1010
- name: Checkout repo
1111
uses: actions/checkout@v4
1212
- name: Install deps
13-
shell: bash
1413
run: |
15-
./.github/scripts/install_deps.sh ubuntu-latest
14+
bash .github/scripts/install_deps.sh ubuntu-latest
1615
- name: Static analysis
17-
run: | # Silence warnings with too many false positives (https://stackoverflow.com/a/73913076)
16+
run:
17+
| # Silence warnings with too many false positives (https://stackoverflow.com/a/73913076)
1818
make -kj CXX=g++-14 CXXFLAGS="-fanalyzer -fanalyzer-verbosity=0 -Wno-analyzer-use-of-uninitialized-value -DNDEBUG" Q=

.github/workflows/coverage.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@ on:
55

66
jobs:
77
coverage:
8-
runs-on: ubuntu-24.04
8+
runs-on: ubuntu-latest
99
steps:
1010
- name: Checkout repo
1111
uses: actions/checkout@v4
1212
- name: Install deps
13-
shell: bash
14-
run: |
15-
./.github/scripts/install_deps.sh ubuntu
16-
- name: Install LCOV
1713
run: |
18-
sudo apt-get install lcov
14+
bash .github/scripts/install_deps.sh ubuntu-latest lcov
1915
- name: Install test dependency dependencies
2016
shell: bash
2117
run: |

.github/workflows/testing.yml

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ jobs:
3535
- name: Checkout repo
3636
uses: actions/checkout@v4
3737
- name: Install deps
38-
shell: bash
3938
run: |
40-
./.github/scripts/install_deps.sh ${{ matrix.os }}
39+
bash ./.github/scripts/install_deps.sh ${{ matrix.os }}
4140
- name: Build & install using Make
4241
if: matrix.buildsys == 'make'
4342
run: |
@@ -175,7 +174,7 @@ jobs:
175174
- name: Build Windows binaries
176175
shell: bash
177176
run: | # ASan seems to be broken on Windows, so we disable it.
178-
cmake -S . -B build --preset develop-msvc${{ matrix.bits }} -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}" -DSANITIZERS=OFF
177+
cmake -S . -B build --preset develop-msvc${{ matrix.bits }} -DSANITIZERS=OFF -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}"
179178
cmake --build build
180179
- name: Package binaries
181180
shell: bash
@@ -222,44 +221,29 @@ jobs:
222221
bits: [32, 64]
223222
include:
224223
- bits: 32
225-
arch: i686
226224
triplet: i686-w64-mingw32
227225
- bits: 64
228-
arch: x86-64
229226
triplet: x86_64-w64-mingw32
230227
fail-fast: false
231-
runs-on: ubuntu-22.04
232-
env:
233-
DIST_DIR: win${{ matrix.bits }}
228+
runs-on: ubuntu-latest
234229
steps:
235230
- name: Checkout repo
236231
uses: actions/checkout@v4
237232
- name: Install deps
238-
shell: bash
239233
run: |
240-
./.github/scripts/install_deps.sh ubuntu
241-
- name: Install MinGW
242-
run: | # dpkg-dev is apparently required for pkg-config for cross-building
243-
sudo apt-get install g++-mingw-w64-${{ matrix.arch }}-win32 mingw-w64-tools libz-mingw-w64-dev dpkg-dev
244-
- name: Install libpng dev headers for MinGW
245-
run: |
246-
./.github/scripts/mingw-w64-libpng-dev.sh ${{ matrix.triplet }}
234+
bash .github/scripts/install_deps.sh ubuntu mingw${{ matrix.bits }}
247235
- name: Cross-build Windows binaries
248-
run: |
249-
make mingw${{ matrix.bits }} -kj Q=
236+
run: | # ASan and UBSan are not supported on MinGW.
237+
cmake -B build --preset develop -DSANITIZERS=OFF -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw${{ matrix.bits }}.cmake -DFETCHCONTENT_BASE_DIR="${{ env.DEPS_ROOT_DIR }}"
238+
cmake --build build
250239
- name: Package binaries
251-
run: | # DLL dependencies can be figured out using e.g. Dependency Walker or objdump -p
252-
mkdir bins
253-
mv -v rgb{asm,link,fix,gfx}.exe bins/
254-
cp -v /usr/${{ matrix.triplet }}/lib/zlib1.dll bins
255-
cp -v /usr/${{ matrix.triplet }}/bin/libpng16-16.dll bins
256-
cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/lib{ssp-0,stdc++-6}.dll bins
257-
[ "${{ matrix.bits }}" -ne 32 ] || cp -v /usr/lib/gcc/${{ matrix.triplet }}/10-win32/libgcc_s_dw2-1.dll bins
240+
run: |
241+
cmake --install build --prefix . --component runtime --verbose
258242
- name: Upload Windows binaries
259243
uses: actions/upload-artifact@v4
260244
with:
261245
name: rgbds-canary-mingw-win${{ matrix.bits }}
262-
path: bins
246+
path: bin
263247
- name: Upload Windows test binaries
264248
uses: actions/upload-artifact@v4
265249
with:

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ CMakeCache.txt
1414
CMakeFiles/
1515
cmake_install.cmake
1616
CMakeUserPresets.json
17-
build/
17+
build*/
1818
*.dSYM/
1919
callgrind.out.*

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ endforeach()
182182
# We only specify here the package-agnostic options;
183183
# the rest is rather convention from our side,
184184
# and thus more appropriate for presets or CLI flags.
185+
include(CPackComponent)
185186
## CPACK_PACKAGE_NAME: copied from `project()`
186187
set(CPACK_PACKAGE_VENDOR "GBDev")
187188
set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") # The individual components are defined implicitly.
@@ -198,4 +199,11 @@ set(CPACK_THREADS 0) # Use all available CPU cores.
198199
# Convert our gitignore into regex ignores, for source tarballs.
199200
# TODO
200201
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) # TODO: source packages don't want this, what about binary ones?
202+
203+
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};runtime;/")
204+
#set(CPACK_ZIP_COMPONENT_INSTALL ON)
205+
#cpack_add_component(runtime)
206+
#cpack_add_component(man)
207+
#set(CPACK_COMPONENTS_ALL "runtime;man")
208+
201209
include(CPack)

Makefile

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -256,22 +256,6 @@ iwyu:
256256
CXX="include-what-you-use" \
257257
REALCXXFLAGS="-std=c++20 -I include"
258258

259-
# Targets for the project maintainer to easily create Windows exes.
260-
# This is not for Windows users!
261-
# If you're building on Windows with Cygwin or MinGW, just follow the Unix
262-
# install instructions instead.
263-
264-
mingw32:
265-
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
266-
CXX=i686-w64-mingw32-g++ \
267-
CXXFLAGS="-O3 -flto -DNDEBUG -static-libgcc -static-libstdc++" \
268-
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/i686-w64-mingw32 pkg-config"
269-
270-
mingw64:
271-
$Q${MAKE} all test/gfx/randtilegen test/gfx/rgbgfx_test \
272-
CXX=x86_64-w64-mingw32-g++ \
273-
PKG_CONFIG="PKG_CONFIG_SYSROOT_DIR=/usr/x86_64-w64-mingw32 pkg-config"
274-
275259
wine-shim:
276260
$Qecho '#!/usr/bin/env bash' > rgbshim.sh
277261
$Qecho 'WINEDEBUG=-all wine $$0.exe "$${@:1}"' >> rgbshim.sh

cmake/toolchain-mingw32.cmake

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# From https://www.mingw-w64.org/build-systems/cmake/
2+
3+
set(CMAKE_SYSTEM_NAME Windows)
4+
set(CMAKE_SYSTEM_PROCESSOR i686)
5+
6+
# specify the cross compiler
7+
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
8+
set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
9+
set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
10+
11+
# where is the target environment
12+
set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
13+
14+
# search for programs in the build host directories
15+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
16+
# for libraries and headers in the target directories
17+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
18+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
19+
20+
# TODO: are those *required*?
21+
# -static-libgcc -static-libstdc++
22+
23+
# CMake determines how to examine dependencies based on the *host* system, leading to
24+
# a `file unknown error` unless the target platform is explicitly specified.
25+
set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM "windows+pe")

cmake/toolchain-mingw64.cmake

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# From https://www.mingw-w64.org/build-systems/cmake/
2+
3+
set(CMAKE_SYSTEM_NAME Windows)
4+
set(CMAKE_SYSTEM_PROCESSOR x86_64)
5+
6+
# specify the cross compiler
7+
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
8+
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
9+
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
10+
11+
# where is the target environment
12+
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
13+
14+
# search for programs in the build host directories
15+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
16+
# for libraries and headers in the target directories
17+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
18+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
19+
20+
# CMake determines how to examine dependencies based on the *host* system, leading to
21+
# a `file unknown error` unless the target platform is explicitly specified.
22+
set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM "windows+pe")

src/CMakeLists.txt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,31 @@ set_target_properties(rgbasm rgblink rgbfix rgbgfx PROPERTIES
109109
RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_SOURCE_DIR}>)
110110
target_link_libraries(rgbgfx PRIVATE PNG::PNG)
111111

112-
# TARGET_RUNTIME_DLLS was introduced in CMake 3.21.
113-
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.21")
114-
install(FILES "$<TARGET_RUNTIME_DLLS:rgbgfx>" DESTINATION bin COMPONENT runtime)
112+
# This is a modified version of the install code generated by
113+
# `install(TARGETS rgbgfx RUNTIME_DEPENDENCIES)`.
114+
# Unfortunately, that `install()` is outright not supported when cross-compiling,
115+
# and working around that has CMake fail to resolve the DLL locations with MinGW,
116+
# due to not specifying any `DIRECTORIES` and the system search path being ineffective.
117+
get_target_property(rgbgfx_NAME rgbgfx OUTPUT_NAME)
118+
if(rgbgfx_NAME STREQUAL "rgbgfx_NAME-NOTFOUND")
119+
set(rgbgfx_NAME rgbgfx)
115120
endif()
121+
get_target_property(rgbgfx_OUTDIR rgbgfx RUNTIME_OUTPUT_DIRECTORY)
122+
# TODO: we've only tested this with minGW, but it may not work with other uses of the variable.
123+
# Anyonw who knows how to handle this better, feel free to submit a patch!
124+
set(extra_search_dir "")
125+
if(DEFINED CMAKE_FIND_ROOT_PATH)
126+
set(extra_search_dir "\"${CMAKE_FIND_ROOT_PATH}/bin\"")
127+
endif()
128+
install(CODE "\
129+
file(GET_RUNTIME_DEPENDENCIES
130+
RESOLVED_DEPENDENCIES_VAR rgbgfx_deps
131+
EXECUTABLES \"${rgbgfx_OUTDIR}/${rgbgfx_NAME}${CMAKE_EXECUTABLE_SUFFIX}\"
132+
DIRECTORIES ${extra_search_dir} \"$<TARGET_FILE_DIR:ZLIB::ZLIB>\" \"$<TARGET_FILE_DIR:PNG::PNG>\"
133+
PRE_EXCLUDE_REGEXES \"^kernel32\\\\.dll$\" \"^msvcrt\\\\.dll\" \"^api-ms-win-.*\\\\.dll$\"
134+
)
135+
foreach(rgbgfx_dep IN LISTS rgbgfx_deps)
136+
file(INSTALL DESTINATION \"$<INSTALL_PREFIX>/${CMAKE_INSTALL_BINDIR}\" TYPE SHARED_LIBRARY FILES \${rgbgfx_dep}
137+
FOLLOW_SYMLINK_CHAIN)
138+
endforeach()"
139+
COMPONENT runtime)

0 commit comments

Comments
 (0)