Add CMake and tests

- Port tests to GitLab
- Add GitLab CI test matrix
- Remove gtest submodule
This commit is contained in:
Jonah Beckford 2023-08-07 19:39:57 -07:00
parent 7056638935
commit f07596dbb5
19 changed files with 1760 additions and 28 deletions

3
.gitignore vendored
View file

@ -33,3 +33,6 @@ c-capnproto.pc
subprojects/googletest-* subprojects/googletest-*
subprojects/packagecache subprojects/packagecache
/build/
/.ci/

67
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,67 @@
.conda-c-cmake:before:
# Use:
# docker run -it --platform linux/amd64 continuumio/miniconda3:22.11.1
# to test out on a local developer machine (including macOS/ARM64 Silicon)
image: continuumio/miniconda3:22.11.1
variables:
CONDA_PKGS_DIRS: "$CI_PROJECT_DIR/.conda-pkgs-cache"
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
DEBIAN_FRONTEND: noninteractive
cache:
key:
files:
- environment.yml
prefix: cachebust1
paths:
- _local
# Technique explained at https://damiankula.com/using_conda_cache_in_gitlabci.html
- $CONDA_PKGS_DIRS/*.conda
- $CONDA_PKGS_DIRS/*.tar.bz2
- $CONDA_PKGS_DIRS/urls*
- $CONDA_PKGS_DIRS/cache
# yay, we don't use pip: - $PIP_CACHE_DIR
before_script:
# Update/install system pkgs first, so conda can use latest system pkgs.
- apt-get update
# Install Ninja + rsync.
# ninja: CMake configure
# build-essential: CMake project(LANGUAGES C)
- apt-get install -qq -o=Dpkg::Use-Pty=0 ninja-build build-essential > /dev/null
# Install CMake
- ./dk dksdk.cmake.link
# Install Python
- conda env create --quiet -f environment.yml
.c-cmake-debian:before:
image: debian:stable-slim
variables:
DEBIAN_FRONTEND: noninteractive # for apt-get
before_script:
# Update/install system pkgs first, so conda can use latest system pkgs.
- apt-get update
# Install Ninja and C compiler
# ninja: CMake configure
# clang-tidy: CMake -D BUILD_HYGIENE=ENABLED (or the unset default)
# wget: ci/install-cmake.sh
# build-essential: CMake project(LANGUAGES C)
# git: CMake FetchContent()
# valgrind: ctest -T memcheck
- apt-get install -qq -o=Dpkg::Use-Pty=0 ninja-build clang-tidy wget build-essential git valgrind > /dev/null
# Install CMake
- ./dk dksdk.cmake.link
.c-cmake-windows:before:
tags: [shared-windows, windows, windows-1809]
variables:
VSDIR: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
DKSDK_NINJA_PROGRAM: "$CI_PROJECT_DIR\\.ci\\ninja\\bin\\ninja.exe"
before_script:
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/main/cookbooks/preinstalled-software/README.md
# CMake is already present on GitLab CI/CD. No 'choco install -y cmake' (choco frequents gets HTTP 403) or './dk dksdk.cmake.link' needed
- ./dk dksdk.ninja.link
include:
- local: ci/gitlab/test.gitlab-ci.yml

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "gtest"]
path = gtest
url = https://github.com/google/googletest.git

17
CHANGES.md Normal file
View file

@ -0,0 +1,17 @@
# Changes
## 0.9.0
- Forked to the DkML repository on GitLab.
- Use binary mode when reading schemas on Windows
- Use SSIZE_T from `BaseTsd.h` to allow MSVC to compile with 32-bits
- Put alignment on segment fields, not just the structure.
- Avoids left shifts of signed integers, which is undefined C behavior. Passes
ASAN (not a false positive)
- Wrap macro parameters in the `capnp_use(x)` macro. Passes clang-tidy (not
a false positive)
## 0.3 (632f0d73a1f4a03026b5e4727386b9fe3ec6e00e)
- Fork of `c-capnproto-0.3` plus several untagged commits from https://github.com/opensourcerouting/c-capnproto on Apr 23, 2023. Specifically: https://github.com/opensourcerouting/c-capnproto/commit/632f0d73a1f4a03026b5e4727386b9fe3ec6e00e

97
CMakeLists.txt Normal file
View file

@ -0,0 +1,97 @@
cmake_minimum_required(VERSION 3.22)
if(BUILD_TESTING)
# The tests are C++
set(languages C CXX)
else()
set(languages C)
endif()
project(c-capnproto LANGUAGES ${languages})
include(CTest)
# Stop noise if CXX compiler is set.
set(ignoreAndAvoidCMakeUnusedWarning "${CMAKE_CXX_COMPILER}")
# Boilerplate DK CMAKE PROJ 2023-05-17.1
if(APPLE)
set(CMAKE_MACOSX_RPATH OFF)
endif()
# Boilerplate DK CMAKE PROJ 2023-05-17.2
if(BUILD_SHARED_LIBS)
# SHARED is implied by BUILD_SHARED_LIBS=ON
set(linkage)
else()
set(linkage STATIC)
endif()
# Build hygiene: Tools for keeping the source code clean. By default
# we try to enforce build hygiene.
# You can override with either BUILD_HYGIENE=DISABLED or
# BUILD_HYGIENE=ENABLED.
if(NOT BUILD_HYGIENE STREQUAL DISABLED)
if(BUILD_HYGIENE STREQUAL ENABLED)
set(find_program_args REQUIRED)
else()
set(find_program_args)
endif()
find_program(CLANG_TIDY_PROGRAM
NAMES clang-tidy
PATHS
# On macOS the easiest way to get clang-tidy is to install the
# keg-only (not installed into PATH) big `llvm` package.
/opt/homebrew/opt/llvm/bin
/usr/local/opt/llvm/bin
${find_program_args})
endif()
add_library(CapnC_Runtime ${linkage}
lib/capn.c
lib/capn-malloc.c
lib/capn-stream.c
lib/capnp_c.h)
add_library(CapnC::Runtime ALIAS CapnC_Runtime)
set_target_properties(CapnC_Runtime PROPERTIES
EXPORT_NAME Runtime
WINDOWS_EXPORT_ALL_SYMBOLS ON)
target_include_directories(CapnC_Runtime
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/compiler>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lib>
$<INSTALL_INTERFACE:include>)
add_executable(capnpc-c
compiler/capnpc-c.c
compiler/schema.capnp.c
compiler/str.c)
target_link_libraries(capnpc-c CapnC_Runtime)
target_include_directories(capnpc-c
PRIVATE lib)
# Boilerplate DK CMAKE PROJ 2023-05-17.3
if(BUILD_SHARED_LIBS)
if(APPLE)
set(base @loader_path)
else()
set(base $ORIGIN)
endif()
file(RELATIVE_PATH relDir
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_INSTALL_RPATH
# best practice RPATH locations when installed
${base}
${base}/${relDir})
endif()
install(TARGETS CapnC_Runtime capnpc-c
EXPORT CapnC)
install(EXPORT CapnC
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CapnC
NAMESPACE CapnC::
FILE CapnCConfig.cmake)
install(FILES lib/capnp_c.h TYPE INCLUDE)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()

306
CMakePresets.json Normal file
View file

@ -0,0 +1,306 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 22
},
"configurePresets": [
{
"name": "ci-agnostic-configure",
"binaryDir": "build",
"hidden": true,
"description": "ABI-agnostic CI configuration for build and test presets"
},
{
"name": "ci-tests-configure",
"inherits": [
"ci-agnostic-configure"
],
"cacheVariables": {
"BUILD_TESTING": "ON"
}
},
{
"name": "ci-clang_gcc-sanitizers-asan",
"description": "Address sanitizer for clang and GCC",
"cacheVariables": {
"BUILD_TESTING": "ON",
"CMAKE_C_FLAGS_INIT": "-fsanitize=address -fno-sanitize-recover=all",
"CMAKE_EXE_LINKER_FLAGS_INIT": "-fsanitize=address -fno-sanitize-recover=all",
"CMAKE_C_FLAGS_INIT_REASONS": "https://developers.redhat.com/blog/2021/05/05/memory-error-checking-in-c-and-c-comparing-sanitizers-and-valgrind. Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94328 ASAN and UBSAN don't work together with [log_path] which is needed for CTest"
}
},
{
"name": "ci-clang_gcc-sanitizers-ubsan",
"description": "Undefined behavior sanitizer for clang and GCC",
"cacheVariables": {
"BUILD_TESTING": "ON",
"CMAKE_C_FLAGS_INIT": "-fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment",
"CMAKE_EXE_LINKER_FLAGS_INIT": "-fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment",
"CMAKE_C_FLAGS_INIT_REASONS": "https://developers.redhat.com/blog/2021/05/05/memory-error-checking-in-c-and-c-comparing-sanitizers-and-valgrind. Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94328 ASAN and UBSAN don't work together with [log_path] which is needed for CTest"
}
},
{
"name": "ci-host-windows_x86",
"hidden": true,
"cacheVariables": {
"CMAKE_MAKE_PROGRAM": "$env{DKSDK_NINJA_PROGRAM}",
"ENV-DKSDK_NINJA_PROGRAM": "Set the environment variable DKSDK_NINJA_PROGRAM to the path to ninja.exe"
}
},
{
"name": "ci-target-windows_x86",
"hidden": true,
"generator": "Ninja",
"architecture": {
"value": "x86",
"strategy": "external"
}
},
{
"name": "ci-host-windows_x86_64",
"hidden": true,
"cacheVariables": {
"CMAKE_MAKE_PROGRAM": "$env{DKSDK_NINJA_PROGRAM}",
"ENV-DKSDK_NINJA_PROGRAM": "Set the environment variable DKSDK_NINJA_PROGRAM to the path to ninja.exe"
}
},
{
"name": "ci-target-windows_x86_64",
"hidden": true,
"generator": "Ninja",
"architecture": {
"value": "x64",
"strategy": "external"
}
},
{
"name": "ci-host-linux_x86",
"hidden": true
},
{
"name": "ci-target-linux_x86",
"hidden": true
},
{
"name": "ci-host-linux_x86_64",
"hidden": true
},
{
"name": "ci-target-linux_x86_64",
"hidden": true
},
{
"name": "ci-host-darwin_arm64",
"hidden": true,
"cacheVariables": {
"CMAKE_APPLE_SILICON_PROCESSOR": "arm64"
}
},
{
"name": "ci-target-darwin_arm64",
"hidden": true,
"cacheVariables": {
"CMAKE_OSX_ARCHITECTURES": "arm64",
"CMAKE_EXE_LINKER_FLAGS": "-arch arm64",
"CMAKE_MODULE_LINKER_FLAGS": "-arch arm64",
"CMAKE_SHARED_LINKER_FLAGS": "-arch arm64",
"CMAKE_C_COMPILER": "/usr/bin/clang",
"CMAKE_CXX_COMPILER": "/usr/bin/clang++"
},
"environment": {
"CMAKE_x_LINKER_FLAGS_REASON": "DkSDK OCaml uses a single target architecture",
"CMAKE_x_COMPILER_REASON": "Direct use of /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc (14.0.0) will fail to link with -lm, -lSystem, etc."
}
},
{
"name": "ci-host-darwin_x86_64",
"hidden": true,
"cacheVariables": {
"CMAKE_APPLE_SILICON_PROCESSOR": "x86_64"
}
},
{
"name": "ci-target-darwin_x86_64",
"hidden": true,
"cacheVariables": {
"CMAKE_OSX_ARCHITECTURES": "x86_64",
"CMAKE_EXE_LINKER_FLAGS": "-arch x86_64",
"CMAKE_MODULE_LINKER_FLAGS": "-arch x86_64",
"CMAKE_SHARED_LINKER_FLAGS": "-arch x86_64",
"CMAKE_C_COMPILER": "/usr/bin/clang",
"CMAKE_CXX_COMPILER": "/usr/bin/clang++"
},
"environment": {
"CMAKE_x_LINKER_FLAGS_REASON": "DkSDK OCaml uses a single target architecture",
"CMAKE_x_COMPILER_REASON": "Direct use of /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc (14.0.0) will fail to link with -lm, -lSystem, etc."
}
},
{
"name": "ci-darwin_x86_64",
"inherits": [
"ci-tests-configure",
"ci-host-darwin_x86_64",
"ci-target-darwin_x86_64"
],
"displayName": "darwin_x86_64",
"description": "Test builds for darwin_x86_64",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_64",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86_64",
"ci-target-linux_x86_64"
],
"displayName": "linux_x86_64",
"description": "Test builds for linux_x86_64",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_64-sanitizers-asan",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86_64",
"ci-target-linux_x86_64",
"ci-clang_gcc-sanitizers-asan"
],
"displayName": "linux_x86_64-sanitizers-asan",
"description": "Address Sanitizer builds for linux_x86_64",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_64-sanitizers-ubsan",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86_64",
"ci-target-linux_x86_64",
"ci-clang_gcc-sanitizers-ubsan"
],
"displayName": "linux_x86_64-sanitizers-ubsan",
"description": "Undefined Behavior Sanitizer builds for linux_x86_64",
"generator": "Ninja"
},
{
"name": "ci-target-android",
"hidden": true,
"cacheVariables": {
"ANDROID_PLATFORM": "android-21",
"ANDROID_NDK": "$env{DKSDK_PROJECT_BASE}.ci/local/share/ndk/ndk/23.1.7779620",
"BUILD_HYGIENE": "DISABLED"
},
"environment": {
"ANDROID_x_REASON": "https://developer.android.com/studio/projects/configure-cmake#call-cmake-cli",
"BUILD_HYGIENE_REASON": "Android has a stdlib.h that does not pass clang-tidy validation"
},
"toolchainFile": "$env{DKSDK_PROJECT_BASE}.ci/local/share/ndk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake"
},
{
"name": "ci-target-android_arm32v7a",
"hidden": true,
"inherits": [ "ci-target-android" ],
"cacheVariables": {
"ANDROID_ABI": "armeabi-v7a"
}
},
{
"name": "ci-target-android_arm64v8a",
"hidden": true,
"inherits": [ "ci-target-android" ],
"cacheVariables": {
"ANDROID_ABI": "arm64-v8a"
}
},
{
"name": "ci-target-android_x86",
"hidden": true,
"inherits": [ "ci-target-android" ],
"cacheVariables": {
"ANDROID_ABI": "x86"
}
},
{
"name": "ci-target-android_x86_64",
"hidden": true,
"inherits": [ "ci-target-android" ],
"cacheVariables": {
"ANDROID_ABI": "x86_64"
}
},
{
"name": "ci-linux_x86_X_android_x86",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86",
"ci-target-android_x86"
],
"displayName": "linux_x86 -> android_x86",
"description": "Cross-compiler of host linux_x86 to target android_x86",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_X_android_arm32v7a",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86",
"ci-target-android_arm32v7a"
],
"displayName": "linux_x86 -> android_arm32v7a",
"description": "Cross-compiler of host linux_x86 to target android_arm32v7a",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_64_X_android_x86_64",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86_64",
"ci-target-android_x86_64"
],
"displayName": "linux_x86_64 -> android_x86_64",
"description": "Cross-compiler of host linux_x86_64 to target android_x86_64",
"generator": "Ninja"
},
{
"name": "ci-linux_x86_64_X_android_arm64v8a",
"inherits": [
"ci-tests-configure",
"ci-host-linux_x86_64",
"ci-target-android_arm64v8a"
],
"displayName": "linux_x86_64 -> android_arm64v8a",
"description": "Cross-compiler of host linux_x86_64 to target android_arm64v8a",
"generator": "Ninja"
},
{
"name": "ci-windows_x86_64",
"inherits": [
"ci-tests-configure",
"ci-host-windows_x86_64",
"ci-target-windows_x86_64"
],
"displayName": "windows_x86_64",
"description": "Test builds for windows_x86_64",
"generator": "Ninja"
}
],
"buildPresets": [
{
"name": "ci-tests-build",
"hidden": true,
"configurePreset": "ci-tests-configure",
"configuration": "Release"
},
{
"name": "ci-tests",
"inherits": "ci-tests-build",
"targets": ["all"]
}
],
"testPresets": [
{
"name": "ci-test",
"configurePreset": "ci-tests-configure"
}
]
}

1
CTestConfig.cmake Normal file
View file

@ -0,0 +1 @@
set(VALGRIND_COMMAND_OPTIONS "--error-exitcode=109 --leak-check=full")

View file

@ -4,17 +4,16 @@ capnpc-c
This is a C plugin for [Cap'n Proto](http://kentonv.github.io/capnproto), an This is a C plugin for [Cap'n Proto](http://kentonv.github.io/capnproto), an
efficient protocol for sharing data and capabilities. efficient protocol for sharing data and capabilities.
## UNMAINTAINED This is a fork of https://github.com/opensourcerouting/c-capnproto with support
for CMake and Windows, a build matrix that includes Android and Windows, and
fixes several bugs that start with the [CHANGES for version 0.9.0](./CHANGES.md#090).
This project is currently **NOT MAINTAINED**. If you are interested in The fork is maintained as part of [DkML](https://diskuv.com/dkmlbook/)
taking over maintenance and/or need this for some project, please look at and [DkSDK](https://diskuv.com/cmake/help/latest/), but PRs are welcome from
issue https://github.com/opensourcerouting/c-capnproto/issues/55 anybody. If you are looking for your first PR, fixing the false positive
memory leaks in the test code would be great!
No releases will be made. PRs may sit unreviewed for multiple years. **PRs ## Security warning!
MAY get merged WITHOUT ANY REVIEW, as a last ditch attempt to not waste
people's efforts on PRs. This means things may break completely.**
> ## Security warning!
> The generated code assumes all input to be trusted. Do NOT use with > The generated code assumes all input to be trusted. Do NOT use with
> untrusted input! There is currently no code in place to check if > untrusted input! There is currently no code in place to check if
@ -28,27 +27,26 @@ this project and then you can utilize it as:
capnpc compiler/test.capnp -oc capnpc compiler/test.capnp -oc
``` ```
[![Build Status](https://travis-ci.org/opensourcerouting/c-capnproto.svg?branch=master)](https://travis-ci.org/opensourcerouting/c-capnproto)
## Building on Linux ## Building on Linux
```sh ```sh
git clone --recurse-submodules https://github.com/opensourcerouting/c-capnproto git clone https://gitlab.com/diskuv-ocaml/ext/c-capnproto.git
cd c-capnproto cd c-capnproto
autoreconf -f -i -s cmake --preset=ci-linux_x86_64
./configure cmake --build --preset=ci-tests
make
make check
``` ```
## Building with Meson ## Building on Windows
You will need Visual Studio 2019 installed. Other versions of Visual Studio may work; they simply haven't been tested.
Once you have Visual Studio, run the `x64 Native Tools Command Prompt for VS 2019` and type the following:
```sh ```sh
git clone --recurse-submodules https://github.com/opensourcerouting/c-capnproto git clone https://gitlab.com/diskuv-ocaml/ext/c-capnproto.git
cd c-capnproto cd c-capnproto
meson setup build cmake --preset=ci-windows_x86_64
meson compile -C build cmake --build --preset=ci-tests
build/capn-test
``` ```
## Usage ## Usage
@ -111,8 +109,8 @@ The project [`quagga-capnproto`](https://github.com/opensourcerouting/quagga-cap
## Status ## Status
This is a merge of 3 forks of [James McKaskill's great https://github.com/opensourcerouting/c-capnproto was a merge of 3 forks of [James McKaskill's great
work](https://github.com/jmckaskill/c-capnproto), which has been untouched for work](https://github.com/jmckaskill/c-capnproto), which had been untouched for
a while: a while:
- [liamstask's fork](https://github.com/liamstask/c-capnproto) - [liamstask's fork](https://github.com/liamstask/c-capnproto)

View file

@ -0,0 +1,66 @@
# Run locally the -asanSanitizer with:
# rm -rf build/
# ./dk dksdk.cmake.link
# .ci/cmake/bin/cmake --preset=ci-linux_x86_64-sanitizers-asan
# .ci/cmake/bin/ctest -S ci/ctest/Sanitizers-ASAN-CTest.cmake --extra-verbose
# Determine project directories
set(OUR_PROJECT_SOURCE_DIR "${CTEST_SCRIPT_DIRECTORY}/../..")
cmake_path(NORMAL_PATH OUR_PROJECT_SOURCE_DIR)
cmake_path(APPEND OUR_PROJECT_SOURCE_DIR build OUTPUT_VARIABLE OUR_PROJECT_BINARY_DIR)
# Re-use test details
include(${OUR_PROJECT_SOURCE_DIR}/CTestConfig.cmake)
# Read the CI generated CMakeCache.txt
load_cache("${OUR_PROJECT_BINARY_DIR}"
READ_WITH_PREFIX CACHED_
CMAKE_BUILD_TYPE)
# Basic information every run should set
site_name(CTEST_SITE)
set(CTEST_BUILD_NAME ${CMAKE_HOST_SYSTEM_NAME})
set(CTEST_SOURCE_DIRECTORY "${OUR_PROJECT_SOURCE_DIR}")
set(CTEST_BINARY_DIRECTORY "${OUR_PROJECT_BINARY_DIR}")
set(CTEST_CMAKE_GENERATOR Ninja)
if(CACHED_CMAKE_BUILD_TYPE)
set(CTEST_CONFIGURATION_TYPE ${CACHED_CMAKE_BUILD_TYPE})
else()
set(CTEST_CONFIGURATION_TYPE Debug)
endif()
set(CTEST_MEMORYCHECK_TYPE AddressSanitizer)
# ASAN_OPTIONS
# --------
#
# Even if we have [ASAN_OPTIONS] defined in CMakePresets.json,
# that will not impact this script which is invoked by `ctest` not
# `cmake`, and [CTEST_MEMORYCHECK_TYPE] will overwrite it anyway.
#
# Valgrind makes ASAN memory leaks redundant. And the unforked
# c-capnproto code disabled memory leaks anyway. So we use the
# same options.
set(extra_OPTIONS detect_leaks=0,detect_odr_violation=0,allocator_may_return_null=1)
# Apply to ctest_memcheck()
set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS ${extra_OPTIONS})
# Apply to ctest_build()
if(extra_OPTIONS)
if(ENV{ASAN_OPTIONS})
set(ENV{ASAN_OPTIONS} ${extra_OPTIONS}:$ENV{ASAN_OPTIONS})
else()
set(ENV{ASAN_OPTIONS} ${extra_OPTIONS})
endif()
endif()
ctest_start(Experimental)
ctest_build(RETURN_VALUE err)
if(err)
message(FATAL_ERROR "CTest build error ${err}")
endif()
ctest_memcheck(RETURN_VALUE err)
if(err)
message(FATAL_ERROR "CTest memcheck error ${err}")
endif()

View file

@ -0,0 +1,69 @@
# Run locally the -ubsan Sanitizer with:
# rm -rf build/
# ./dk dksdk.cmake.link
# .ci/cmake/bin/cmake --preset=ci-linux_x86_64-sanitizers-ubsan
# .ci/cmake/bin/ctest -S ci/ctest/Sanitizers-UBSAN-CTest.cmake --extra-verbose
# Determine project directories
if(NOT OUR_PROJECT_SOURCE_DIR)
set(OUR_PROJECT_SOURCE_DIR "${CTEST_SCRIPT_DIRECTORY}/../..")
cmake_path(NORMAL_PATH OUR_PROJECT_SOURCE_DIR)
endif()
if(NOT OUR_PROJECT_BINARY_DIR)
cmake_path(APPEND OUR_PROJECT_SOURCE_DIR build OUTPUT_VARIABLE OUR_PROJECT_BINARY_DIR)
endif()
# Re-use test details
include(${OUR_PROJECT_SOURCE_DIR}/CTestConfig.cmake)
# Read the CI generated CMakeCache.txt
load_cache("${OUR_PROJECT_BINARY_DIR}"
READ_WITH_PREFIX CACHED_
CMAKE_BUILD_TYPE)
# Basic information every run should set
site_name(CTEST_SITE)
set(CTEST_BUILD_NAME ${CMAKE_HOST_SYSTEM_NAME})
set(CTEST_SOURCE_DIRECTORY "${OUR_PROJECT_SOURCE_DIR}")
set(CTEST_BINARY_DIRECTORY "${OUR_PROJECT_BINARY_DIR}")
set(CTEST_CMAKE_GENERATOR Ninja)
if(CACHED_CMAKE_BUILD_TYPE)
set(CTEST_CONFIGURATION_TYPE ${CACHED_CMAKE_BUILD_TYPE})
else()
set(CTEST_CONFIGURATION_TYPE Debug)
endif()
# Tell CTest to add to UBSAN_OPTIONS to capture its logs
set(CTEST_MEMORYCHECK_TYPE UndefinedBehaviorSanitizer)
# UBSAN_OPTIONS
# --------
#
# Even if we have [UBSAN_OPTIONS] defined in CMakePresets.json,
# that will not impact this script which is invoked by `ctest` not
# `cmake`, and [CTEST_MEMORYCHECK_TYPE] will overwrite it anyway.
#
# Enable stack traces
set(extra_OPTIONS print_stacktrace=1)
# Apply to ctest_memcheck()
set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS ${extra_OPTIONS})
# Apply to ctest_build()
if(extra_OPTIONS)
if(ENV{UBSAN_OPTIONS})
set(ENV{UBSAN_OPTIONS} ${extra_OPTIONS}:$ENV{UBSAN_OPTIONS})
else()
set(ENV{UBSAN_OPTIONS} ${extra_OPTIONS})
endif()
endif()
ctest_start(Experimental)
ctest_build(RETURN_VALUE err)
if(err)
message(FATAL_ERROR "CTest build error ${err}")
endif()
ctest_memcheck(RETURN_VALUE err)
if(err)
message(FATAL_ERROR "CTest memcheck error ${err}")
endif()

View file

@ -0,0 +1,155 @@
.unit-test:
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "next"'
artifacts:
paths:
- build/Testing/Temporary/LastBuild_*.log
- build/Testing/Temporary/LastTest.log
- build/Testing/Temporary/LastTests_*.log
- build/Testing/Temporary/MemoryChecker.*.log
reports:
junit:
- build/cmakespec.xml
- build/tests/*-Results.xml
when: always
unit-test-debian:
stage: test
# The original c-capnproto unit tests were full of memory leaks (not closing test
# structures). Sigh. Until those are fixed, we can't detect real memory leaks.
allow_failure: true
extends:
- .c-cmake-debian:before
- .unit-test
script:
- export PATH="$PWD/.ci/cmake/bin:$PATH"
- echo -e "\e[0Ksection_start:`date +%s`:configure[collapsed=true]\r\e[0KConfiguring build scripts"
- rm -rf build/
- cmake --preset=ci-linux_x86_64 -D BUILD_HYGIENE=ENABLED
- echo -e "\e[0Ksection_end:`date +%s`:configure\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:build[collapsed=true]\r\e[0KBuilding test targets"
- cmake --build --preset=ci-tests
- echo -e "\e[0Ksection_end:`date +%s`:build\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:unittest[collapsed=true]\r\e[0KUnit Testing"
- ctest --output-junit cmakespec.xml --verbose --preset=ci-test
- echo -e "\e[0Ksection_end:`date +%s`:unittest\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:memcheck[collapsed=true]\r\e[0KMemory Testing"
- ctest -T memcheck --test-dir build --verbose
- echo -e "\e[0Ksection_end:`date +%s`:memcheck\r\e[0K"
unit-test-android_x86_64:
stage: test
extends:
- .c-cmake-debian:before
- .unit-test
script:
- export PATH="$PWD/.ci/cmake/bin:$PATH"
- echo -e "\e[0Ksection_start:`date +%s`:installandroid[collapsed=true]\r\e[0KInstalling Android NDK"
- ./dk dksdk.android.ndk.download
- echo -e "\e[0Ksection_end:`date +%s`:installandroid\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:configure[collapsed=true]\r\e[0KConfiguring build scripts"
- rm -rf build/
- cmake --preset=ci-linux_x86_64_X_android_x86_64
- echo -e "\e[0Ksection_end:`date +%s`:configure\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:build[collapsed=true]\r\e[0KBuilding test targets"
- cmake --build --preset=ci-tests
- echo -e "\e[0Ksection_end:`date +%s`:build\r\e[0K"
- echo 'No unit tests and no memory tests for a cross-compiled target'
unit-test-windows:
stage: test
extends:
- .c-cmake-windows:before
- .unit-test
script:
- $env:Path += ';C:\Program Files\CMake\bin'
- $esc="$([char]27)"; $cr="$([char]13)"; $TXT_SECTION="${esc}[36m"; $TXT_CLEAR="${esc}[0m"
- |
function Get-CurrentEpochSecs {
[long]$timestamp = [math]::Round((([datetime]::UtcNow) - (Get-Date -Date '1/1/1970')).TotalMilliseconds)
[math]::Round($timestamp / 1000)
}
- Write-Host "${esc}[0Ksection_start:$(Get-CurrentEpochSecs):configure[collapsed=true]${cr}${esc}[0K"$TXT_SECTION"Configuring build scripts"
- if (Test-Path build) { Remove-Item -Recurse -Force build }
# Linux can test with BUILD_HYGIENE=ENABLED. Don't want to install clang-tidy through
# Chocolatey because huge LLVM download (`choco install llvm`).
- ci/run-with-msvc.cmd cmake --preset=ci-windows_x86_64 -D BUILD_HYGIENE=DISABLED
- Write-Host "${esc}[0Ksection_end:$(Get-CurrentEpochSecs):configure${cr}${esc}[0K"
- Write-Host "${esc}[0Ksection_start:$(Get-CurrentEpochSecs):build[collapsed=true]${cr}${esc}[0K"$TXT_SECTION"Building test targets"
- ci/run-with-msvc.cmd cmake --build --preset=ci-tests
- Write-Host "${esc}[0Ksection_end:$(Get-CurrentEpochSecs):build${cr}${esc}[0K"
- Write-Host "${esc}[0Ksection_start:$(Get-CurrentEpochSecs):unittest[collapsed=true]${cr}${esc}[0K"$TXT_SECTION"Unit Testing"
- ci/run-with-msvc.cmd ctest --output-junit cmakespec.xml --verbose --preset=ci-test
- Write-Host "${esc}[0Ksection_end:$(Get-CurrentEpochSecs):unittest${cr}${esc}[0K"
sanitizers-debian-asan:
stage: test
extends:
- .c-cmake-debian:before
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "next"'
artifacts:
paths:
- build/Testing/Temporary/LastBuild_*.log
- build/Testing/Temporary/LastDynamicAnalysis_*.log
- build/Testing/Temporary/LastTest.log
- build/Testing/Temporary/LastTests_*.log
- build/Testing/Temporary/MemoryChecker.*.log
reports:
junit:
- build/cmakespec.xml
- build/tests/*-Results.xml
when: always
script:
- export PATH="$PWD/.ci/cmake/bin:$PATH"
- echo -e "\e[0Ksection_start:`date +%s`:configure[collapsed=true]\r\e[0KConfiguring build scripts"
- rm -rf build/
- cmake --preset=ci-linux_x86_64-sanitizers-asan
- echo -e "\e[0Ksection_end:`date +%s`:configure\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:build[collapsed=true]\r\e[0KRunning ASAN sanitizers build and check"
- ctest -S ci/ctest/Sanitizers-ASAN-CTest.cmake
- echo -e "\e[0Ksection_end:`date +%s`:build\r\e[0K"
sanitizers-debian-ubsan:
stage: test
extends:
- .c-cmake-debian:before
rules:
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "next"'
artifacts:
paths:
- build/Testing/Temporary/LastBuild_*.log
- build/Testing/Temporary/LastDynamicAnalysis_*.log
- build/Testing/Temporary/LastTest.log
- build/Testing/Temporary/LastTests_*.log
- build/Testing/Temporary/MemoryChecker.*.log
reports:
junit:
- build/cmakespec.xml
- build/tests/*-Results.xml
when: always
script:
- export PATH="$PWD/.ci/cmake/bin:$PATH"
- echo -e "\e[0Ksection_start:`date +%s`:configure[collapsed=true]\r\e[0KConfiguring build scripts"
- rm -rf build/
- cmake --preset=ci-linux_x86_64-sanitizers-ubsan
- echo -e "\e[0Ksection_end:`date +%s`:configure\r\e[0K"
- echo -e "\e[0Ksection_start:`date +%s`:build[collapsed=true]\r\e[0KRunning UBSAN sanitizers build and check"
- ctest -S ci/ctest/Sanitizers-UBSAN-CTest.cmake
- echo -e "\e[0Ksection_end:`date +%s`:build\r\e[0K"

3
ci/run-with-msvc.cmd Normal file
View file

@ -0,0 +1,3 @@
CALL "%VSDIR%\VC\Auxiliary\Build\vcvars64.bat"
ECHO ON
%*

View file

@ -0,0 +1,88 @@
# Recommendation: Place this file in source control.
# Auto-generated by `./dk dksdk.project.new` of DkHelloWorld.
include(FetchContent)
function(parse_dktool_command_line)
# The first argument is <command>. All dots will be replaced with a
# triple underscore as a convenience and to be pretty for the user.
if(ARGC EQUAL 0)
message(FATAL_ERROR "Missing <command>. Usage: ./dk <command> [args]")
endif()
set(command ${ARGV0})
string(REPLACE "." "___" function_name ${command})
# Set policies (we are in a new EVAL CODE context)
# Included scripts do automatic cmake_policy PUSH and POP
if(POLICY CMP0011)
cmake_policy(SET CMP0011 NEW)
endif()
# Setup the binary directory
if(NOT DKTOOL_WORKDIR)
message(FATAL_ERROR "Illegal state. Expecting DKTOOL_WORKDIR")
endif()
set(CMAKE_BINARY_DIR ${DKTOOL_WORKDIR})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR})
# Include all the user scripts
file(GLOB_RECURSE command_files LIST_DIRECTORIES FALSE
cmake/scripts/*.cmake)
foreach(command_file IN LISTS command_files)
include(${command_file})
endforeach()
# Include all the system scripts.
# - Since the system scripts come after the user scripts, the user scripts
# don't override the system scripts unless the user scripts use deferred
# hooks or redefine CMake built-in functions.
if(NOT IS_DIRECTORY cmake/scripts/dksdk)
# If this project (ex. DkHelloWorld) has the system scripts, it must
# have all of them. Otherwise we download the system scripts.
FetchContent_Populate(DkHelloWorld
QUIET
GIT_REPOSITORY https://gitlab.com/diskuv/samples/DkHelloWorld.git
GIT_TAG 1.0
)
file(GLOB_RECURSE system_command_files LIST_DIRECTORIES FALSE
${dkhelloworld_SOURCE_DIR}/cmake/scripts/dksdk/*.cmake)
list(APPEND command_files ${system_command_files})
foreach(command_file IN LISTS system_command_files)
include(${command_file})
endforeach()
endif()
# Validate the <command> exists
if(NOT COMMAND ${function_name})
set(pretty_command_files ${command_files})
list(TRANSFORM pretty_command_files PREPEND " ")
list(TRANSFORM pretty_command_files APPEND "\n")
string(JOIN "" str_pretty_command_files ${pretty_command_files})
message(FATAL_ERROR "No command '${command}' exists. The function '${function_name}' was searched in the following locations:
${str_pretty_command_files}")
endif()
# Parse the remainder of the arguments [args]
# * Use technique from [Professional CMake: A Practical Guide - Forwarding Command Arguments]
# to forward arguments correctly to an inner function (the <command> function).
cmake_parse_arguments(PARSE_ARGV 1 FWD "" "" "")
set(quotedArgs "")
foreach(arg IN LISTS FWD_UNPARSED_ARGUMENTS)
string(APPEND quotedArgs " [===[${arg}]===]")
endforeach()
# Call the <command> function
cmake_language(EVAL CODE "${function_name}(${quotedArgs})")
endfunction()
# DkSDK data home
if(WIN32)
set(DKSDK_DATA_HOME "$ENV{LOCALAPPDATA}/Programs/DkSDK")
elseif(DEFINED ENV{XDG_DATA_HOME})
set(DKSDK_DATA_HOME "$ENV{XDG_DATA_HOME}/dksdk")
else()
set(DKSDK_DATA_HOME "$ENV{HOME}/.local/share/dksdk")
endif()
# Splat DKTOOL_CMDLINE
cmake_language(EVAL CODE "parse_dktool_command_line(${DKTOOL_CMDLINE})")

701
dk Executable file
View file

@ -0,0 +1,701 @@
#!/bin/sh
# Recommendation: Place this file in source control.
# Auto-generated by `./dk dksdk.project.new` of DkHelloWorld.
#
# Invoking: ./dk
# That works in Powershell on Windows, and in Unix. Copy-and-paste works!
#
# Purpose: Install CMake if not already. Then invoke CMake.
set -euf
# --- Imports of dkml-runtime-common's crossplatform-functions.sh ---
# Get standard locations of Unix system binaries like `/usr/bin/mv` (or `/bin/mv`).
#
# Will not return anything in `/usr/local/bin` or `/usr/sbin`. Use when you do not
# know whether the PATH has been set correctly, or when you do not know if the
# system binary exists.
#
# At some point in the future, this function will error out if the required system binaries
# do not exist. Most system binaries are common to all Unix/Linux/macOS installations but
# some (like `comm`) may need to be installed for proper functioning of DKML.
#
# Outputs:
# - env:DKMLSYS_MV - Location of `mv`
# - env:DKMLSYS_CHMOD - Location of `chmod`
# - env:DKMLSYS_UNAME - Location of `uname`
# - env:DKMLSYS_ENV - Location of `env`
# - env:DKMLSYS_AWK - Location of `awk`
# - env:DKMLSYS_SED - Location of `sed`
# - env:DKMLSYS_COMM - Location of `comm`
# - env:DKMLSYS_INSTALL - Location of `install`
# - env:DKMLSYS_RM - Location of `rm`
# - env:DKMLSYS_SORT - Location of `sort`
# - env:DKMLSYS_CAT - Location of `cat`
# - env:DKMLSYS_STAT - Location of `stat`
# - env:DKMLSYS_GREP - Location of `grep`
# - env:DKMLSYS_CURL - Location of `curl` (empty if not found)
# - env:DKMLSYS_WGET - Location of `wget` (empty if not found)
# - env:DKMLSYS_TR - Location of `tr`
autodetect_system_binaries() {
if [ -z "${DKMLSYS_MV:-}" ]; then
if [ -x /usr/bin/mv ]; then
DKMLSYS_MV=/usr/bin/mv
else
DKMLSYS_MV=/bin/mv
fi
fi
if [ -z "${DKMLSYS_CHMOD:-}" ]; then
if [ -x /usr/bin/chmod ]; then
DKMLSYS_CHMOD=/usr/bin/chmod
else
DKMLSYS_CHMOD=/bin/chmod
fi
fi
if [ -z "${DKMLSYS_UNAME:-}" ]; then
if [ -x /usr/bin/uname ]; then
DKMLSYS_UNAME=/usr/bin/uname
else
DKMLSYS_UNAME=/bin/uname
fi
fi
if [ -z "${DKMLSYS_ENV:-}" ]; then
if [ -x /usr/bin/env ]; then
DKMLSYS_ENV=/usr/bin/env
else
DKMLSYS_ENV=/bin/env
fi
fi
if [ -z "${DKMLSYS_AWK:-}" ]; then
if [ -x /usr/bin/awk ]; then
DKMLSYS_AWK=/usr/bin/awk
else
DKMLSYS_AWK=/bin/awk
fi
fi
if [ -z "${DKMLSYS_SED:-}" ]; then
if [ -x /usr/bin/sed ]; then
DKMLSYS_SED=/usr/bin/sed
else
DKMLSYS_SED=/bin/sed
fi
fi
if [ -z "${DKMLSYS_COMM:-}" ]; then
if [ -x /usr/bin/comm ]; then
DKMLSYS_COMM=/usr/bin/comm
else
DKMLSYS_COMM=/bin/comm
fi
fi
if [ -z "${DKMLSYS_INSTALL:-}" ]; then
if [ -x /usr/bin/install ]; then
DKMLSYS_INSTALL=/usr/bin/install
else
DKMLSYS_INSTALL=/bin/install
fi
fi
if [ -z "${DKMLSYS_RM:-}" ]; then
if [ -x /usr/bin/rm ]; then
DKMLSYS_RM=/usr/bin/rm
else
DKMLSYS_RM=/bin/rm
fi
fi
if [ -z "${DKMLSYS_SORT:-}" ]; then
if [ -x /usr/bin/sort ]; then
DKMLSYS_SORT=/usr/bin/sort
else
DKMLSYS_SORT=/bin/sort
fi
fi
if [ -z "${DKMLSYS_CAT:-}" ]; then
if [ -x /usr/bin/cat ]; then
DKMLSYS_CAT=/usr/bin/cat
else
DKMLSYS_CAT=/bin/cat
fi
fi
if [ -z "${DKMLSYS_STAT:-}" ]; then
if [ -x /usr/bin/stat ]; then
DKMLSYS_STAT=/usr/bin/stat
else
DKMLSYS_STAT=/bin/stat
fi
fi
if [ -z "${DKMLSYS_GREP:-}" ]; then
if [ -x /usr/bin/grep ]; then
DKMLSYS_GREP=/usr/bin/grep
else
DKMLSYS_GREP=/bin/grep
fi
fi
if [ -z "${DKMLSYS_CURL:-}" ]; then
if [ -x /usr/bin/curl ]; then
DKMLSYS_CURL=/usr/bin/curl
elif [ -x /bin/curl ]; then
DKMLSYS_CURL=/bin/curl
else
DKMLSYS_CURL=
fi
fi
if [ -z "${DKMLSYS_WGET:-}" ]; then
if [ -x /usr/bin/wget ]; then
DKMLSYS_WGET=/usr/bin/wget
elif [ -x /bin/wget ]; then
DKMLSYS_WGET=/bin/wget
else
DKMLSYS_WGET=
fi
fi
if [ -z "${DKMLSYS_TR:-}" ]; then
if [ -x /usr/bin/tr ]; then
DKMLSYS_TR=/usr/bin/tr
else
DKMLSYS_TR=/bin/tr
fi
fi
export DKMLSYS_MV DKMLSYS_CHMOD DKMLSYS_UNAME DKMLSYS_ENV DKMLSYS_AWK DKMLSYS_SED DKMLSYS_COMM DKMLSYS_INSTALL
export DKMLSYS_RM DKMLSYS_SORT DKMLSYS_CAT DKMLSYS_STAT DKMLSYS_GREP DKMLSYS_CURL DKMLSYS_WGET DKMLSYS_TR
}
# Is a Windows build machine if we are in a MSYS2 or Cygwin environment.
#
# Better alternatives
# -------------------
#
# 1. If you are checking to see if you should do a cygpath, then just guard it
# like so:
# if [ -x /usr/bin/cygpath ]; then
# do_something $(/usr/bin/cygpath ...) ...
# fi
# This clearly guards what you are about to do (cygpath) with what you will
# need (cygpath).
# 2. is_arg_windows_platform
is_unixy_windows_build_machine() {
if is_msys2_msys_build_machine || is_cygwin_build_machine; then
return 0
fi
return 1
}
# Is a MSYS2 environment with the MSYS or MINGW64 subsystem?
# * MSYS2 can also do MinGW 32-bit and 64-bit subsystems. Used by Diskuv OCaml
# * MINGW64 used by Git Bash (aka. GitHub Actions `shell: bash`)
# https://www.msys2.org/docs/environments/
is_msys2_msys_build_machine() {
if [ -e /usr/bin/msys-2.0.dll ] && {
[ "${MSYSTEM:-}" = "MSYS" ] || [ "${MSYSTEM:-}" = "MINGW64" ] || [ "${MSYSTEM:-}" = "UCRT64" ] || [ "${MSYSTEM:-}" = "CLANG64" ] || [ "${MSYSTEM:-}" = "MINGW32" ] || [ "${MSYSTEM:-}" = "CLANG32" ] || [ "${MSYSTEM:-}" = "CLANGARM64" ]
}; then
return 0
fi
return 1
}
is_cygwin_build_machine() {
if [ -e /usr/bin/cygwin1.dll ]; then
return 0
fi
return 1
}
# Tries to find the host ABI.
#
# Beware: This function uses `uname` probing which is inaccurate during
# cross-compilation.
#
# Outputs:
# - env:BUILDHOST_ARCH will contain the host ABI.
autodetect_buildhost_arch() {
# Set DKMLSYS_*
autodetect_system_binaries
autodetect_buildhost_arch_SYSTEM=$("$DKMLSYS_UNAME" -s)
autodetect_buildhost_arch_MACHINE=$("$DKMLSYS_UNAME" -m)
# list from https://en.wikipedia.org/wiki/Uname and https://stackoverflow.com/questions/45125516/possible-values-for-uname-m
case "${autodetect_buildhost_arch_SYSTEM}-${autodetect_buildhost_arch_MACHINE}" in
Linux-armv7*)
BUILDHOST_ARCH=linux_arm32v7;;
Linux-armv6* | Linux-arm)
BUILDHOST_ARCH=linux_arm32v6;;
Linux-aarch64 | Linux-arm64 | Linux-armv8*)
BUILDHOST_ARCH=linux_arm64;;
Linux-i386 | Linux-i686)
BUILDHOST_ARCH=linux_x86;;
Linux-x86_64)
BUILDHOST_ARCH=linux_x86_64;;
Darwin-arm64)
BUILDHOST_ARCH=darwin_arm64;;
Darwin-x86_64)
BUILDHOST_ARCH=darwin_x86_64;;
*-i386 | *-i686)
if is_unixy_windows_build_machine; then
BUILDHOST_ARCH=windows_x86
else
printf "%s\n" "FATAL: Unsupported build machine type obtained from 'uname -s' and 'uname -m': $autodetect_buildhost_arch_SYSTEM and $autodetect_buildhost_arch_MACHINE" >&2
exit 1
fi
;;
*-x86_64)
if is_unixy_windows_build_machine; then
BUILDHOST_ARCH=windows_x86_64
else
printf "%s\n" "FATAL: Unsupported build machine type obtained from 'uname -s' and 'uname -m': $autodetect_buildhost_arch_SYSTEM and $autodetect_buildhost_arch_MACHINE" >&2
exit 1
fi
;;
*)
# Since:
# 1) MSYS2 does not run on ARM/ARM64 (https://www.msys2.org/docs/environments/)
# 2) MSVC does not use ARM/ARM64 as host machine (https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-160)
# we do not support Windows ARM/ARM64 as a build machine
printf "%s\n" "FATAL: Unsupported build machine type obtained from 'uname -s' and 'uname -m': $autodetect_buildhost_arch_SYSTEM and $autodetect_buildhost_arch_MACHINE" >&2
exit 1
;;
esac
}
# A function that will try to print an ISO8601 timestamp, but will fallback to
# the system default. Always uses UTC timezone.
try_iso8601_timestamp() {
date -u -Iseconds 2>/dev/null || TZ=UTC date
}
# A function that will print the command and possibly time it (if and only if it uses a full path to
# an executable, so that 'time' does not fail on internal shell functions).
# If --return-error-code is the first argument or LOG_TRACE_RETURN_ERROR_CODE=ON, then instead of exiting the
# function will return the error code.
log_trace() {
log_trace_RETURN=${LOG_TRACE_RETURN_ERROR_CODE:-OFF}
log_trace_1="$1"
if [ "$log_trace_1" = "--return-error-code" ]; then
shift
log_trace_RETURN=ON
fi
if [ "${DKML_BUILD_TRACE:-OFF}" = ON ]; then
printf "[%s] %s\n" "$(try_iso8601_timestamp)" "+ $*" >&2
if [ -x "$1" ]; then
time "$@"
else
"$@"
fi
else
# use judgement so we essentially have log at an INFO level
case "$1" in
rm|cp)
# debug level. only show when DKML_BUILD_TRACE=ON
;;
git|make|ocaml_configure|ocaml_make|make_host|make_target)
# info level. and can show entire command without polluting the screen
printf "[%s] %s\n" "$(try_iso8601_timestamp)" "$*" >&2
;;
*) printf "[%s] %s\n" "$(try_iso8601_timestamp)" "$1" >&2
esac
"$@"
fi
log_trace_ec="$?"
if [ "$log_trace_ec" -ne 0 ]; then
if [ "$log_trace_RETURN" = ON ]; then
return "$log_trace_ec"
else
printf "FATAL: Command failed with exit code %s: %s\n" "$log_trace_ec" "$*" >&2
exit "$log_trace_ec"
fi
fi
}
# [sha256compute FILE] writes the SHA256 checksum (hex encoded) of file FILE to the standard output.
sha256compute() {
sha256compute_FILE="$1"
shift
# For reasons unclear doing the following in MSYS2:
# sha256sum 'Z:\source\README.md'
# will produce a backslash like:
# \5518c76ed7234a153941fb7bc94b6e91d9cb8f1c4e22daf169a59b5878c3fc8a *Z:\\source\\README.md
# So always cygpath the filename if available
if [ -x /usr/bin/cygpath ]; then
sha256compute_FILE=$(/usr/bin/cygpath -a "$sha256compute_FILE")
fi
if [ -x /usr/bin/shasum ]; then
/usr/bin/shasum -a 256 "$sha256compute_FILE" | awk '{print $1}'
elif [ -x /usr/bin/sha256sum ]; then
/usr/bin/sha256sum "$sha256compute_FILE" | awk '{print $1}'
else
printf "FATAL: %s\n" "No sha256 checksum utility found" >&2
exit 107
fi
}
# [sha256check FILE SUM] checks that the file FILE has a SHA256 checksum (hex encoded) of SUM.
# The function will return nonzero (and exit with failure if `set -e` is enabled) if the checksum does not match.
sha256check() {
sha256check_FILE="$1"
shift
sha256check_SUM="$1"
shift
if [ -x /usr/bin/shasum ]; then
printf "%s %s" "$sha256check_SUM" "$sha256check_FILE" | /usr/bin/shasum -a 256 -c >&2
elif [ -x /usr/bin/sha256sum ]; then
printf "%s %s" "$sha256check_SUM" "$sha256check_FILE" | /usr/bin/sha256sum -c >&2
else
printf "FATAL: %s\n" "No sha256 checksum utility found" >&2
exit 107
fi
}
# [downloadfile URL FILE SUM] downloads from URL into FILE and verifies the SHA256 checksum of SUM.
# If the FILE already exists with the correct checksum it is not redownloaded.
# The function will exit with failure if the checksum does not match.
downloadfile() {
downloadfile_URL="$1"
shift
downloadfile_FILE="$1"
shift
downloadfile_SUM="$1"
shift
# Set DKMLSYS_*
autodetect_system_binaries
if [ -e "$downloadfile_FILE" ]; then
if sha256check "$downloadfile_FILE" "$downloadfile_SUM"; then
return 0
else
$DKMLSYS_RM -f "$downloadfile_FILE"
fi
fi
if [ "${CI:-}" = true ]; then
if [ -n "$DKMLSYS_CURL" ]; then
log_trace "$DKMLSYS_CURL" -L -s "$downloadfile_URL" -o "$downloadfile_FILE".tmp
elif [ -n "$DKMLSYS_WGET" ]; then
log_trace "$DKMLSYS_WGET" -q -O "$downloadfile_FILE".tmp "$downloadfile_URL"
else
echo "No curl or wget available on the system paths" >&2
exit 107
fi
else
if [ -n "$DKMLSYS_CURL" ]; then
log_trace "$DKMLSYS_CURL" -L "$downloadfile_URL" -o "$downloadfile_FILE".tmp
elif [ -n "$DKMLSYS_WGET" ]; then
log_trace "$DKMLSYS_WGET" -O "$downloadfile_FILE".tmp "$downloadfile_URL"
else
echo "No curl or wget available on the system paths" >&2
exit 107
fi
fi
if ! sha256check "$downloadfile_FILE".tmp "$downloadfile_SUM"; then
printf "%s\n" "FATAL: Encountered a corrupted or compromised download from $downloadfile_URL" >&2
exit 1
fi
$DKMLSYS_MV "$downloadfile_FILE".tmp "$downloadfile_FILE"
}
# --- Environment detection ---
# Set DKMLSYS_*
autodetect_system_binaries
# Find host ABI. Set in BUILDHOST_ARCH
autodetect_buildhost_arch
# Use the project tree as the current directory
PROJ_DIR=$(dirname "$0")
PROJ_DIR=$(cd "$PROJ_DIR" && pwd)
cd "$PROJ_DIR"
# --- Tool directory selection ---
tools_dir=
tools_name=dktool
# 1. Check if CI since many CI providers can only cache content in a subdirectory
# of the project.
if [ -z "$tools_dir" ] && [ "${CI:-}" = true ]; then
install -d "$PROJ_DIR/.tools"
tools_dir="$PROJ_DIR/.tools"
fi
# 2. Check in locations rooted under /opt/diskuv
# We look under a /opt/diskuv early because
# - Especially important for WSL2 to use a pure Linux filesystem (ext4) for
# best performance.
# - Using a canonical location (especially /opt/diskuv/usr/share) makes
# it easy to use CMake presets for non-Windows hosts.
if [ -z "$tools_dir" ] && [ -n "${XDG_DATA_HOME:-}" ] && [ -w "/opt/diskuv/$XDG_DATA_HOME" ]; then
install -d "/opt/diskuv/$XDG_DATA_HOME/$tools_name"
tools_dir="/opt/diskuv/$XDG_DATA_HOME/$tools_name"
fi
if [ -z "$tools_dir" ] && [ -n "${HOME:-}" ] && [ -w "/opt/diskuv/$HOME" ]; then
install -d "/opt/diskuv/$HOME/.local/share/$tools_name"
tools_dir="/opt/diskuv/$HOME/.local/share/$tools_name"
fi
if [ -z "$tools_dir" ] && [ -w "/opt/diskuv/usr/share" ]; then
install -d "/opt/diskuv/usr/share/$tools_name"
tools_dir="/opt/diskuv/usr/share/$tools_name"
fi
# 3. Check in the conventional locations rooted under /
if [ -z "$tools_dir" ] && [ -n "${XDG_DATA_HOME:-}" ] && [ -w "$XDG_DATA_HOME" ]; then
install -d "$XDG_DATA_HOME/$tools_name"
tools_dir="$XDG_DATA_HOME/$tools_name"
fi
if [ -z "$tools_dir" ] && [ -n "${HOME:-}" ] && [ -w "$HOME" ]; then
install -d "$HOME/.local/share/$tools_name"
tools_dir="$HOME/.local/share/$tools_name"
fi
# 4. Validate
if [ -z "$tools_dir" ]; then
echo "FATAL: Could not find a location to install the tools necessary for this project." >&2
echo " ...: Make sure you have a home directory and that it is write-able, or define" >&2
echo " ...: the environment variable XDG_DATA_HOME in a shell profile script after" >&2
echo " ...: creating the \$XDG_DATA_HOME directory." >&2
exit 2
fi
# --- Tool downloads and installs ---
# PREREQS
# -------
install_linux_prog() {
install_linux_prog_NAME=$1
shift
install_linux_prog_PKG=$1
shift
if [ -x "/usr/bin/$install_linux_prog_NAME" ]; then
export DK_PROG_INSTALLED_LOCATION="/usr/bin/$install_linux_prog_NAME"
else
if command -v yum > /dev/null 2> /dev/null; then
if [ "$(id -u)" -eq 0 ]; then
yum install -y "$install_linux_prog_PKG"
else
echo "Running: sudo yum install -y $install_linux_prog_PKG"
sudo yum install -y "$install_linux_prog_PKG"
fi
else
if [ "$(id -u)" -eq 0 ]; then
apt-get -q install -y "$install_linux_prog_PKG"
else
echo "Running: sudo -q apt-get -qq install -y --no-install-suggests $install_linux_prog_PKG"
sudo apt-get -qq install -y --no-install-suggests "$install_linux_prog_PKG"
fi
fi
DK_PROG_INSTALLED_LOCATION=$(command -v "$install_linux_prog_NAME")
export DK_PROG_INSTALLED_LOCATION
fi
}
get_homebrew_binary() {
get_homebrew_binary_NAME=$1
shift
if command -v brew > /dev/null 2> /dev/null; then
get_homebrew_binary_PREFIX=$(brew --prefix)
if [ -x "$get_homebrew_binary_PREFIX/bin/$get_homebrew_binary_NAME" ]; then
export DK_PROG_INSTALLED_LOCATION="$get_homebrew_binary_PREFIX/bin/$get_homebrew_binary_NAME"
return 0
fi
fi
return 1
}
install_macos_prog() {
install_macos_prog_NAME=$1
shift
install_macos_prog_PKG=$1
shift
if [ -x "/usr/bin/$install_macos_prog_NAME" ]; then
export DK_PROG_INSTALLED_LOCATION="/usr/bin/$install_macos_prog_NAME"
elif [ -x "/usr/local/bin/$install_macos_prog_NAME" ]; then
export DK_PROG_INSTALLED_LOCATION="/usr/local/bin/$install_macos_prog_NAME"
elif get_homebrew_binary "$install_macos_prog_NAME"; then
# DK_PROG_INSTALLED_LOCATION already set by [get_homebrew_binary]
true
else
if command -v brew > /dev/null 2> /dev/null; then
brew install --quiet --formula "$install_macos_prog_PKG" >&2
get_homebrew_binary "$install_macos_prog_NAME"
# DK_PROG_INSTALLED_LOCATION already set by [get_homebrew_binary]
elif command -v port > /dev/null 2> /dev/null; then
if [ "$(id -u)" -eq 0 ]; then
port install "$install_macos_prog_PKG"
else
echo "Running: sudo port install $install_macos_prog_PKG"
sudo port install "$install_macos_prog_PKG"
fi
DK_PROG_INSTALLED_LOCATION=$(command -v "$install_macos_prog_NAME")
export DK_PROG_INSTALLED_LOCATION
else
echo "FATAL: Neither Homebrew nor MacPorts are available on your macOS. You can follow https://docs.brew.sh/Installation to install Homebrew." >&2
exit 2
fi
fi
}
case $BUILDHOST_ARCH in
linux_*)
install_linux_prog wget wget # For [downloadfile]
install_linux_prog tar tar # For handling tar balls later in this script
;;
esac
# NINJA
# -----
# We need a valid CMAKE_GENERATOR to do FetchContent_Populate() in script mode
NINJA_EXE=
case $BUILDHOST_ARCH in
darwin_*)
install_macos_prog ninja ninja
NINJA_EXE=$DK_PROG_INSTALLED_LOCATION;;
linux_*)
install_linux_prog ninja ninja-build
NINJA_EXE=$DK_PROG_INSTALLED_LOCATION;;
esac
# CMAKE
# -----
case $BUILDHOST_ARCH in
linux_*)
# This is for CMake to do FetchContent()
install_linux_prog git git ;;
esac
case $BUILDHOST_ARCH in
linux_x86)
# This is for Python wheel extraction
install_linux_prog unzip unzip ;;
esac
cmake_base=
cmake_majmin_ver=3.25
cmake_majminpat_ver=3.25.2
cmake_bindir=
cmake_destdir=$tools_dir/cmake-$cmake_majminpat_ver
install -d "$tools_dir/dl"
download_cmake() {
case $BUILDHOST_ARCH in
darwin_*)
install_macos_prog cmake cmake
cmake_bindir=$(dirname "$DK_PROG_INSTALLED_LOCATION")
;;
linux_x86_64)
cmake_base="cmake-$cmake_majminpat_ver-linux-x86_64"
printf "%s\n\n" "-- Downloading cmake-$cmake_majminpat_ver for Linux x86_64" >&2
downloadfile \
"https://github.com/Kitware/CMake/releases/download/v$cmake_majminpat_ver/$cmake_base.tar.gz" \
"$tools_dir/dl/cmake.tar.gz" \
783da74f132fd1fea91b8236d267efa4df5b91c5eec1dea0a87f0cf233748d99
cmake_bindir="$cmake_destdir/bin" ;;
linux_x86)
# CMake does not provide 32-bit binaries. But pypi does at https://pypi.org/project/cmake/
printf "%s\n\n" "-- Downloading cmake-$cmake_majminpat_ver for Linux x86" >&2
downloadfile \
https://files.pythonhosted.org/packages/11/6e/aeeddf2f5b16542b6a30ceab4896421e8705d8e9a9296dba79395db11b00/cmake-3.25.2-py2.py3-none-manylinux_2_17_i686.manylinux2014_i686.whl \
"$tools_dir/dl/cmake.whl" \
715ef82e81b48db3e4c7744614c15ff361d53f6987fd70b1b66b0880595f2e2c
cmake_bindir="$cmake_destdir/bin" ;;
linux_arm64)
cmake_base="cmake-$cmake_majminpat_ver-linux-aarch64"
printf "%s\n\n" "-- Downloading cmake-$cmake_majminpat_ver for Linux ARM64" >&2
downloadfile \
"https://github.com/Kitware/CMake/releases/download/v$cmake_majminpat_ver/$cmake_base.tar.gz" \
"$tools_dir/dl/cmake.tar.gz" \
9216ecf0449ade700e66e0def11eeaebf9fa7d4428c02f49cb59f11418d3f8a5
cmake_bindir="$cmake_destdir/bin" ;;
esac
}
export_cmake_vars() {
case $BUILDHOST_ARCH in
darwin_*)
if command -v brew > /dev/null 2> /dev/null; then
cmake_bindir=$(brew --prefix cmake)/bin
else
cmake_bindir=$(command -v cmake)
cmake_bindir=$(dirname "$cmake_bindir")
fi
;;
linux_x86_64)
cmake_bindir="$cmake_destdir/bin" ;;
linux_x86)
cmake_bindir="$cmake_destdir/bin" ;;
esac
}
have_correct_cmake=0
if [ -x "$tools_dir/cmake-$cmake_majminpat_ver/bin/cmake" ]; then
# shellcheck disable=SC2016
have_correct_cmake_VER=$("$tools_dir/cmake-$cmake_majminpat_ver/bin/cmake" --version | $DKMLSYS_AWK 'NR==1{print $NF}')
if [ "$have_correct_cmake_VER" = "$cmake_majminpat_ver" ]; then
have_correct_cmake=1
fi
fi
if [ $have_correct_cmake -eq 0 ]; then
download_cmake
fi
# Handle tarball
if [ -e "$tools_dir/dl/cmake.tar.gz" ] && [ -n "$cmake_base" ]; then
rm -rf "$tools_dir/cmake-$cmake_majminpat_ver"
install -d "$cmake_destdir"
tar xCfz "$cmake_destdir" "$tools_dir/dl/cmake.tar.gz"
rm -f "$tools_dir/dl/cmake.tar.gz"
set +f
if [ -e "$cmake_destdir/$cmake_base/CMake.app" ]; then
mv "$cmake_destdir/$cmake_base/CMake.app/Contents"/* "$cmake_destdir/"
else
mv "$cmake_destdir/$cmake_base"/* "$cmake_destdir/"
fi
set -f
fi
# Handle Python wheel
if [ -e "$tools_dir/dl/cmake.whl" ]; then
rm -rf "$tools_dir/cmake-$cmake_majminpat_ver"
cd "$tools_dir/dl"
rm -rf cmake/data
# Don't want cmake/data/{aclocal,bash-completion,emacs,vim}
unzip -q cmake.whl 'cmake/data/bin/**'
unzip -q cmake.whl 'cmake/data/doc/**'
# Don't want cmake/data/share/cmake-$cmake_majmin_ver/Help
unzip -q cmake.whl "cmake/data/share/cmake-$cmake_majmin_ver/"'include/**'
unzip -q cmake.whl "cmake/data/share/cmake-$cmake_majmin_ver/"'Modules/**'
unzip -q cmake.whl "cmake/data/share/cmake-$cmake_majmin_ver/"'Templates/**'
rm -f cmake.whl
cd -
set +f
install -d "$cmake_destdir/share" "$cmake_destdir/doc" "$cmake_destdir/bin"
mv "$tools_dir/dl/cmake/data/bin"/* "$cmake_destdir/bin/"
rm -rf "$cmake_destdir/share/cmake-$cmake_majmin_ver" "$cmake_destdir/doc/cmake-$cmake_majmin_ver" "$cmake_destdir/doc/cmake"
mv "$tools_dir/dl/cmake/data/share/cmake-$cmake_majmin_ver" "$cmake_destdir/share/"
if [ -e "$tools_dir/dl/cmake/data/doc/cmake" ]; then # Windows wheel
mv "$tools_dir/dl/cmake/data/doc/cmake" "$cmake_destdir/doc/"
fi
if [ -e "$tools_dir/dl/cmake/data/doc/cmake-$cmake_majmin_ver" ]; then # Linux wheel
mv "$tools_dir/dl/cmake/data/doc/cmake-$cmake_majmin_ver" "$cmake_destdir/doc/"
fi
set -f
# other dirs: aclocal bash-completion emacs vim
rm -rf "$tools_dir/dl/cmake/data/share"
# be pedantic. if we don't know about a directory, it may be important. so error
# if some directory is non-empty
rmdir "$tools_dir/dl/cmake/data/bin" "$tools_dir/dl/cmake/data/doc"
rmdir "$tools_dir/dl/cmake/data"
fi
# Put tools in PATH
export_cmake_vars
if [ -n "$cmake_bindir" ] && [ -d "$cmake_bindir" ]; then
tools_bin_dir=$(cd "$cmake_bindir" && pwd)
export PATH="$tools_bin_dir:$PATH"
else
echo "This platform is not supported. No cmake 3.25+ download logic has been added" >&2
exit 1
fi
# Validate
"$cmake_bindir/cmake" --version > /dev/null
# --- Run finder script ---
cd "$PROJ_DIR"
"$cmake_bindir/cmake" \
-D CMAKE_GENERATOR=Ninja -D CMAKE_MAKE_PROGRAM="$NINJA_EXE" \
-D "DKTOOL_WORKDIR:FILEPATH=$tools_dir/work" -D "DKTOOL_CMDLINE:STRING=$*" \
-P cmake/FindDkToolScripts.cmake

146
dk.cmd Executable file
View file

@ -0,0 +1,146 @@
@ECHO OFF
REM Recommendation: Place this file in source control.
REM Auto-generated by `./dk dksdk.project.new` of DkHelloWorld.
REM The canonical way to run this script is: ./dk
REM That works in Powershell on Windows, and in Unix. Copy-and-paste works!
SETLOCAL
REM Coding guidelines
REM 1. Microsoft way of getting around PowerShell permissions:
REM https://github.com/microsoft/vcpkg/blob/71422c627264daedcbcd46f01f1ed0dcd8460f1b/bootstrap-vcpkg.bat
REM 2. Write goto downward please so code flow is top to bottom.
SET DK_CMAKE_VER=3.25.3
SET DK_NINJA_VER=1.11.1
SET DK_BUILD_TYPE=Release
SET DK_SHARE=%LOCALAPPDATA%\Programs\DkSDK\dktool
SET DK_PROJ_DIR=%~dp0
REM -------------- CMAKE --------------
REM Find CMAKE.EXE
where.exe /q cmake.exe >NUL 2>NUL
IF %ERRORLEVEL% neq 0 (
goto FindDownloadedCMake
)
FOR /F "tokens=* usebackq" %%F IN (`where.exe cmake.exe`) DO (
SET "DK_CMAKE_EXE=%%F"
)
REM Check if present at <data>/cmake-VER/bin/cmake.exe
:FindDownloadedCMake
IF EXIST %DK_SHARE%\cmake-%DK_CMAKE_VER%-windows-x86_64\bin\cmake.exe (
SET "DK_CMAKE_EXE=%DK_SHARE%\cmake-%DK_CMAKE_VER%-windows-x86_64\bin\cmake.exe"
GOTO ValidateCMake
)
REM Download CMAKE.EXE
bitsadmin /transfer dktool-cmake /download /priority FOREGROUND ^
"https://github.com/Kitware/CMake/releases/download/v%DK_CMAKE_VER%/cmake-%DK_CMAKE_VER%-windows-x86_64.zip" ^
"%TEMP%\cmake-%DK_CMAKE_VER%-windows-x86_64.zip"
IF %ERRORLEVEL% equ 0 (
GOTO UnzipCMakeZip
)
REM Try PowerShell 3+ instead
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Invoke-WebRequest https://github.com/Kitware/CMake/releases/download/v%DK_CMAKE_VER%/cmake-%DK_CMAKE_VER%-windows-x86_64.zip -OutFile '%TEMP%\cmake-%DK_CMAKE_VER%-windows-x86_64.zip'"
IF %ERRORLEVEL% neq 0 (
echo.
echo.Could not download CMake %DK_CMAKE_VER%. Make sure that PowerShell is installed
echo.and has not been disabled by a corporate policy.
echo.
EXIT /b 1
)
REM Unzip CMAKE.EXE (use PowerShell; could download unzip.exe and sha256sum.exe as well in case corporate policy)
:UnzipCMakeZip
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Expand-Archive '%TEMP%\cmake-%DK_CMAKE_VER%-windows-x86_64.zip' -DestinationPath '%DK_SHARE%'"
IF %ERRORLEVEL% neq 0 (
echo.
echo.Could not unzip CMake %DK_CMAKE_VER%. Make sure that PowerShell is installed
echo.and has not been disabled by a corporate policy.
echo.
EXIT /b 1
)
SET "DK_CMAKE_EXE=%DK_SHARE%\cmake-%DK_CMAKE_VER%-windows-x86_64\bin\cmake.exe"
REM Validate cmake.exe
:ValidateCMake
"%DK_CMAKE_EXE%" -version >NUL 2>NUL
if %ERRORLEVEL% neq 0 (
echo.
echo.%DK_CMAKE_EXE%
echo.is not responding to the -version option. Make sure that
echo.CMake is installed correctly.
echo.
exit /b 1
)
REM -------------- NINJA --------------
REM Find NINJA.EXE
where.exe /q ninja.exe >NUL 2>NUL
IF %ERRORLEVEL% neq 0 (
goto FindDownloadedNinja
)
FOR /F "tokens=* usebackq" %%F IN (`where.exe ninja.exe`) DO (
SET "DK_NINJA_EXE=%%F"
)
REM Check if present at <data>/ninja-VER/bin/ninja.exe
:FindDownloadedNinja
IF EXIST %DK_SHARE%\ninja-%DK_NINJA_VER%-windows-x86_64\bin\ninja.exe (
SET "DK_NINJA_EXE=%DK_SHARE%\ninja-%DK_NINJA_VER%-windows-x86_64\bin\ninja.exe"
GOTO ValidateNinja
)
REM Download NINJA.EXE
bitsadmin /transfer dktool-ninja /download /priority FOREGROUND ^
"https://github.com/ninja-build/ninja/releases/download/v%DK_NINJA_VER%/ninja-win.zip" ^
"%TEMP%\ninja-%DK_NINJA_VER%-windows-x86_64.zip"
IF %ERRORLEVEL% equ 0 (
GOTO UnzipNinjaZip
)
REM Try PowerShell 3+ instead
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v%DK_NINJA_VER%/ninja-win.zip -OutFile '%TEMP%\ninja-%DK_NINJA_VER%-windows-x86_64.zip'"
IF %ERRORLEVEL% neq 0 (
echo.
echo.Could not download Ninja %DK_NINJA_VER%. Make sure that PowerShell is installed
echo.and has not been disabled by a corporate policy.
echo.
EXIT /b 1
)
REM Unzip NINJA.EXE (use PowerShell; could download unzip.exe and sha256sum.exe as well in case corporate policy)
:UnzipNinjaZip
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Expand-Archive '%TEMP%\ninja-%DK_NINJA_VER%-windows-x86_64.zip' -DestinationPath '%DK_SHARE%\ninja-%DK_NINJA_VER%-windows-x86_64\bin'"
IF %ERRORLEVEL% neq 0 (
echo.
echo.Could not unzip Ninja %DK_NINJA_VER%. Make sure that PowerShell is installed
echo.and has not been disabled by a corporate policy.
echo.
EXIT /b 1
)
SET "DK_NINJA_EXE=%DK_SHARE%\ninja-%DK_NINJA_VER%-windows-x86_64\bin\ninja.exe"
REM Validate ninja.exe
:ValidateNinja
"%DK_NINJA_EXE%" --version >NUL 2>NUL
if %ERRORLEVEL% neq 0 (
echo.
echo.%DK_NINJA_EXE%
echo.is not responding to the --version option. Make sure that
echo.Ninja is installed correctly.
echo.
exit /b 1
)
REM -------------- Run finder --------------
cd %DK_PROJ_DIR%
"%DK_CMAKE_EXE%" -D CMAKE_GENERATOR=Ninja -D "CMAKE_MAKE_PROGRAM=%DK_NINJA_EXE%" -D "DKTOOL_WORKDIR:FILEPATH=%DK_SHARE%\work" -D "DKTOOL_CMDLINE:STRING=%*" -P cmake/FindDkToolScripts.cmake

7
environment.yml Normal file
View file

@ -0,0 +1,7 @@
name: c-capnproto
# channels:
# - conda-forge
# - defaults
dependencies:
- 'python>=3.8'
- meson

1
gtest

@ -1 +0,0 @@
Subproject commit d225acc90bc3a8c420a9bcd1f033033c1ccd7fe0

12
tests/CMakeLists.txt Normal file
View file

@ -0,0 +1,12 @@
include(FetchContent)
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # v1.14.0
)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
add_executable(c-capnproto-testcases addressbook.capnp.c capn-stream-test.cpp capn-test.cpp example-test.cpp)
target_link_libraries(c-capnproto-testcases PRIVATE CapnC_Runtime GTest::gtest)
gtest_add_tests(TARGET c-capnproto-testcases)

View file

@ -85,7 +85,7 @@ TEST(Examples, RoundTripPerson) {
{ {
// Write serialized object to file system. // Write serialized object to file system.
FILE *f = fopen("tests/example-test.cpp.Person.out", "wb"); FILE *f = fopen("example-test.cpp.Person.out", "wb");
ASSERT_NE(f, (void*)0); ASSERT_NE(f, (void*)0);
fwrite(buf, 1 /* size */, sz /* count */, f); fwrite(buf, 1 /* size */, sz /* count */, f);
int close_ret = fclose(f); int close_ret = fclose(f);