Skip to content

Commit

Permalink
Added CMake Flags to make tests optional (#89)
Browse files Browse the repository at this point in the history
This will support building INKCpp without installing/downloading
inklecate.
To enable tests set `INKCPP_TEST=ON`
Also allows auto-download inklecate for testing with
`INCKPP_INKLECATE=OS`

fixes #88
  • Loading branch information
JBenda authored Sep 16, 2024
1 parent e11411f commit 8b85f2d
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 75 deletions.
18 changes: 1 addition & 17 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ jobs:
with:
submodules: true

# Download inklecate
- uses: suisei-cn/actions-download-file@v1.6.0
name: Download Inklecate
id: download_inklecate
with:
url: ${{ matrix.inklecate_url }}
target: "inklecate/"

# Install Inklecate
- name: Deploy Inkelcate
shell: bash
run: |
cd inklecate
unzip *.zip
echo "INKLECATE=${{ matrix.inklecate_pre }}$GITHUB_WORKSPACE/inklecate/inklecate${{ matrix.inklecate_post }}" >> $GITHUB_ENV
# Setup python
- uses: actions/setup-python@v5
if: ${{ matrix.proof }}
Expand All @@ -83,7 +67,7 @@ jobs:
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DINKCPP_PY=OFF -DINKCPP_C=ON
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DINKCPP_PY=OFF -DINKCPP_C=ON -DINKCPP_TEST=ON -DINKCPP_INKLECATE=OS

# Build using CMake and OS toolkit
- name: Build
Expand Down
44 changes: 43 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
cmake_minimum_required(VERSION 3.16)

if(${CMAKE_VERSION} VERSION_GREATER "3.24.0")
cmake_policy(SET CMP0135 NEW)
endif()
include(FetchContent)
FetchContent_Declare(inklecate_mac
URL https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_mac.zip
URL_HASH SHA256=c516402bca5fa249a7712e62591b048b137eba3098c53f9fb85a4253f9b9e2c0
SOURCE_DIR "inklecate/mac"
)
FetchContent_Declare(inklecate_windows
URL https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_windows.zip
URL_HASH SHA256=6f317cb4c59bf1b31c6dd61e80c6a2287a1d8c241a703f0586f736ae00871aab
SOURCE_DIR "inklecate/windows"
)
FetchContent_Declare(inklecate_linux
URL https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_linux.zip
URL_HASH SHA256=26f4e188e02536d6e99e73e71d9b13e2c2144187f1368a87e82fd5066176cff8
SOURCE_DIR "inklecate/linux"
)
set(FETCHCONTENT_QUIET OFF)
set(CMAKE_TLS_VERIFY true)
# Testing enabled
enable_testing()

Expand All @@ -14,6 +35,25 @@ SET(CMAKE_INSTALL_INCLUDE_DIR include)
set(INKCPP_PY OFF CACHE BOOL "Build python bindings")
set(WHEEL_BUILD OFF CACHE BOOL "Set for build wheel python lib (do not forgett INKCPP_PY")
set(INKCPP_C OFF CACHE BOOL "Build c library")
set(INKCPP_TEST OFF CACHE BOOL "Build inkcpp tests (requires: inklecate in path / env: INKLECATE set / INKCPP_INKLECATE=OS or ALL)")
set(INKCPP_INKLECATE "NONE" CACHE STRING "If inklecate should be downloaded automatically from the official release page. NONE -> No, OS -> Yes, but only for the current OS, ALL -> Yes, for all availible OSs")
set_property(CACHE INKCPP_INKLECATE PROPERTY STRINGS "NONE" "OS" "ALL")
set(INKCPP_DOC_BlueprintUE ON CACHE BOOL "Building doxygen documentation with BlueprintUE visualisation for unreal blueprints.")

string(TOUPPER "${INKCPP_INKLECATE}" inkcpp_inklecate_upper)
if (inkcpp_inklecate_upper STREQUAL "ALL")
FetchContent_MakeAvailable(inklecate_windows inklecate_mac inklecate_linux)
elseif(inkcpp_inklecate_upper STREQUAL "OS")
if(UNIX AND NOT APPLE)
FetchContent_MakeAvailable(inklecate_linux)
elseif(APPLE)
FetchContent_MakeAvailable(inklecate_mac)
elseif(MSYS OR MINGW OR WIN32 OR CYGWIN)
FetchContent_MakeAvailable(inklecate_windows)
else()
message(FATAL_ERROR "Unable to identify OS for option INKCPP_INKLECATE=OS, please consider using NONE or ALL.")
endif()
endif()

if (INKCPP_PY)
add_compile_options(-fPIC)
Expand All @@ -27,7 +67,9 @@ if (INKCPP_C)
endif(INKCPP_C)
if (NOT WHEEL_BUILD)
add_subdirectory(inkcpp_cl)
add_subdirectory(inkcpp_test)
if(INKCPP_TEST)
add_subdirectory(inkcpp_test)
endif(INKCPP_TEST)
add_subdirectory(unreal)
endif(NOT WHEEL_BUILD)

Expand Down
Binary file modified Documentation/cmake_example.zip
Binary file not shown.
1 change: 1 addition & 0 deletions Documentation/cmake_example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ find_package(inkcpp CONFIG REQUIRED)

# for CXX builds
add_executable(main_cpp main.cpp)
set_property(TARGET main_cpp PROPERTY CXX_STANDARD 20)
target_link_libraries(main_cpp inkcpp inkcpp_compiler)

# for C builds
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Doxygen Documentation: https://jbenda.github.io/inkcpp/html

Run `inkcpp_cl.exe -p myfile.json` to execute a compiled Ink JSON file in play mode. It can also operate on `.ink` files but `inklecate.exe` must be in the same folder or in the PATH.
`inklecate` can be downloaded from the [official release page](https://github.com/inkle/ink/releases) and will be downloaded from CMake at configure time (located at `build/unreal/inkcpp/Resources/inklecate`).
Or do it automatically with the `INKCPP_INKLECATE=OS` CMake flag. (It will be downloaded to `<build-dir>/inklecate/<os>/` and will be installed with `cmake --install . --component cl`)

Without the `-p` flag, it'll just compile the JSON/Ink file into InkCPP's binary format (see the Wiki on GitHub).

Expand Down Expand Up @@ -129,6 +130,7 @@ To build, either run the generated buildfiles OR you can use `cmake --build . --
To install the different components use `cmake --install . --component <lib|cl|unreal>`
+ `lib` C++ library to link against
+ `clib` C library to link against
+ `cl` command line application
+ `unreal` UE-plugin
Expand All @@ -142,7 +144,29 @@ If you recieve an error like "Mismatch Detected for Runtime Library," it means y
### Running Tests
Run `ctest` from the build folder to execute unit tests configured with CMake. Use `ctest -V` for more verbose error output.
To enable testing set the CMake flag `INKCPP_TEST=ON`. If you do not have inklecate at your path you can set `INKCPP_INKLECATE=OS` to download und use the current supported verision.
Run `ctest -C Release` from the build folder to execute unit tests configured with CMake. Use `ctest -V -Release` for more verbose error output.
Do not forgett that the C libs are only testet if `INKCPP_C=ON` is set.
```sh
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DINKCPP_TEST=ON -DINKCPP_INKLECATE=OS
cmake --build . --config Release
ctest -C Release
```

To test the python bindings use:

```sh
pip install .
python -m pip install build pytest
python -m build
python -m pip install dist/*.whl --user
# if inklecate is not in the same directory / inside Path set INKLECATE enviroment variable
export INKLECATE=<PATH-TO-inklecate> # unix
set INKLECTATE=<PATH-TO-inklecate> # windows
python -m pytest
```

Right now this only executes the internal unit tests which test the functions of particular classes. Soon it'll run more complex tests on .ink files using ink-proof.

Expand All @@ -155,7 +179,7 @@ To build it from source use:

```sh
git clone --recurse-submodules https://github.com/JBenda/inkcpp.git
pip install inkcpp
pip install .
```

The python bindnigs are defined in `inkcpp_py` subfolder.
Expand Down
36 changes: 28 additions & 8 deletions inkcpp/include/story.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,12 @@ class story
* `linux-lib.zip`). <br/> to link the libraries you can use `find_package(inkcpp CONFIG)` which
* provides two targets:
* + inkcpp: the runtime enviroment
* + inkcpp_comopiler: functionality to compile a story.json to story.bin
* + inkcpp_compiler: functionality to compile a story.json to story.bin
*
* To run your own `.ink` files you need a way to compile it to inks runtime format `.ink.json`. One
* way is to use `inklecate <story>.ink`.<br/> Which is available at the [official release
* page](https://github.com/inkle/ink/releases/latest).<br/>
* Alternativly set the enviroment variable `INKLECATE` so that `%INKLECATE%` executes inklecate.
*
* If you want to use the inkcpp with C link against the target inkcpp_c and `#include
* <ink/c/inkcpp.h>` The C-API documentation and example can be found @ref clib "here".
Expand All @@ -143,12 +144,29 @@ class story
* ls # expected output: CMakeLists.txt main.cpp test.ink test.ink.json linux-lib
* mkdir build
* cd build
* inkcpp_DIR=../linux-lib cmake ..
* cmake --build .
* cp ../test.ink.json .
* ./main_cpp
* inkcpp_DIR=../linux-lib cmake .. -DCMAKE_BUILD_TYPE=Release # linux
* set inkcpp_DIR=../win64-lib # windows
* cmake .. # windows
* cmake --build . --config=Release
* cd ..
* ./build/main_cpp # exact path depends on build system
* used
* @endcode
*
* @subsection cmake_flags CMake Flags
* + INKCPP_TEST: (ON|OFF) weather or not execute tests
* requires `inklecate` to be in the PATH or `INKCPP_INKLECATE=OS` or `=ALL`
* + INKCPP_INKLECATE: (NONE|OS|ALL) download the current supported inklecate version from the
* official [release page](https://github.com/inkle/ink/releases/latest)</br> They are stored at
* `<build-dir>/inklecate/<os>/` and will be automatcilly used for the tests
* + NONE: disable this function
* + OS: only the version supported for the OS
* + ALL: all versions
* + INKCPP_C: (ON|OFF) Build the inkcpp c bindings (and thest them if test is enabled)
* + INKCPP_PY: (ON|OFF) Build python bindings (build system only)
* + WHEEL_BUILD: (ON|OFF) Settings to work with a python wheel build (build system only)
* + INKCPP_DOC_BlueprintUE: (ON|OFF) enables nice blueprint renders for the documentation
*
* @subsection src_main main.cpp
* @include cmake_example/main.cpp
*
Expand All @@ -161,15 +179,17 @@ class story
*
* @section ue Unreal Installation
*
* The current release is available at the [release
* The easiest way is to install it via the [unreal
* marcetplace](https://www.unrealengine.com/marketplace/en-US/product/inkcpp). The overview to the
* UE Blueprint class and examples can be found at @ref unreal "here".
*
* The current release is also available at the [release
* page](https://github.com/JBenda/inkcpp/releases/latest), as `unreal.zip`.<br/>
* Unpack this foldor in `/PATH/TO/UNREAL_ENGINE/Engine/Plugins/` and it will be available
* as plugin in the plugin list. <br/>
* Or unpack this folder in `/PATH/TO/UNREAL_PROJECT/Plugins/` and it will be
* intigrated at the next startup.<br/> A MarketPlace appearance is work in progress :)
*
* The overview to the UE Blueprint class and examples can be found at @ref unreal "here".
*
* If you want to use the newest version clone the project and install the unreal component.
* @code {sh}
* git clone https://github.com/JBenda/inkcpp
Expand Down
30 changes: 30 additions & 0 deletions inkcpp_cl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,33 @@ endif()

# Install
install(TARGETS inkcpp_cl DESTINATION . COMPONENT cl EXCLUDE_FROM_ALL)
string(TOUPPER "${INKCPP_INKLECATE}" inkcpp_inklecate_upper)
unset(inklecate_dir)
if((inkcpp_inklecate_upper STREQUAL "ALL") OR (inkcpp_inklecate_upper STREQUAL "OS"))
if(UNIX AND NOT APPLE)
FetchContent_GetProperties(inklecate_linux)
if(inklecate_linux_POPULATED)
set(inklecate_dir "${inklecate_linux_SOURCE_DIR}")
else()
message(WARNING "Inklecate for this OS was not downloaded successfully, and will therfore not be packat with cl")
endif(inklecate_linux_POPULATED)
elseif(APPLE)
if(inklecate_mac_POPULATED)
set(inklecate_dir "${inklecate_mac_SOURCE_DIR}")
else()
message(WARNING "Inklecate for this OS was not downloaded successfully, and will therfore not be packat with cl")
endif(inklecate_mac_POPULATED)
elseif(MSYS OR MINGW OR WIN32 OR CYGWIN)
if(inklecate_windows_POPULATED)
set(inklecate_dir "${inklecate_windows_SOURCE_DIR}")
else()
message(WARNING "Inklecate for this OS was not downloaded successfully, and will therfore not be packat with cl")
endif(inklecate_windows_POPULATED)
else()
message(WARNING "Failed to determine OS for bundling inklecate with command line application!")
endif()
if(inklecate_dir)
file(GLOB inklecate_files "${inklecate_dir}/*")
install(FILES ${inklecate_files} DESTINATION . COMPONENT cl EXCLUDE_FROM_ALL)
endif(inklecate_dir)
endif((inkcpp_inklecate_upper STREQUAL "ALL") OR (inkcpp_inklecate_upper STREQUAL "OS"))
27 changes: 17 additions & 10 deletions inkcpp_cl/inkcpp_cl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void usage()
"snapshot file enter '-1' as choice\n"
<< "\t--ommit-choice-tags:\tdo not print tags after choices, primarly used to be compatible "
"with inkclecat output"
<< "\t--inklecate <path-to-inklecate>:\toverwrites INKLECATE enviroment variable\n"
<< endl;
}

Expand All @@ -38,6 +39,7 @@ int main(int argc, const char** argv)
std::string outputFilename;
bool playMode = false, testMode = false, testDirectory = false, ommit_choice_tags = false;
std::string snapshotFile;
const char* inklecateOverwrite = nullptr;
for (int i = 1; i < argc - 1; i++) {
std::string option = argv[i];
if (option == "-o") {
Expand All @@ -56,6 +58,11 @@ int main(int argc, const char** argv)
} else if (option == "-td") {
testMode = true;
testDirectory = true;
} else if (option == "--inklecate") {
if (i + 1 < argc - 1 && argv[i + 1][0] != '-') {
++i;
inklecateOverwrite = argv[i];
}
} else {
std::cerr << "Unrecognized option: '" << option << "'\n";
}
Expand All @@ -65,16 +72,16 @@ int main(int argc, const char** argv)
std::string inputFilename = argv[argc - 1];

// Test mode
if (testMode) {
bool result;
if (testDirectory) {
result = test_directory(inputFilename);
} else {
result = test(inputFilename);
}
// if (testMode) {
// bool result;
// if (testDirectory) {
// result = test_directory(inputFilename);
// } else {
// result = test(inputFilename);
// }

return result ? 0 : -1;
}
// return result ? 0 : -1;
// }

// If output filename not specified, use input filename as guideline
if (outputFilename.empty()) {
Expand All @@ -90,7 +97,7 @@ int main(int argc, const char** argv)

// Then we need to do a compilation with inklecate
try {
inklecate(inputFilename, jsonFile);
inklecate(inputFilename, jsonFile, inklecateOverwrite);
} catch (const std::exception& e) {
std::cerr << "Inklecate Error: " << e.what() << std::endl;
return 1;
Expand Down
17 changes: 14 additions & 3 deletions inkcpp_cl/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,21 @@
#include <compiler.h>
#include <choice.h>

void inklecate(const std::string& inkFilename, const std::string& jsonFilename)
void inklecate(
const std::string& inkFilename, const std::string& jsonFilename, const char* inklecateOverwrite
)
{
// Get environment specific inklecate invocation command
const char* inklecateCmd = std::getenv("INKLECATE");

const char* inklecateCmd = nullptr;
if (inklecateCmd == nullptr) {
if (inklecateOverwrite) {
inklecateCmd = inklecateOverwrite;
}
}
if (inklecateCmd == nullptr) {
std::getenv("INKLECATE");
}
if (inklecateCmd == nullptr)
inklecateCmd = "inklecate";

Expand Down Expand Up @@ -55,7 +66,7 @@ bool test(const std::string& inkFilename)
std::cout << std::filesystem::path(inkFilename).filename().string() << std::endl;

// Compile into a temporary json file
inklecate(inkFilename, "test.tmp");
inklecate(inkFilename, "test.tmp", nullptr);

// Compile into binary
ink::compiler::compilation_results results;
Expand Down
9 changes: 6 additions & 3 deletions inkcpp_cl/test.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <string>

void inklecate(const std::string& inkFilename, const std::string& jsonFilename);
bool test(const std::string& inkFilename);
bool test_directory(const std::string& directory);
void inklecate(
const std::string& inkFilename, const std::string& jsonFilename, const char* inkclecateOverwrite
);
// TODO: reevaluate in ink file test mechanism
// bool test(const std::string& inkFilename);
// bool test_directory(const std::string& directory);
Loading

0 comments on commit 8b85f2d

Please sign in to comment.