Fix MSVC tests + add mingw support (#65)

* Include windows.h before imagehlp.h

This fixes a long list of undefined type errors when building with mingw (on Linux).

* Remove matherr function

This function is provided by the c library.

* Use GetFileAttributesA to filter files

dirent->d_type is not available in all implementation.
Posix only mandates the fields d_name and d_ino.

* Use FindOpenGL.cmake to get the opengl library

Mingw has no libGL.so, but has libopengl32.a. Use the CMake module to abstract this away.

* harness needs to link to dbghelp

This fixes undefined references to:
__imp_SymInitialize, __imp_SymGetModuleBase64,
__imp_SymFunctionTableAccess64, __imp_StackWalk64 and __imp_SymCleanup.

* Don't add -g to compile options.

CMAKE_BUILD_TYPE=(Debug|RelWithDebInfo) takes care of this

* Set test file name before running tests in suite.

This causes the message to contain the correct file name where an assertion failed/succeeded.

* Use wrapper to sleep for number on seconds in tests

sleep on Windows expects milliseconds.
sleep on Posix expects seconds.

* Use char* instead of void*

MSVC complained that it couldn't determine the size of void

* Don't test state of removed resource after deletion when building Debug

When building in Debug configuration, the compiler may mark deleted memory ranges with some value.
Therefore, we cannot expect deleted memory to remain unchanged.
(MSVC in Debug mode does this)

* Use helper to get system temporary folder.

Using /tmp on Windows failed hard.

* Header containing sse3 intrinsics is pmmintrin.h

See https://github.com/recp/cglm/pull/234

* Add errno.h include for ENOTSUP

* Fix test_utility_GetALineWithNoPossibleService: avoid strcpy of uninitialized s

Found by running the tests with CMAKE_BUILD_TYPE=Debug with MSVC

* Add mingw@Linux and mingw@Windows jobs to github workflow

* Rename build-windows.ps1 script to build-msvc.ps1.

Also bump the versions of SDL2 and ninja, used in this script.

* Run tests in github jobs running on Windows

Co-authored-by: Dethrace Engineering Laboratory <78985374+dethrace-labs@users.noreply.github.com>
This commit is contained in:
Anonymous Maarten 2022-01-20 01:17:10 +01:00 committed by GitHub
parent e8f3b6f95b
commit ee032df264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 210 additions and 38 deletions

55
.github/scripts/build-mingw.sh vendored Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
set -e
if test -z "$MSYSTEM"; then
# mingw@Linux
if test $MATRIX_PLATFORM = "x86"; then
sdl_path="i686-w64-mingw32"
apt_packages="gcc-mingw-w64-i686 g++-mingw-w64-i686"
export CC=i686-w64-mingw32-gcc-win32
export CXX=i686-w64-mingw32-g++-win32
else
sdl_path="x86_64-w64-mingw32"
apt_packages="gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64"
export CC=x86_64-w64-mingw32-gcc-win32
export CXX=x86_64-w64-mingw32-g++-win32
fi
# install deps
sudo apt-get update -qq > /dev/null
sudo apt-get install -qq -y $apt_packages > /dev/null
SDL2_VERSION=2.0.18
wget -nv https://www.libsdl.org/release/SDL2-devel-$SDL2_VERSION-mingw.tar.gz -O /tmp/SDL2-devel-$SDL2_VERSION-mingw.tar.gz
tar -xf /tmp/SDL2-devel-$SDL2_VERSION-mingw.tar.gz -C /tmp
$CC --verbose
$CXX --verbose
# build
cmake -DCMAKE_SYSTEM_NAME=Windows -DSDL2_ROOT_DIR=/tmp/SDL2-$SDL2_VERSION/$sdl_path -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTS=ON -B build -DCMAKE_EXE_LINKER_FLAGS_INIT=-lssp
cmake --build build -- -j 4
# package artifact
tar -czvf mingw-$MATRIX_PLATFORM.tar.gz -C build dethrace.exe -C /tmp/SDL2-$SDL2_VERSION/$sdl_path/bin SDL2.dll
else
# mingw@Windows
if test $MATRIX_PLATFORM = "x86"; then
bin_path="/mingw32/bin"
pacman_packages="mingw-w64-i686-cmake mingw-w64-i686-make mingw-w64-i686-gcc mingw-w64-i686-SDL2"
else
bin_path="/mingw64/bin"
pacman_packages="mingw-w64-x86_64-cmake mingw-w64-x86_64-make mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2"
fi
# install deps
pacman -S --noconfirm $pacman_packages
# build
cmake -G "MinGW Makefiles" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTS=ON -B build
cmake --build build -- -j 4
# package artifact
tar -czvf mingw-$MATRIX_PLATFORM.tar.gz -C build dethrace.exe -C $bin_path SDL2.dll
fi

View File

@ -4,16 +4,22 @@ if ($($Env:MATRIX_PLATFORM) -eq "x86") {
$sdl_path = "x64"
}
$sdl2_version = "2.0.18"
$ninja_version = "1.10.2"
# install deps
Invoke-WebRequest -Uri https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip -OutFile $Env:TEMP\SDL2-devel.zip
Invoke-WebRequest -Uri https://github.com/ninja-build/ninja/releases/download/v1.10.1/ninja-win.zip -OutFile $Env:TEMP\ninja-win.zip
Invoke-WebRequest -Uri https://www.libsdl.org/release/SDL2-devel-$sdl2_version-VC.zip -OutFile $Env:TEMP\SDL2-devel.zip
Invoke-WebRequest -Uri https://github.com/ninja-build/ninja/releases/download/v$ninja_version/ninja-win.zip -OutFile $Env:TEMP\ninja-win.zip
Expand-Archive $Env:TEMP\SDL2-devel.zip -DestinationPath $Env:TEMP
Expand-Archive $Env:TEMP\ninja-win.zip -DestinationPath $Env:TEMP\ninja
echo "$Env:TEMP\ninja" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# build
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSDL2=ON "-DSDL2_ROOT_DIR=$($Env:TEMP)\SDL2-2.0.12" -B build
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTS=ON "-DSDL2_ROOT_DIR=$($Env:TEMP)\SDL2-$sdl2_version" -B build
cmake --build build --config RelWithDebInfo
# copy SDL2.dll to build folder, so tests can run
cp $Env:TEMP\SDL2-$sdl2_version\lib\$sdl_path\SDL2.dll build
# package artifact
7z a windows-$Env:MATRIX_PLATFORM.zip .\build\dethrace.exe .\build\dethrace.pdb $Env:TEMP\SDL2-2.0.12\lib\$sdl_path\SDL2.dll
7z a windows-$Env:MATRIX_PLATFORM.zip .\build\dethrace.exe .\build\dethrace.pdb $Env:TEMP\SDL2-$sdl2_version\lib\$sdl_path\SDL2.dll

View File

@ -68,9 +68,13 @@ jobs:
arch: ${{ matrix.platform }}
- name: Build
run: |
.github/scripts/build-windows.ps1
.github/scripts/build-msvc.ps1
env:
MATRIX_PLATFORM: ${{ matrix.platform }}
- name: Test
run: |
cd build
ctest --verbose -C RelWithDebInfo
- name: Upload artifact
if: startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v1
@ -78,6 +82,52 @@ jobs:
name: artifacts
path: windows-${{ matrix.platform }}.zip
build-mingw:
runs-on: 'ubuntu-latest'
strategy:
matrix:
platform: [x86, amd64]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Build
run: |
.github/scripts/build-mingw.sh
env:
MATRIX_PLATFORM: ${{ matrix.platform }}
build-mingw-msys2:
runs-on: 'windows-latest'
strategy:
matrix:
include:
- platform: x86
msystem: mingw32
- platform: amd64
msystem: mingw64
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
- name: Build
run: |
.github/scripts/build-mingw.sh
env:
MATRIX_PLATFORM: ${{ matrix.platform }}
- name: Test
run: |
cd build
ctest --verbose
create-release:
needs: [build-linux, build-macos, build-windows]
@ -140,4 +190,4 @@ jobs:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: ./artifacts/windows-amd64.zip
asset_name: dethrace-${{ steps.get_version.outputs.VERSION }}-windows-amd64.zip
asset_content_type: application/octet-stream
asset_content_type: application/octet-stream

View File

@ -34,7 +34,7 @@
#endif
#if defined(__SSE3__)
# include <x86intrin.h>
# include <pmmintrin.h>
# ifndef CGLM_SIMD_x86
# define CGLM_SIMD_x86
# endif

View File

@ -163,7 +163,13 @@ if(NOT MSVC)
target_link_libraries(dethrace PRIVATE "-framework OpenGL")
target_link_options(dethrace PRIVATE -fno-pie)
else()
target_link_libraries(dethrace PRIVATE GL)
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL REQUIRED)
if(TARGET OpenGL::OpenGL)
target_link_libraries(dethrace PRIVATE OpenGL::OpenGL)
else()
target_link_libraries(dethrace PRIVATE OpenGL::GL)
endif()
endif()
else()
target_link_libraries(dethrace PRIVATE dbghelp)

