Programming with C on Windows using VSCode and CMake

The SDK for Windows is a little anemic, so I figured this might be useful to anyone trying to figure out how to program in C on Windows. Also, none of this is really Windows only, the modified bits are fixed up to also support Windows properly as well as allow user defined paths for the SDK and toolchain using environment variables.

This will setup a simple C project using Visual Studio Code and CMake. We use CMake because Panic has provided some helper CMake files that help generate/compile our project, and Visual Studio Code as it has extensions to interact with CMake.

  • CMake (https://cmake.org/)
    First half of our build system; this will configure and generate Ninja build files for us to build our project with.

  • Visual Studio Code

    • C/C++ extension by Microsoft
    • CMake Tools extension by Microsoft
      Don't forget the extensions! They help us get Visual Studio Code to a decently functioning IDE for our project.
  • Ninja (Releases · ninja-build/ninja · GitHub)
    Just unpack this in some directory (for ex. C:/playdate_dev/bin). Remember where you put it, we're gonna need to add it to our PATH environment variable later. This would be done so CMake Tools would be able to use it.

  • GCC ARM Toolchain (https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/9-2019-q4-major)
    As we did with Ninja, unpack the zip into some directory (for ex. C:/playdate_dev/arm_toolchain) and note the path. We will save the path in a new environment variable later.

  • Playdate SDK
    If you haven't already unpacked this, go on and do it! Be sure to note the path where "bin" is a child directory. Again, this will be going into its own environment variable.

  • Addtional Helper Files vscode_helpers_v2.zip (3.8 KB)
    This zip holds a template workspace folder called "c_template", which is already setup to be working with VSCode when your environment is setup properly. There is also the "arm_patched.cmake" file, place that in (Playdate SDK)/C_API/buildsupport. This essentially defines our toolchain to cmake.

Once CMake, Visual Studio Code + Extensions are setup and everything is unpacked to where they're supposed to be, we need to setup an environment with which that would allow our setup to work. I'm using environment variables for this, and you can set these up however you like, as long as they'll be defined in an environment that VS Code executes in. You can set it up under your user's environment variable or setup some command prompt shell that has the environment variables setup for that shell window (you can open a workspace folder in VS Code from prompt via "vscode .").

  • PATH: For the PATH environment variable, you need to add the path to wherever Ninja was unpacked.
  • PLAYDATE_SDK: This will be a new one, the path define should point to your SDK directory where bin is a child directory.
  • PLAYDATE_ARM_GCC: Another new environment variable, this time the path defined to where you've unpacked the ARM GCC toolchain.

Don't forget to escape your back slashes (or use forward slashes) in your paths!! Once that's done, make a copy of the "c_template" folder and rename it to whatever you'd like. After that, we open VS Code with that copied folder as our workspace. Again, when we open VS Code, it has to have the environment variables setup as above.

Once VS Code opens up, the cmake-tools extension will detect the CMakeLists.txt file, and will ask if you want to configure it. Hit "Yes", and at the top a drop down will open. This is where we select our kit, meaning our tool chain. You should see at least one available called "Playdate Device", select that.

After the kit has been selected, cmake-tools will invoke CMake to configure the project for us. If everything is working, there should be no errors in the output window (this is a warning popup from VS Code itself but it seems safe to ignore). All we need to do now is to try a build; F7 is a shortcut for CMake Build but it is a task you can run under the command palette using Ctrl+Shift+P. There are also CMake Clean/Rebuild/Configure/etc tasks under the command palette. Anyways, the build should finish pretty quickly and show no errors if everything is setup properly. You should now see a "c_template.pdx" folder in the workspace directory! You can install this using pdutil.exe, via pdutil install c_template.pdx. This could be a task but I've been using VS Code as long as I've been hammering it to work for Playdate :slight_smile:

After all that is said and done, run the CMake Clean task (again, Ctrl+Shift+P and start typing cmake clean and the task should pop up) and open up CMakeLists.txt and change the project name to something other than c_template. Your first C project for Playdate is now setup!

You'd guys be the first ones aside from myself using this, so I'll try to stick around for questions.

EDIT: updated zip with a fixed arm_patched.cmake file and attached a task to the build hotkey (Ctrl+Shift+B, remember actual Build is on F7!) that will deploy and run the package on the Playdate. For this to work, the workspace folder must be named the same as your project name in CMakeLists.txt

10 Likes

Hi Ali Scissons,

Thanks for your sharing, I have successfully setup the VSCode for Playdate.

I noticed there is something to change, so CMAKE latest version can works and below are documented for better visualization.

There is no Windows Playdate Emulator or Playdate device available at the moment, the instruction "pdutil install c_template.pdx" screen shot is not available though.

Current version installed:
PlaydateSDK version 0.10.1
gcc-arm-none-eabi-9-2019-q4-major-win32-sha2
cmake-3.17.2-win64-x64
ninja v1.10.0

Hopes, this help.

2 Likes

Thanks for catching that! I've fixed it and re-uploaded the zip. I also added deploy/run task that is bound to Ctrl+Shift+B (this requires the workspace folder to be the same name as the project).

For more details on pdutil, you can just use a full path to the PDX package. Or are you saying that you cannot run pdutil?

2 Likes

PDUTIL is ok, but the PlaydateSDK 0.10.1 for Windows don't have the Simulator and personally not yet receive the Playdate device, therefore I cannot test PDUTIL :slight_smile:

Is it possible we could get a C++ project template alongside this C template? It seems there's some nuanced differences between the provided one here and the hello world cpp sample and I'm not versed enough to understand the nuance between what's needed to make it buildable on windows via VS Code.

My mashed together CMakeList had some weird differences. First being the execution of commands that I assume were put there for mac, so it would throw strange errors trying to configure. I removed those because they seemed to be just for setting up the SDK env variable, and instead I opted for the windows solution provided here. The next weird difference was that the add_executable line was targeting setup.s instead of setup.c. I'm not sure if that's a typo or if we're just missing a file or if those bash commands did something to generate that file (though I don't think they were).

