Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/actions/msvc-dev-cmd/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Setup MSVC dev environment
description: >
Setups the MSVC toolchain. Based on https://github.com/ilammy/msvc-dev-cmd
inputs:
arch:
description: Target architecture passed to vcvarsall.bat
required: false
default: x64
runs:
using: composite
steps:
- name: Setup Environment
shell: pwsh
run: |
$vswhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio\Installer\vswhere.exe"
$installPath = & $vswhere -latest -products * `
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
-property installationPath
if (-not $installPath) {
throw "vswhere could not find a Visual Studio install with the VC++ toolset"
}

$vcvarsall = Join-Path $installPath "VC\Auxiliary\Build\vcvarsall.bat"
if (-not (Test-Path $vcvarsall)) {
throw "vcvarsall.bat not found at $vcvarsall"
}

$before = @{}
Get-ChildItem Env: | ForEach-Object { $before[$_.Name] = $_.Value }

$output = & cmd.exe /c "`"$vcvarsall`" ${{ inputs.arch }} && set"
if ($LASTEXITCODE -ne 0) {
throw "vcvarsall.bat ${{ inputs.arch }} failed with exit code $LASTEXITCODE"
}

foreach ($line in $output) {
if ($line -notmatch '^([^=]+)=(.*)$') { continue }
$name = $Matches[1]
$value = $Matches[2]
if ($before[$name] -eq $value) { continue }
Add-Content -Path $env:GITHUB_ENV -Value "$name=$value"
}
163 changes: 162 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
with:
cmake-version: "3.22.x"

# use MSVC instead of MinGW
- name: Setup MSVC dev environment
if: ${{ matrix.os == 'windows-latest' }}
uses: ./.github/actions/msvc-dev-cmd

# Create a build directory to store all the CMake generated files
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build
Expand Down Expand Up @@ -194,7 +199,162 @@
name: ${{ matrix.artifact }}-www
path: proofing/ink-proof/out

verify-install:
name: Verify Install (${{ matrix.artifact }}, ${{ matrix.compiler }})
needs: compilation
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
include:
- os: "ubuntu-22.04"
artifact: linux
compiler: gcc
cc: gcc
cxx: g++
exe_ext: ""
- os: "ubuntu-22.04"
artifact: linux
compiler: clang
cc: clang
cxx: clang++
exe_ext: ""
- os: macos-latest
artifact: macos
compiler: clang
cc: clang
cxx: clang++
exe_ext: ""
- os: macos-latest
artifact: macos
compiler: gcc
cc: gcc-14
cxx: g++-14
exe_ext: ""
- os: macos-14
artifact: macos-arm
compiler: clang
cc: clang
cxx: clang++
exe_ext: ""
- os: macos-14
artifact: macos-arm
compiler: gcc
cc: gcc-14
cxx: g++-14
exe_ext: ""
- os: windows-latest
artifact: win64
compiler: msvc
cc: ""
cxx: ""
exe_ext: ".exe"
- os: windows-latest
artifact: win64
compiler: clang
cc: clang
cxx: clang++
exe_ext: ".exe"
steps:
- uses: actions/checkout@v6

- name: Download Lib artifact
uses: actions/download-artifact@v8
with:
name: ${{ matrix.artifact }}-lib
path: install/lib
- name: Download CLib artifact
uses: actions/download-artifact@v8
with:
name: ${{ matrix.artifact }}-clib
path: install/clib
- name: Download Cl artifact
uses: actions/download-artifact@v8
with:
name: ${{ matrix.artifact }}-cl
path: install/cl

- name: Make inkcpp_cl executable
shell: bash
run: chmod +x install/cl/inkcpp_cl${{ matrix.exe_ext }}

- name: Setup MSVC dev environment
if: ${{ matrix.os == 'windows-latest' }}
uses: ./.github/actions/msvc-dev-cmd

- name: Install pkg-config
if: ${{ matrix.os == 'windows-latest' && matrix.compiler == 'clang' }}
run: |
winget install pkgconf.pkgconf --source winget --accept-source-agreements --accept-package-agreements --disable-interactivity
$pkgconf = (Get-ChildItem -Path "C:\Program Files", "C:\Program Files (x86)" -Filter pkgconf.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1).FullName
if (-not (Test-Path $pkgconf)) { throw "pkgconf.exe not found after winget install" }

$bin = Split-Path $pkgconf -Parent
$alias = Join-Path $bin "pkg-config.exe"
if (-not (Test-Path $alias)) { Copy-Item $pkgconf $alias }
Add-Content -Path $env:GITHUB_PATH -Value $bin

- name: Precompile test story
shell: bash
run: >-
install/cl/inkcpp_cl${{ matrix.exe_ext }}
-o Documentation/cmake_example/test.bin
Documentation/cmake_example/test.ink.json