View File

@ -231,6 +231,7 @@ char* GetALineWithNoPossibleService(FILE* pF, /*unsigned*/ char* pS) {
do {
result = fgets(s, 256, pF);
if (!result) {
s[0] = '\0';
break;
}
if (s[0] == '@') {
@ -274,7 +275,7 @@ char* GetALineWithNoPossibleService(FILE* pF, /*unsigned*/ char* pS) {
result[len - 2] = 0;
}
}
strcpy((char*)pS, s);
strcpy(pS, s);
len = strlen(s);
for (i = 0; i < len; i++) {
if (pS[i] >= 0xE0u) {

View File

@ -15,6 +15,7 @@
#include "utility.h"
#include "watcom_functions.h"
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -510,8 +511,12 @@ void PDForEveryFile(char* pThe_path, void (*pAction_routine)(char*)) {
d = opendir(pThe_path);
if (d) {
while ((entry = readdir(d)) != NULL) {
// only files, and only files that dont start with '.'
// only files, and only files that don't start with '.'
#ifdef _WIN32
if ((GetFileAttributesA(pThe_path) & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
#else
if (entry->d_type == DT_REG && entry->d_name[0] != '.') {
#endif
PathCat(found_path, pThe_path, entry->d_name);
pAction_routine(found_path);
}
@ -722,12 +727,6 @@ void PDEndItAllAndReRunTheBastard() {
NOT_IMPLEMENTED();
}
// IDA: int __usercall matherr@<EAX>(exception *err@<EAX>)
int matherr(struct exception_* err) {
LOG_TRACE("(%p)", err);
NOT_IMPLEMENTED();
}
// IDA: int __usercall LoopLimitTooLow@<EAX>(tU32 limit@<EAX>)
int LoopLimitTooLow(tU32 limit) {
clock_t start;

View File

@ -11,9 +11,12 @@ target_include_directories(harness
target_link_libraries(harness PRIVATE miniposix brender SDL2::SDL2 glad s3 cglm_headers)
if(WIN32)
target_link_libraries(harness PRIVATE dbghelp)
endif()
if(NOT MSVC)
target_compile_options(harness PRIVATE
-g
-Wall
-Wextra
-Werror
@ -46,4 +49,4 @@ target_sources(harness PRIVATE
platforms/sdl_gl.h
platforms/null.h
stack_trace_handler.h
)
)

View File

@ -12,8 +12,8 @@
#include <unistd.h>
#ifdef _WIN32
#include <imagehlp.h>
#include <windows.h>
#include <imagehlp.h>
#ifdef _WIN64
#define Esp Rsp
#define Eip Rip
@ -335,4 +335,4 @@ void install_signal_handler(char* program_name) {
}
}
}
#endif
#endif

View File

@ -51,7 +51,8 @@ void test_actsupt_BrActorAdd() {
}
void test_actsupt_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_actsupt_BrActorAllocateAndFree);
RUN_TEST(test_actsupt_BrActorAllocateAndFreeChild);
RUN_TEST(test_actsupt_BrActorAdd);
}
}

View File

@ -352,6 +352,7 @@ static void test_brlists_BrSimpleRemove() {
}
void test_brlists_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_brlists_BrNewList);
RUN_TEST(test_brlists_BrAddHead);
RUN_TEST(test_brlists_BrAddTail);

View File

@ -13,5 +13,6 @@ void test_datafile_ReadBinary() {
}
void test_datafile_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_datafile_ReadBinary);
}
}

View File

@ -8,5 +8,6 @@ void test_fwsetup_BrFwBegin() {
}
void test_fwsetup_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_fwsetup_BrFwBegin);
}
}

