DkSDK CMake Tutorial

What you need to know

To complete this tutorial, you should:

  • Be able to use git to clone a project

  • Be familiar enough with one of the following C IDEs to open, configure and build a C project:

    • Visual Studio Code

    • CLion

    • Visual Studio

    • Xcode

  • Have access to at least one computer from the following list:

    • Windows 64-bit

    • macOS

    • Linux x86_64

Step One - Accessing DkSDK

Follow the steps laid out in the DkSDK Subscriber Access Guide.

Step Two - Creating a Project

For your new project, decide on


A project name like AcmeWidgets, where Acme is a short abbreviation for your company, brand or team and Widgets describes your project.

The project naming rules are as follows:

  • The project name must be at least 3 characters long

  • must only have alphanumeric characters

  • must have its first character be an uppercase letter

  • must have its second character be a lowercase letter

  • must contain, after the second character, another sequence of an upper case letter followed by a lowercase letter


Where you would like to place your new project directory


  1. Make a git clone of DkHelloWorld.

  2. Open PowerShell on Windows, Terminal on macOS, or a shell on Linux. Then change directory to where you cloned DkHelloWorld:

    cd .../DkHelloWorld
  3. In the same PowerShell/Terminal/shell, run the following with your chosen NAME and DIR:

    ./dk NAME AcmeWidgets DIR ../acme-widgets
  4. Open your new project in your C IDE.

    You can build and run the main-cli target in the src/MainCLI directory to start an echo server. You won't get any output unless you add the -v option to main-cli.

  5. There is a in your new project with other instructions. For now though, just continue with Step Three - Embedding OCaml in C below.

Step Three - Embedding OCaml in C

You won't need to read these references now, but the two references below explain in detail how to embed OCaml into your C code:

  1. Real World OCaml - The Compiler Backend

  2. OCaml 4.14 Language Manual - Interfacing C with OCaml

What follows is the simple example from Real World OCaml - The Compiler Backend:

  1. Create a directory src/EmbedOut in your project tree.

  2. Create the file src/EmbedOut/embed_out.c. The highlighted line is the interesting line: it will call the OCaml code we'll write in the next step. Here is the C code:

/* filename: src/EmbedOut/embed_out.c */

/************************************************************************* * * * Copyright 2023 Diskuv, Inc. * * * * Licensed under the DkSDK SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT * * <> or under the * * Open Software License version 3.0 * * <;, at your option. * * This file may not be copied, modified, or distributed except * * according to those terms. * * * *************************************************************************/ #include <stdio.h> #include <caml/alloc.h> #include <caml/mlvalues.h> #include <caml/memory.h> #include <caml/callback.h>

#ifdef _WIN32 # define portable_main wmain # define portable_char wchar_t #else # define portable_main main # define portable_char char #endif

int (portable_main)(int argc, portable_char **argv) { printf("Before calling OCaml\n"); fflush(stdout); caml_startup (argv); caml_shutdown (); printf("After calling OCaml\n"); return 0; }


Windows wmain function

If you are familiar with Unix C programming, the wmain function and wchar_t typedef may be unusual to you. In Windows the w prefix means wide-characters, which is a fancy way of saying Unicode support.

  1. Create the files src/EmbedOut/

    (* filename: src/EmbedOut/ *)
    let () =
      print_endline "hello embedded world 1"; ()

    and src/EmbedOut/

    (* filename: src/EmbedOut/ *)
    let run () = print_endline "hello embedded world 2"


    Differences from Real World OCaml

    With DkSDK you provide one entry point to a library, and from that entry point do all the calls to other modules you need. That entry point ( in our case) must have the same name as the library which we'll define in the next step.

  2. Create src/EmbedOut/CMakeLists.txt:

    # src/EmbedOut/CMakeLists.txt


    add_library(embed_ml STATIC

    add_executable(embed-out embed_out.c) target_link_libraries(embed-out PRIVATE DkSDK::OCamlCompile DkSDK::OCamlDependencies embed_ml)

  3. Add the highlighted line to bottom of src/CMakeLists.txt:

    # src/CMakeLists.txt

    add_subdirectory(HelloLib) add_subdirectory(MainCLI) add_subdirectory(EmbedOut)

Then configure the project. You can now build and run the embed-out target. You should see:

Before calling OCaml
hello embedded world 1
hello embedded world 2
After calling OCaml

Step Four - What's Next?

You have just:

  • Created a new project

  • Created a new target that embeds C and OCaml code

There is a inside your new project that you should skim.