Here's the CMakeList.txt I put together:

cmake_minimum_required(VERSION 3.14)
set (CMAKE_CXX_STANDARD 11)

# Initial Variables
set(SDK $ENV{PLAYDATE_SDK})

# Game Name Customization
set(PLAYDATE_GAME_NAME cpp_template)
set(PLAYDATE_GAME_DEVICE cpp_template_DEVICE)

# Source files
#TODO include a txt from src that keeps an updated list of files to compile
file(
    GLOB_RECURSE
    SOURCE_FILES
    src/*.cpp
)

# Configure project
project(${PLAYDATE_GAME_NAME} C CXX ASM)

if (TOOLCHAIN STREQUAL "armgcc")
	add_executable(${PLAYDATE_GAME_DEVICE} ${SDK}/C_API/buildsupport/setup.c ${SOURCE_FILES})
else()
	add_library(${PLAYDATE_GAME_NAME} SHARED src/main.cpp)
endif()

# Make sure we get rid of any existing builds on clean
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "../${PLAYDATE_GAME_NAME}.pdx" "../Source/pdex.bin")

include(${SDK}/C_API/buildsupport/playdate_game.cmake)

Edit: I should note, the C template worked fine, I got it building, and outputting files as expected. Was even able to run in the mac simulator from a windows build to confirm.

Edit2: After not looking for a day, I decided to check again on my configuration and I figured out I made a mistake in this line

# Configure project
project(${PLAYDATE_GAME_NAME} C CXX ASM)

I fixed it by removing the "C" so it's just CXX ASM

Now I no longer get errors and get an output pdx folder. It still won't run in the simulator though, so any possible help there would be good. Steps in the right direction though!

1 Like

Thank you so much, @ali.aya, this was a huge time saver!

Btw, I wasn't able to get CMake to clean the build directory properly until I changed this line in CMakeLists.txt:

# Make sure we get rid of any existing builds on clean
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "../${PLAYDATE_GAME_NAME}.pdx" "../Source/pdex.bin")

Looks like ADDITIONAL_MAKE_CLEAN_FILES was deprecated in version 3.15 of CMake.

1 Like

Hi,

Your statement,

" You should now see a “c_template.pdx” folder in the workspace directory! You can install this using pdutil.exe, via pdutil install c_template.pdx ."

From my understanding it is a c_template.pdx folder and no .pdx file but a .bin file within.

Does it means C compiled version only can deploy to physical Playdate device merely at 0.10.1 SDK ?

Hi Zach and Ali, I am able to compile in C++ successfully and created the .bin file.

However, there is a pop up from CMake tools such as:

CMake tools issues

Any idea how to resolve this pop up message ?

Hi Scott,

I just tested 0.10.2 VSCode generated cpp_template.pdx folder under Mac , obviously the Mac Playdate Simulator required physical ".pdx" file to run and ".bin" is for physical playdate device.

I believed, for Windows toolchain, only physical playdate device deployment makes sense, based on 0.10.2 SDK at the moment.

HI there! This template works perfectly.

How would one add compiler flags using this environment?

The poom thread has the answer I was looking for.

Hi a_rival,

I am unsure how you able to work perfectly without the warning message below as so far there is no obvious solution after searching the internet ?

PlaydateSDK - cmake error on loading

From what I understand, to use C/C++ toolchain for Playdate under Windows, there are two options:

  1. Using VSCode to establish SSH remote connection to MacOS SSH host ( server ) then compile under Windows VSCode to generate .dylib and .pdx file stored under MAC computer for its MacOS Playdate emulator, .bin for physical Dev Preview Playdate device.

  2. Stick to Windows PC using the C/C++ template and creates the .bin to test on physical Dev Preview Playdate device only.

Personally, I will decide which is the best method when the Dev Preview Playdate device is received.

Apparently, Panics is responsible for the toolchain and not the developers, building games already time consuming and I really don't want to spend much time on toolchain though :slightly_smiling_face:

The Windows Simulator does support loading C API games, although we haven't published any additional build support / example files for this yet.

It basically comes down to:

  • Build your game as a Windows x86 DLL
  • Make sure eventHandler is exported: __declspec(dllexport) int eventHandler(PlaydateAPI* playdate, PDSystemEvent event, uint32_t arg)
  • Rename your DLL to pdex.bin

Simulator can not load ARM binaries. The DLL must be built using MSVC++ or other Win32 x86 compiler.

1 Like

hi Brook, thanks for sharing, i did not know .bin is actually a DLL file :slightly_smiling_face:

Hey y'all.

I've been trying to get the Hello World C sample to run in the Windows simulator. It looks like it's now expecting the library to be in a file named pdex.dll instead of pdex.bin as Brook mentioned. I've built using CLion and VS2019 community, all defaults. I did have to modify the CMake files a little:

  1. Had to rephrase the post build steps (renaming the output, etc) with windows shell commands.
  2. Had to disable the compiler flags that didn't map to VS 2019 (the -W ones, and the ggdb ones).
  3. Had to hardcode the SDK path as the search in the cmake preamble won't work on windows.

I'm now at a place where the windows simulator does try to load this, but immediately fails with the following errors. Any thoughts on next steps? Thanks!

Loading C API game ../C_API/Examples/Hello World/hello_world.pdx/pdex.dll
LoadLibrary FAILED (193): ../C_API/Examples/Hello World/hello_world.pdx/pdex.dll

This tutorial has been replaced by official support; please see the Windows section in Inside Playdate with C.