- name: CMake / lib
shell: bash
# the "lib" package is built with AppleClang/libc++ on macOS; GCC cannot link a C++
# translation unit against that archive, so skip main_cpp for that combination
run: |
set -e
if [ -n "${{ matrix.cc }}" ]; then
export CC="${{ matrix.cc }}"
export CXX="${{ matrix.cxx }}"
fi
skip_cpp=OFF
if [[ "${{ matrix.os }}" == macos* && "${{ matrix.compiler }}" == "gcc" ]]; then
skip_cpp=ON
fi
cmake -S Documentation/cmake_example -B build-lib -GNinja \
-DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/install/lib" \
-DINKCPP_EXAMPLE_SKIP_CPP="$skip_cpp"
cmake --build build-lib
cd Documentation/cmake_example
if [ "$skip_cpp" != "ON" ]; then
echo 0 | "${{ github.workspace }}/build-lib/main_cpp${{ matrix.exe_ext }}"
fi
echo 0 | "${{ github.workspace }}/build-lib/main_c${{ matrix.exe_ext }}"

- name: CMake / clib
shell: bash
run: |
set -e
if [ -n "${{ matrix.cc }}" ]; then
export CC="${{ matrix.cc }}"
export CXX="${{ matrix.cxx }}"
fi
cmake -S Documentation/cmake_example -B build-clib -GNinja \
-DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \
-DCMAKE_PREFIX_PATH="${{ github.workspace }}/install/clib"
cmake --build build-clib
cd Documentation/cmake_example
echo 0 | "${{ github.workspace }}/build-clib/main_c${{ matrix.exe_ext }}"

# cl.exe ignores pkg-configs linkage flags
- name: pkg-config / clib
if: ${{ matrix.compiler != 'msvc' }}
shell: bash
run: |
set -e
export CC="${{ matrix.cc }}"
export PKG_CONFIG_PATH="${{ github.workspace }}/install/clib/lib/pkgconfig"
pkg-config --define-prefix --cflags --libs inkcpp
cd Documentation/cmake_example
$CC main.c -o main_pkgconfig${{ matrix.exe_ext }} $(pkg-config --define-prefix --cflags --libs inkcpp)
echo 0 | ./main_pkgconfig${{ matrix.exe_ext }}

build-doc:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: Build Doxygen documentation
needs: [compilation, build-python]
runs-on: ubuntu-latest
Expand Down Expand Up @@ -271,7 +431,7 @@
- name: Build python release
run: python3 -m build

- uses: suisei-cn/actions-download-file@v1.6.0
- uses: suisei-cn/actions-download-file@v1.6.1
name: Download Inklecate
id: download_inklecate
with:
Expand All @@ -281,6 +441,7 @@
shell: bash
run: |
cd inklecate
echo "26f4e188e02536d6e99e73e71d9b13e2c2144187f1368a87e82fd5066176cff8 *$(ls *.zip)" | sha256sum -c -
unzip *.zip
echo "INKLECATE=${{ matrix.inklecate_pre }}$GITHUB_WORKSPACE/inklecate/inklecate${{ matrix.inklecate_post }}" >> $GITHUB_ENV

Expand Down
28 changes: 20 additions & 8 deletions Documentation/cmake_example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
cmake_minimum_required(VERSION 3.16)
project(main)
project(main C CXX)

find_package(inkcpp CONFIG REQUIRED)

# for CXX builds
add_executable(main_cpp main.cpp)
set_property(TARGET main_cpp PROPERTY CXX_STANDARD 17)
target_link_libraries(main_cpp inkcpp inkcpp_compiler)
# Set when linking a libc++-built "lib" package against a compiler using a different C++ ABI (e.g.
# GCC on macOS), where the C++ example can never link.
option(INKCPP_EXAMPLE_SKIP_CPP "Skip building the C++ example (main_cpp)" OFF)

# for C builds
# add_executable(main_c main.c)
# target_link_libraries(main_c inkcpp_c)
# for CXX builds - only available when the "lib" package was installed
if(NOT INKCPP_EXAMPLE_SKIP_CPP
AND TARGET inkcpp
AND TARGET inkcpp_compiler)
add_executable(main_cpp main.cpp)
set_property(TARGET main_cpp PROPERTY CXX_STANDARD 17)
target_link_libraries(main_cpp PRIVATE inkcpp inkcpp_compiler)
endif()

# for C builds - available from both the "lib" and "clib" packages
if(TARGET inkcpp_c)
add_executable(main_c main.c)
set_property(TARGET main_c PROPERTY C_STANDARD 17)
set_property(TARGET main_c PROPERTY C_STANDARD_REQUIRED ON)
target_link_libraries(main_c PRIVATE inkcpp_c)
endif()
15 changes: 10 additions & 5 deletions Documentation/cmake_example/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include <stdio.h>
#include <assert.h>

#include <ink/c/inkcpp.h> // if <os>-lib.zip was used for the installation

// #include <ink/inkcpp.h> // if <os>-clib.zip was used for the installation
#if __has_include(<ink/c/inkcpp.h>)
# include <ink/c/inkcpp.h> // <os>-lib.zip layout
#else
# include <ink/inkcpp.h> // <os>-clib.zip layout
#endif

