Windows/Ninja/CMake Build for the C API

Hi there,

I'm trying to build via the Git Bash (an msys2 terminal) on my Windows 10 machine with the ARM compiler installed (arm-none-eabi). I'm using:

  • arm-none-eabi-gcc.exe et al (Arm GNU Toolchain 12.2.MPACBTI-Rel1 (Build arm-12-mpacbti.34)) 12.2.1 20230214 (in my $PATH variable)
  • cmake version 3.20.1
  • ninja version 1.10.2
  • Playdate SDK 2.0.0
  • PLAYDATE_SDK_PATH set

I built with this, in the "Examples/Sprite Game/build" directory (which was empty):

build$ cmake -DCMAKE_TOOLCHAIN_FILE=$PLAYDATE_SDK_PATH/C_API/buildsupport/arm.cmake -GNinja -B. ..

This gives a "Platform not supported!" message from buildsupport/playdate_game.cmake:68. That's an if-else statement that checks for platform variables (specifically the cmake variables MSVC, APPLE and UNIX). I'm on none of those, at least we know from the error message that MSVC isn't true, so I added a case with CYGWIN and copied the body of the UNIX block, as in:

	elseif(UNIX)
		add_custom_command(
			TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
			COMMAND ${CMAKE_COMMAND} -E copy
			${CMAKE_CURRENT_BINARY_DIR}/lib${PLAYDATE_GAME_NAME}.so
			${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.so)
    elseif(CYGWIN)
		add_custom_command(
			TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
			COMMAND ${CMAKE_COMMAND} -E copy
			${CMAKE_CURRENT_BINARY_DIR}/lib${PLAYDATE_GAME_NAME}.so
			${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.so)
	else()
		message(FATAL_ERROR "Platform not supported!")
	endif()

This makes it generate fine with the cmake command above, and running ninja results in this:

$ ninja
[1/4] Building C object CMakeFiles/SpriteGame_DEVICE.dir/main.c.obj
[2/4] Building C object CMakeFiles/SpriteGame_DEVICE.dir/C_/PlaydateSDK/C_API/buildsupport/setup.c.obj
[3/4] Building C object CMakeFiles/SpriteGame_DEVICE.dir/game.c.obj
[4/4] Linking C executable SpriteGame_DEVICE.elf
c:/progra~2/armgnu~1/12977f~1.2mp/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: SpriteGame_DEVICE.elf has a LOAD segment with RWX permissions

I figure it's a warning, so probably not a dealbreaker. And besides there's a SpriteGame.pdx folder that's been created. Clicking File -> Open in the simulator and selecting the pdx folder. It fails to boot, and there's a message in red saying "Update error: no such function 'update'".

So okay, I tried to use the objdump and readelf utilities in the ARM toolchain I installed to inspect the pdex.bin file created, but while they identify an elf header in the file, I cannot read the symbol table with them. In the build folder, there's a .elf file, and using readelf on that reveals that there is an update function in that. The ARM toolchain doesn't support __declspec(dllexport), but I assume this isn't needed with their toolchain.

Any help would be appreciated, I don't feel like my tools are too outlandish here. I saw someone else got VS Code working, which is cool but they seem to have patched a different set of files in the SDK than me, and I don't like the VS Code cmake plugin.

I'm not familiar with Ninja, but what I noticed here is you're building an .so file; but you're using the Windows Simulator which will only load a .dll file. If you look at the MSVC section you'll see it outputs .dll files, .so are only loaded on Linux. Second, when building for arm, it will output an .elf file and this code path isn't hit. Hope this gets you going down the right track.

Instead of using the msys2 terminal, I use the x64 Native Tools Command Prompt for VS 2022, and I'm able to build games with C API and Ninja. No patched files needed, only those included in the SDK.

1 Like

yeah i also think the problem is indeed using msys2 terminal . I also use visual studio developper prompt from vs 2022 to build my c api games

Yeah, there's a bunch of special cases inside if (MSVC) checks in the CMake files, but I'd rather not depend on the windows developer tools. I assume those checks are making CMake not do anything for my environment (which appears to set CYGWIN, but not APPLE, or UNIX or MSVC). Realistically, I have the right compiler toolchain and all that, seems this should be very possible.

So I went in and reinstalled visual studio 2022, opened the x64 Native Tools Command Prompt for VS 2022, and it actually produces the exact same result for me. Output below (exchanging the actual playdate SDK path for C:\PlaydateSDK for brevity):

C:\PlaydateSDK\C_API\Examples\Sprite Game>rmdir /S build
build, Are you sure (Y/N)? Y

C:\PlaydateSDK\C_API\Examples\Sprite Game>cmake -DCMAKE_TOOLCHAIN_FILE=%PLAYDATE_SDK_PATH%\C_API\buildsupport\arm.cmake -GNinja -Bbuild .
-- arm.cmake loaded
-- arm.cmake loaded
-- The C compiler identification is GNU 12.2.1
-- The ASM compiler identification is GNU
-- Found assembler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/12.2 mpacbti-rel1/bin/arm-none-eabi-gcc.exe
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/12.2 mpacbti-rel1/bin/arm-none-eabi-gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- SDK Path: C:/PlaydateSDK
-- Configuring done
-- Generating done
-- Build files have been written to: C:/PlaydateSDK/C_API/Examples/Sprite Game/build

C:\PlaydateSDK\C_API\Examples\Sprite Game>cd build

C:\PlaydateSDK\C_API\Examples\Sprite Game\build>ninja
[4/4] Linking C executable SpriteGame_DEVICE.elf
c:/progra~2/armgnu~1/12977f~1.2mp/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: SpriteGame_DEVICE.elf has a LOAD segment with RWX permissions

C:\PlaydateSDK\C_API\Examples\Sprite Game\build>

And as before, opening the resulting SpriteGame.pdx folder in the simulator results in the same error. Maybe some of the other output is meaningful?
From the simulator console:

01:31:51: Loading: C:\PlaydateSDK\C_API\Examples\Sprite Game\SpriteGame.pdx\
01:31:51: Loading: OK
01:31:51: Error: Failed to create a temporary file name (error 267: The directory name is invalid.)
01:31:51: Error: can't open user configuration file.
Update error: no such function 'update'
01:31:51: Update failed, simulator paused.

Sorry, I commented that maybe your folder name had something to do with your issue, but then I realized you were using an example folder. I deleted the post, but didn't know it would still be visible :sweat_smile:

Maybe you could try again with this ARM toolchain version: 10.3-2021.10

I just compiled the example project, and worked with no issues.