View File

@ -40,5 +40,6 @@ void test_genclip_PixelmapRectangleClip() {
}
void test_genclip_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_genclip_PixelmapRectangleClip);
}
}

View File

@ -35,7 +35,8 @@ void test_pattern_BrNamePatternMatch_QuestionMark() {
}
void test_pattern_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_pattern_BrNamePatternMatch);
RUN_TEST(test_pattern_BrNamePatternMatch_Star);
RUN_TEST(test_pattern_BrNamePatternMatch_QuestionMark);
}
}

View File

@ -15,5 +15,6 @@ void test_pmfile_BrPixelmapLoad() {
}
void test_pmfile_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_pmfile_BrPixelmapLoad);
}
}

View File

@ -489,6 +489,7 @@ static void test_register_BrRegistryEnum() {
}
void test_register_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_register_BrRegistryNew);
RUN_TEST(test_register_BrRegistryAdd_BrRegistryRemove);
RUN_TEST(test_register_offsets);

View File

@ -34,5 +34,6 @@ void test_regsupt_BrMaterialEnum() {
}
void test_regsupt_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_regsupt_BrMaterialEnum);
}
}

View File

@ -43,7 +43,7 @@ void test_resource_BrResFree2() {
child = BrResAllocate(NULL, sizeof(br_file), BR_MEMORY_FILE);
child->raw_file = (void*)0x1;
TEST_ASSERT_NOT_NULL(child);
resource_header* childhdr = (void*)child - sizeof(resource_header);
resource_header* childhdr = (char*)child - sizeof(resource_header);
if (childhdr->magic_num != 0xDEADBEEF) {
LOG_PANIC("Bad resource header at %p. Was %X", childhdr, ((resource_header*)childhdr)->magic_num);
}
@ -62,17 +62,21 @@ void test_resource_BrResFree_Child() {
header = (resource_header*)(((char*)child) - sizeof(resource_header));
TEST_ASSERT_EQUAL_INT(0xDEADBEEF, header->magic_num);
BrResFree(r);
#ifndef _DEBUG
// when the res is free'd, magic_num is set to 1. We make sure the child was free'd when the parent was
TEST_ASSERT_EQUAL_INT(1, header->magic_num);
// And the parent should have the child unlinked from its list of children
header = (resource_header*)(((char*)r) - sizeof(resource_header));
TEST_ASSERT_NULL(header->children.head);
#endif
}
void test_resource_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_resource_BrResAllocate);
RUN_TEST(test_resource_BrResFree);
RUN_TEST(test_resource_BrResFree2);
RUN_TEST(test_resource_BrResFree_Child);
}
}