InkValue ink_add(int argc, const InkValue argv[])
{
Expand All @@ -15,7 +17,8 @@ InkValue ink_add(int argc, const InkValue argv[])

int main()
{
ink_compile_json("test.ink.json", "test.bin", NULL);
// test.bin is precompiled ahead of time (e.g. via inkcpp_cl) since the clib
// package does not include the compiler
HInkStory* story = ink_story_from_file("test.bin");
HInkRunner* runner = ink_story_new_runner(story, NULL);

Expand All @@ -32,7 +35,9 @@ int main()
}

int id;
scanf("%i", &id);
while (scanf("%i", &id) != 1) {
printf("Failed to parse input!, try again\n");
}
ink_runner_choose(runner, id);
}
}
2 changes: 1 addition & 1 deletion Documentation/cmake_example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <ink/story.h>
#include <ink/compiler.h>

#include <memory.h>
#include <memory>
#include <iostream>

using namespace ink::runtime;
Expand Down
27 changes: 20 additions & 7 deletions inkcpp_c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,26 @@ install(
COMPONENT clib
EXCLUDE_FROM_ALL)

# configure in two steps to get the current installation prefix
set(PREFIX "@PREFIX@")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/inkcpp_c.pc.in ${CMAKE_BINARY_DIR}/inkcpp_c.pc.in @ONLY)
set(INKCPP_C_PC_EXTRA_LIBS "")
foreach(lib IN LISTS CMAKE_CXX_IMPLICIT_LINK_LIBRARIES)
if(IS_ABSOLUTE "${lib}")
string(APPEND INKCPP_C_PC_EXTRA_LIBS " ${lib}")
else()
string(APPEND INKCPP_C_PC_EXTRA_LIBS " -l${lib}")
endif()
endforeach()

set(INKCPP_C_PC_EXTRA_CFLAGS "")
if(MSVC)
# this archive is built with MSVC's default dynamic CRT (/MD in Release).
set(INKCPP_C_PC_EXTRA_CFLAGS "-fms-runtime-lib=dll -lmsvcrt -lvcruntime -lucrt -loldnames")
endif()

set(PREFIX "/user/local")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/inkcpp_c.pc.in ${CMAKE_CURRENT_BINARY_DIR}/inkcpp.pc
@ONLY)
install(
CODE [[
get_filename_component(PREFIX ${CMAKE_INSTALL_PREFIX} ABSOLUTE)
configure_file(inkcpp_c.pc.in ${PREFIX}/lib/pkgconfig/inkcpp.pc @ONLY)
]]
FILES ${CMAKE_CURRENT_BINARY_DIR}/inkcpp.pc
DESTINATION lib/pkgconfig
COMPONENT clib
EXCLUDE_FROM_ALL)
20 changes: 4 additions & 16 deletions inkcpp_c/include/inkcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ typedef struct HInkSTory HInkStory;
* page](https://github.com/JBenda/inkcpp/releases/latest) to `/MY/INKCPP/EXAMPLE_INSTALL/PATH`.
* <br/> To run the example do the following:
*
* + change the `prefix=...` in `/MY/INKCPP/EXAMPLE_INSTALL/PATH/lib/pkgconfig/inkcpp.pc`
* to `prefix=/MY/INKCPP_EXAMPLE_INSTALL_PATH/`
* + `export PKG_CONFIG_PATH=/MY/INKCPP/EXAMPLE_INSTALL/PATH/lib/pkgconfig`
* + `gcc -c main.c $(pkg-config --cflags inkcpp)`
* + `g++ -o main main.o $(pkg-config --libs inkcpp)`
* + `clang main.c -o main $(pkg-config --define-prefix --cflags --libs inkcpp)`
* + `./main`
*
* @note `clang` is used here since, unlike `gcc`, it is readily available on Windows, macOS and
* Linux alike.
*
* As a sideproduct a file named `test.bin` should be created coaining the binary format used by
* inkCPP.
*
Expand Down Expand Up @@ -456,18 +456,6 @@ typedef struct HInkSTory HInkStory;
HInkStory* self, const HInkSnapshot* obj, HInkGlobals* store, int runner_id
);

/**
* @ingroup clib
* Compiles a .ink.json file to an inkCPP .bin file.
* @param input_filename path to file contaning input data (.ink.json)
* @param output_filename path to file output data will be written (.bin)
* @param error if not NULL will contain a error message if an error occures (else will be set to
* NULL)
*/
void
ink_compile_json(const char* input_filename, const char* output_filename, const char** error);


#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions inkcpp_c/inkcpp_c.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ includedir=${prefix}/include
Name: inkcpp
Description: C Bindnigs for inkpp. @CMAKE_PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
CFlags: -I${includedir}
Libs: -L${libdir} -linkcpp_c
CFlags: -I${includedir} @INKCPP_C_PC_EXTRA_CFLAGS@
Libs: -L${libdir} -linkcpp_c @INKCPP_C_PC_EXTRA_LIBS@
Loading
Loading