View File

@ -62,7 +62,8 @@ void test_v1dbfile_BrMaterialLoad() {
}
void test_v1dbfile_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_v1dbfile_BrModelLoad);
RUN_TEST(test_v1dbfile_BrActorLoad);
RUN_TEST(test_v1dbfile_BrMaterialLoad);
}
}

View File

@ -17,7 +17,13 @@ if(NOT MSVC)
if(APPLE)
target_link_libraries(dethrace_test PRIVATE "-framework OpenGL")
else()
target_link_libraries(dethrace_test PRIVATE GL)
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL REQUIRED)
if(TARGET OpenGL::OpenGL)
target_link_libraries(dethrace_test PRIVATE OpenGL::OpenGL)
else()
target_link_libraries(dethrace_test PRIVATE OpenGL::GL)
endif()
endif()
else()
target_compile_definitions(dethrace_test PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED)

View File

@ -24,7 +24,7 @@ void test_controls_CheckKevKeys() {
gKeys_pressed = 0;
result = KevKeyService();
}
sleep(2);
sleep_s(2);
gKeys_pressed = 0;
CheckKevKeys();
@ -34,5 +34,6 @@ void test_controls_CheckKevKeys() {
}
void test_controls_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_controls_CheckKevKeys);
}

View File

@ -7,4 +7,5 @@
#include "pd/sys.h"
void test_dossys_suite() {
UnitySetTestFile(__FILE__);
}

View File

@ -10,5 +10,6 @@ void test_errors_FatalError() {
}
void test_errors_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_errors_FatalError);
}

View File

@ -33,5 +33,6 @@ void test_flicplay_playflic() {
}
void test_flicplay_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_flicplay_playflic);
}
}

View File

@ -12,5 +12,6 @@ void test_graphics_loadfont() {
}
void test_graphics_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_graphics_loadfont);
}
}

View File

@ -9,5 +9,6 @@ void test_init_AllocateCamera() {
}
void test_init_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_init_AllocateCamera);
}
}

View File

@ -15,7 +15,7 @@ void test_input_KevKeyService() {
gKeys_pressed = 0;
result = KevKeyService();
}
sleep(2);
sleep_s(2);
gKeys_pressed = 0;
result = KevKeyService();
@ -24,5 +24,6 @@ void test_input_KevKeyService() {
}
void test_input_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_input_KevKeyService);
}

View File

@ -231,6 +231,7 @@ void test_loading_LoadOpponentCar() {
}
void test_loading_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_loading_GetCDPathFromPathsTxtFile);
RUN_TEST(test_loading_OldDRfopen);
RUN_TEST(test_loading_LoadGeneralParameters);

View File

@ -14,5 +14,6 @@ void test_loading_powerups() {
}
void test_powerup_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_loading_powerups);
}

View File

@ -45,12 +45,23 @@ void test_utility_StripCR() {
TEST_ASSERT_EQUAL_STRING("line", buf);
}
static void get_system_temp_folder(char *buffer, size_t bufferSize) {
#ifdef _WIN32
GetTempPathA(bufferSize, buffer);
#else
strcpy(buffer, "/tmp/");
#endif
}
void test_utility_GetALineWithNoPossibleService() {
FILE* file = fopen("/tmp/testfile", "wt");
char tmpPath[256];
get_system_temp_folder(tmpPath, sizeof(tmpPath));
strcat(tmpPath, "testfile");
FILE* file = fopen(tmpPath, "wt");
fprintf(file, "hello world\r\n space_prefixed\r\n\r\n\ttab_prefixed\r\n$ignored_prefix\r\nlast_line");
fclose(file);
file = fopen("/tmp/testfile", "rt");
file = fopen(tmpPath, "rt");
char s[256];
char* result = GetALineWithNoPossibleService(file, s);
@ -71,6 +82,8 @@ void test_utility_GetALineWithNoPossibleService() {
result = GetALineWithNoPossibleService(file, s);
TEST_ASSERT_NULL(result);
fclose(file);
}
void test_utility_PathCat() {
@ -90,6 +103,7 @@ void test_utility_IRandomBetween() {
}
void test_utility_suite() {
UnitySetTestFile(__FILE__);
RUN_TEST(test_utility_EncodeLinex);
RUN_TEST(test_utility_DecodeLine2);
RUN_TEST(test_utility_EncodeLine2);

View File

@ -103,6 +103,14 @@ int has_data_directory() {
return root_dir != NULL;
}
void sleep_s(int sec) {
#ifdef _WIN32
Sleep(1000 * sec);
#else
sleep(sec);
#endif
}
int main(int argc, char** argv) {
UNITY_BEGIN();

View File

@ -5,6 +5,7 @@
#include "harness/trace.h"
extern int has_data_directory();
extern void sleep_s(int sec);
#define REQUIRES_DATA_DIRECTORY() \
if (!has_data_directory()) \