Improvements:

- A single and much simpler `CMakeLists.txt` (100 lines)
- Removed all git submodules - link against (system) libs instead:
  - RapidJSON
  - Boost (`system`, `filesystem`)
  - fmt
- Some small header-only libraries are included in the repo as-is:
  - `string-view-lite`, `optional-lite`, `variant-lite`, `expected-lite`
- Removed support for the `nlohmann/json` library (only support RapidJSON)
- Removed support for the Conan build system (only support CMake)
- Removed test suite and CI/CD definition(s)
- Added support for `ccache` (compilation cache)
- Removed documentation
master
Kroket Ltd 2022-10-01 00:49:19 +03:00
parent 1dacf16a1f
commit 45e112f7ee
71 changed files with 9053 additions and 8361 deletions

View File

@ -1,70 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '23 15 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -1,154 +0,0 @@
name: CI-linux-build
on:
push:
branches:
- master
- main
paths-ignore:
- 'docs/**'
- '**.md'
pull_request:
branches:
- master
- main
paths-ignore:
- 'docs/**'
- '**.md'
jobs:
linux-gcc-build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 8
matrix:
compiler: [g++-9, g++-10, g++-11]
base-flags: ["", -DJINJA2CPP_CXX_STANDARD=17]
build-config: [Release, Debug]
build-shared: [TRUE, FALSE]
include:
- compiler: g++-9
extra-flags: -DJINJA2CPP_STRICT_WARNINGS=OFF
- compiler: g++-10
extra-flags: -DJINJA2CPP_STRICT_WARNINGS=OFF
- compiler: g++-11
extra-flags: -DJINJA2CPP_STRICT_WARNINGS=OFF
steps:
- uses: actions/checkout@v1
- name: Setup environment
env:
INPUT_COMPILER: ${{ matrix.compiler }}
INPUT_BASE_FLAGS: ${{ matrix.base-flags }}
INPUT_BASE_CONFIG: ${{ matrix.build-config }}
INPUT_EXTRA_FLAGS: ${{ matrix.extra-flags }}
run: |
sudo apt-get update
sudo apt-get install -y cmake build-essential ${INPUT_COMPILER}
- name: Prepare build
env:
INPUT_COMPILER: ${{ matrix.compiler }}
INPUT_BASE_FLAGS: ${{ matrix.base-flags }}
INPUT_BASE_CONFIG: ${{ matrix.build-config }}
INPUT_EXTRA_FLAGS: ${{ matrix.extra-flags }}
run: |
set -ex
export BUILD_TARGET=all
export CMAKE_OPTS=-DCMAKE_VERBOSE_MAKEFILE=OFF
if [[ "${INPUT_COMPILER}" != "" ]]; then export CXX=${INPUT_COMPILER}; fi
export BUILD_CONFIG=${INPUT_BASE_CONFIG}
$CXX --version
export EXTRA_FLAGS="${INPUT_BASE_FLAGS} ${INPUT_EXTRA_FLAGS}"
- name: Build
env:
INPUT_BASE_CONFIG: ${{ matrix.build-config }}
INPUT_BASE_FLAGS: ${{ matrix.base-flags }}
INPUT_BUILD_SHARED: ${{ matrix.build-shared }}
INPUT_COMPILER: ${{ matrix.compiler }}
INPUT_EXTRA_FLAGS: ${{ matrix.extra-flags }}
run: |
set -ex
export BUILD_TARGET=all
export CMAKE_OPTS=-DCMAKE_VERBOSE_MAKEFILE=OFF
if [[ "${INPUT_COMPILER}" != "" ]]; then export CXX=${INPUT_COMPILER}; fi
export BUILD_CONFIG=${INPUT_BASE_CONFIG}
$CXX --version
export EXTRA_FLAGS="${INPUT_BASE_FLAGS} ${INPUT_EXTRA_FLAGS}"
mkdir -p .build && cd .build
cmake $CMAKE_OPTS -DCMAKE_BUILD_TYPE=$BUILD_CONFIG -DCMAKE_CXX_FLAGS=$CMAKE_CXX_FLAGS -DJINJA2CPP_DEPS_MODE=internal -DJINJA2CPP_BUILD_SHARED=$INPUT_BUILD_SHARED $EXTRA_FLAGS .. && cmake --build . --config $BUILD_CONFIG --target all -- -j4
- name: Test
env:
BUILD_CONFIG: ${{ matrix.build-config }}
run: |
cd .build && ctest -C $BUILD_CONFIG -V
linux-clang-build:
runs-on: ubuntu-latest
container:
image: ${{matrix.docker-image}}
env:
BUILD_DIRECTORY: /home/conan/.build
HOME: /home/conan
strategy:
fail-fast: false
max-parallel: 8
matrix:
compiler: [10, 11, 12]
base-flags: ["", -DJINJA2CPP_CXX_STANDARD=17]
build-config: [Release, Debug]
build-shared: [TRUE, FALSE]
include:
- compiler: 10
docker-image: conanio/clang10
- compiler: 11
docker-image: conanio/clang11
- compiler: 12
docker-image: conanio/clang12-ubuntu16.04:1.39.0
steps:
- uses: actions/checkout@v1
- name: Build
env:
INPUT_COMPILER: clang-${{ matrix.compiler }}
INPUT_BASE_FLAGS: ${{ matrix.base-flags }}
INPUT_BASE_CONFIG: ${{ matrix.build-config }}
INPUT_EXTRA_FLAGS: ${{ matrix.extra-flags }}
INPUT_BUILD_SHARED: ${{ matrix.build-shared }}
HOME: /home/conan
run: |
#!/bin/bash
set -ex
export BUILD_TARGET=all
export CMAKE_OPTS=-DCMAKE_VERBOSE_MAKEFILE=OFF
export BUILD_CONFIG=${INPUT_BASE_CONFIG}
export WORKSPACE=$GITHUB_WORKSPACE
#if [ "${INPUT_COMPILER}" != "" ]; then export CXX=${INPUT_COMPILER}; fi
if [ "${INPUT_COMPILER}" == "clang-12" ] ; then
export INPUT_BASE_FLAGS="-DJINJA2CPP_CXX_STANDARD=20" ;
fi
#$CXX --version
export EXTRA_FLAGS="${INPUT_BASE_FLAGS} ${INPUT_EXTRA_FLAGS}"
mkdir $BUILD_DIRECTORY && cd $BUILD_DIRECTORY
sudo chmod gou+rw -R $WORKSPACE
cmake $CMAKE_OPTS -DCMAKE_BUILD_TYPE=$BUILD_CONFIG -DCMAKE_CXX_FLAGS=$CMAKE_CXX_FLAGS -DJINJA2CPP_DEPS_MODE=internal -DJINJA2CPP_BUILD_SHARED=$INPUT_BUILD_SHARED $EXTRA_FLAGS $WORKSPACE && cmake --build . --config $BUILD_CONFIG --target all -- -j4
shell: bash
- name: Test
env:
BUILD_CONFIG: ${{ matrix.build-config }}
run: |
cd $BUILD_DIRECTORY
ctest -C $BUILD_CONFIG -V

View File

@ -1,89 +0,0 @@
name: CI-windows-build
on:
push:
branches:
- master
- main
paths-ignore:
- 'docs/**'
- '**.md'
pull_request:
branches:
- master
- main
paths-ignore:
- 'docs/**'
- '**.md'
jobs:
windows-msvc-build:
runs-on: ${{matrix.run-machine}}
strategy:
fail-fast: false
max-parallel: 20
matrix:
compiler: [msvc-2019, msvc-2017]
base-flags: ["", -DJINJA2CPP_CXX_STANDARD=17]
build-config: [Release, Debug]
build-platform: [x86, x64]
build-runtime: ["", /MT, /MD]
build-shared: [FALSE, TRUE]
include:
- compiler: msvc-2017
build-platform: x86
run-machine: windows-2016
generator: Visual Studio 15 2017
vc_vars: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars32.bat
- compiler: msvc-2017
build-platform: x64
run-machine: windows-2016
generator: Visual Studio 15 2017 Win64
vc_vars: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars64.bat
- compiler: msvc-2019
build-platform: x86
run-machine: windows-2019
generator: Visual Studio 16 2019
vc_vars: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat
- compiler: msvc-2019
build-platform: x64
run-machine: windows-2019
generator: Visual Studio 16 2019
vc_vars: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
steps:
- uses: actions/checkout@v1
- name: Build
shell: cmd
env:
INPUT_COMPILER: ${{ matrix.compiler }}
INPUT_BASE_FLAGS: ${{ matrix.base-flags }}
INPUT_BUILD_CONFIG: ${{ matrix.build-config }}
INPUT_BUILD_SHARED: ${{ matrix.build-shared }}
INPUT_EXTRA_FLAGS: ${{ matrix.extra_flags }}
INPUT_BUILD_PLATFORM: ${{ matrix.build-platform }}
INPUT_BUILD_RUNTIME: ${{ matrix.build-runtime }}
INPUT_GENERATOR: ${{ matrix.generator }}
VC_VARS: "${{ matrix.vc_vars }}"
run: |
call "%VC_VARS%"
mkdir -p .build
cd .build
cmake .. -G "%INPUT_GENERATOR%" -DCMAKE_BUILD_TYPE=%INPUT_BUILD_CONFIG% -DJINJA2CPP_MSVC_RUNTIME_TYPE="%INPUT_BUILD_RUNTIME%" -DJINJA2CPP_DEPS_MODE=internal -DJINJA2CPP_BUILD_SHARED=%INPUT_BUILD_SHARED% %INPUT_BASE_FLAGS% %INPUT_EXTRA_FLAGS%
cmake --build . --config %INPUT_BUILD_CONFIG% --verbose
- name: Test
shell: cmd
env:
INPUT_BUILD_CONFIG: ${{ matrix.build-config }}
VC_VARS: "${{ matrix.vc_vars }}"
run: |
cd .build
call "%VC_VARS%"
set path=%BOOST_ROOT%\lib;%PATH%
ctest -C %INPUT_BUILD_CONFIG% -V

27
.gitmodules vendored
View File

@ -1,27 +0,0 @@
[submodule "thirdparty/gtest"]
path = thirdparty/gtest
url = https://github.com/google/googletest.git
[submodule "thirdparty/boost"]
path = thirdparty/boost
url = https://github.com/boostorg/boost.git
[submodule "thirdparty/nonstd/expected-lite"]
path = thirdparty/nonstd/expected-lite
url = https://github.com/martinmoene/expected-lite.git
[submodule "thirdparty/nonstd/variant-lite"]
path = thirdparty/nonstd/variant-lite
url = https://github.com/martinmoene/variant-lite.git
[submodule "thirdparty/nonstd/optional-lite"]
path = thirdparty/nonstd/optional-lite
url = https://github.com/martinmoene/optional-lite.git
[submodule "thirdparty/nonstd/string-view-lite"]
path = thirdparty/nonstd/string-view-lite
url = https://github.com/martinmoene/string-view-lite.git
[submodule "thirdparty/fmtlib"]
path = thirdparty/fmtlib
url = https://github.com/fmtlib/fmt.git
[submodule "thirdparty/json/nlohmann"]
path = thirdparty/json/nlohmann
url = https://github.com/nlohmann/json.git
[submodule "thirdparty/json/rapid"]
path = thirdparty/json/rapid
url = https://github.com/Tencent/rapidjson.git

View File

@ -1,57 +0,0 @@
---
dist: xenial
language: cpp
sudo: required
matrix:
include:
-
compiler: clang
env: COMPILER='clang++'
os: osx
osx_image: xcode9
-
compiler: clang
env: COMPILER='clang++'
os: osx
osx_image: xcode10
-
compiler: clang
env: COMPILER='clang++'
os: osx
osx_image: xcode11
-
addons:
apt:
packages:
- cmake
- g++-6
- lcov
sources:
- ubuntu-toolchain-r-test
compiler: gcc
env: "COMPILER=g++-6 COLLECT_COVERAGE=1"
os: linux
-
addons:
apt:
packages:
- cmake
- clang-8
- g++-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
compiler: clang
env: "COMPILER=clang++-8 EXTRA_FLAGS=-DJINJA2CPP_CXX_STANDARD=17 SANITIZE_BUILD=address+undefined"
os: linux
before_install:
- "date -u"
- "uname -a"
script: ./scripts/build.sh
after_success:
- "if [[ \"${COLLECT_COVERAGE}\" != \"\" ]]; then echo \"Uploading code coverate report\" ; fi"
- "if [[ \"${COLLECT_COVERAGE}\" != \"\" ]]; then lcov --directory . --capture --output-file coverage.info ; fi"
- "if [[ \"${COLLECT_COVERAGE}\" != \"\" ]]; then lcov --remove coverage.info '/usr/*' --output-file coverage.info ; fi"
- "if [[ \"${COLLECT_COVERAGE}\" != \"\" ]]; then lcov --list coverage.info ; fi"
- "if [[ \"${COLLECT_COVERAGE}\" != \"\" ]]; then bash <(curl -s https://codecov.io/bash) -t \"225d6d7a-2b71-4dbe-bf87-fbf75eb7c119\" || echo \"Codecov did not collect coverage reports\"; fi"

View File

@ -1,325 +1,100 @@
cmake_minimum_required(VERSION 3.0.1)
project(Jinja2Cpp VERSION 1.1.0)
cmake_minimum_required(VERSION 3.13)
project(jinja2cppmedium)
message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
if (${CMAKE_VERSION} VERSION_GREATER "3.12")
cmake_policy(SET CMP0074 OLD)
endif ()
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
set(PROJECT_VERSION "0.1")
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(JINJA2CPP_IS_MAIN_PROJECT TRUE)
else()
set(JINJA2CPP_IS_MAIN_PROJECT FALSE)
set(CMAKE_CXX_STANDARD 14)
include(FindCcache)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_SKIP_RPATH ON)
endif()
# Options
set(JINJA2CPP_SANITIZERS address+undefined memory)
set(JINJA2CPP_WITH_SANITIZERS none CACHE STRING "Build with sanitizer")
set_property(CACHE JINJA2CPP_WITH_SANITIZERS PROPERTY STRINGS ${JINJA2CPP_SANITIZERS})
set (JINJA2CPP_DEPS_MODE "internal" CACHE STRING "Jinja2Cpp dependency management mode (internal | external | external-boost | conan-build). See documentation for details. 'interal' is default.")
option(JINJA2CPP_BUILD_TESTS "Build Jinja2Cpp unit tests" ${JINJA2CPP_IS_MAIN_PROJECT})
option(JINJA2CPP_STRICT_WARNINGS "Enable additional warnings and treat them as errors" ON)
option(JINJA2CPP_BUILD_SHARED "Build shared linkage version of Jinja2Cpp" OFF)
option(JINJA2CPP_PIC "Control -fPIC option for library build" OFF)
option(JINJA2CPP_VERBOSE "Add extra debug output to the build scripts" OFF)
find_package(rapidjson REQUIRED)
if (DEFINED BUILD_SHARED_LIBS)
set(JINJA2CPP_BUILD_SHARED ${BUILD_SHARED_LIBS})
endif ()
if (JINJA2CPP_BUILD_SHARED)
set(JINJA2CPP_PIC ON)
set(JINJA2CPP_MSVC_RUNTIME_TYPE "/MD")
endif ()
if (NOT JINJA2CPP_DEPS_MODE)
set(JINJA2CPP_DEPS_MODE "internal")
endif ()
if (JINJA2CPP_IS_MAIN_PROJECT OR NOT CMAKE_CXX_STANDARD)
set(JINJA2CPP_CXX_STANDARD 14 CACHE STRING "Jinja2Cpp C++ standard to build with. C++14 is default")
set(CMAKE_CXX_STANDARD ${JINJA2CPP_CXX_STANDARD})
endif ()
if (NOT JINJA2CPP_CXX_STANDARD)
set (JINJA2CPP_CXX_STANDARD ${CMAKE_CXX_STANDARD})
endif ()
if (JINJA2CPP_CXX_STANDARD LESS 14)
message(FATAL_ERROR "Jinja2Cpp is required C++14 or greater standard set. Currently selected standard: ${JINJA2CPP_CXX_STANDARD}")
else ()
message(STATUS "Jinja2Cpp C++ standard: ${JINJA2CPP_CXX_STANDARD}")
endif ()
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CLANG_CXX_FLAGS)
set(GCC_CXX_FLAGS)
set(MSVC_CXX_FLAGS)
if (JINJA2CPP_WITH_COVERAGE)
message(STATUS "This is DEBUG build with enabled Code Coverage")
set(CMAKE_BUILD_TYPE Debug)
set(JINJA2CPP_COVERAGE_TARGET "jinja2cpp_build_coverage")
include(coverage)
add_coverage_target("${JINJA2CPP_COVERAGE_TARGET}")
endif ()
if(NOT ${JINJA2CPP_WITH_SANITIZERS} STREQUAL "none")
message (STATUS "Build with sanitizers enabled: ${JINJA2CPP_WITH_SANITIZERS}")
set(_chosen_san)
list(FIND JINJA2CPP_SANITIZERS ${JINJA2CPP_WITH_SANITIZERS} _chosen_san)
if (${_chosen_san} EQUAL -1)
message(FATAL_ERROR "Wrong sanitizer type has been chosen, must be one of ${JINJA2CPP_SANITIZERS}")
endif()
include("sanitizer.${JINJA2CPP_WITH_SANITIZERS}")
set (JINJA2CPP_SANITIZE_TARGET "jinja2cpp_build_sanitizers")
add_sanitizer_target(${JINJA2CPP_SANITIZE_TARGET})
if(STATIC)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
endif()
if (UNIX)
if (JINJA2CPP_PIC OR CONAN_CMAKE_POSITION_INDEPENDENT_CODE)
add_compile_options(-fPIC)
endif ()
if (DEFINED CONAN_SHARED_LINKER_FLAGS)
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} -Wl,${CONAN_SHARED_LINKER_FLAGS})
set(CLANG_CXX_FLAGS ${CLANG_CXX_FLAGS} -Wl,${CONAN_SHARED_LINKER_FLAGS})
endif ()
else ()
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} "-Wa,-mbig-obj" -O1)
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif ()
add_definitions(-DBOOST_ALL_NO_LIB)
set(MSVC_CXX_FLAGS ${MSVC_CXX_FLAGS} /wd4503 /bigobj)
if (CMAKE_BUILD_TYPE MATCHES "Debug" AND JINJA2CPP_MSVC_RUNTIME_TYPE)
set(JINJA2CPP_MSVC_RUNTIME_TYPE "${JINJA2CPP_MSVC_RUNTIME_TYPE}d")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if (JINJA2CPP_DEPS_MODE MATCHES "conan-build" OR CMAKE_BUILD_TYPE STREQUAL "")
if (NOT JINJA2CPP_MSVC_RUNTIME_TYPE STREQUAL "")
set(MSVC_RUNTIME_DEBUG ${JINJA2CPP_MSVC_RUNTIME_TYPE})
set(MSVC_RUNTIME_RELEASE ${JINJA2CPP_MSVC_RUNTIME_TYPE})
endif ()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MSVC_RUNTIME_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MSVC_RUNTIME_RELEASE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${MSVC_RUNTIME_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/PROFILE")
set(Boost_USE_DEBUG_RUNTIME OFF)
elseif (CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(Boost_USE_DEBUG_RUNTIME ON)
else ()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/PROFILE")
set(Boost_USE_DEBUG_RUNTIME OFF)
endif ()
message(STATUS "Selected MSVC runtime type for Jinja2C++ library: '${JINJA2CPP_MSVC_RUNTIME_TYPE}'")
endif ()
if(MINGW)
set(Boost_THREADAPI win32)
endif()
set(_BOOST_COMPONENTS system filesystem)
find_package(Boost 1.69 REQUIRED COMPONENTS ${_BOOST_COMPONENTS})
# the source files
file(GLOB SOURCE_FILES
"src/*.cpp"
"include/*.h"
)
if (JINJA2CPP_BUILD_SHARED)
set(LIB_LINK_TYPE SHARED)
message(STATUS "Jinja2C++ library type: SHARED")
else()
set(LIB_LINK_TYPE STATIC)
message(STATUS "Jinja2C++ library type: STATIC")
endif()
list(APPEND PublicHeaders
include/jinja2cpp/polymorphic_value.h
include/jinja2cpp/generic_list_iterator.h
include/jinja2cpp/string_helpers.h
include/jinja2cpp/generic_list_impl.h
include/jinja2cpp/reflected_value.h
include/jinja2cpp/value_ptr.h
include/jinja2cpp/binding/rapid_json.h
include/jinja2cpp/error_handler.h
include/jinja2cpp/utils/i_comparable.h
include/jinja2cpp/user_callable.h
include/jinja2cpp/error_info.h
include/jinja2cpp/template_env.h
include/jinja2cpp/template.h
include/jinja2cpp/config.h
include/jinja2cpp/filesystem_handler.h
include/jinja2cpp/value.h
include/jinja2cpp/generic_list.h)
include(collect_sources)
add_library(jinja2cppmedium SHARED
${SOURCE_FILES}
${RESOURCES}
)
set (LIB_TARGET_NAME jinja2cpp)
find_package(fmt 8.0.0 REQUIRED)
CollectSources(Sources Headers ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
CollectSources(PublicSources PublicHeaders ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(${LIB_TARGET_NAME} ${LIB_LINK_TYPE}
${Sources}
${Headers}
${PublicHeaders}
)
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_CFG_NAME)
set(CURRENT_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BUILD_CFG_NAME}}")
set(JINJA2CPP_EXTRA_LIBS "" CACHE STRING "You can pass some libs that could used during link stage")
set(JINJA2CPP_PUBLIC_LIBS "${JINJA2CPP_EXTRA_LIBS}")
separate_arguments(JINJA2CPP_PUBLIC_LIBS)
if (JINJA2CPP_WITH_COVERAGE)
target_compile_options(
${JINJA2CPP_COVERAGE_TARGET}
INTERFACE
-g -O0
)
list(APPEND JINJA2CPP_PUBLIC_LIBS ${JINJA2CPP_COVERAGE_TARGET})
endif()
if (NOT JINJA2CPP_WITH_SANITIZERS STREQUAL "none")
target_compile_options(
${JINJA2CPP_SANITIZE_TARGET}
INTERFACE
-g -O2
)
list(APPEND JINJA2CPP_PUBLIC_LIBS ${JINJA2CPP_SANITIZE_TARGET})
endif()
set(JINJA2CPP_PRIVATE_LIBS "${JINJA2CPP_PRIVATE_LIBS}")
include(thirdparty/CMakeLists.txt)
target_link_libraries(
${LIB_TARGET_NAME}
PUBLIC
${JINJA2CPP_PUBLIC_LIBS}
PRIVATE
${JINJA2CPP_PRIVATE_LIBS}
)
target_include_directories(${LIB_TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
if (JINJA2CPP_STRICT_WARNINGS)
if (UNIX)
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} -Wall -Werror)
set(CLANG_CXX_FLAGS ${CLANG_CXX_FLAGS} -Wall -Werror -Wno-unused-command-line-argument)
set(MSVC_CXX_FLAGS ${MSVC_CXX_FLAGS} /W4)
endif ()
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${GCC_CXX_FLAGS})
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${CLANG_CXX_FLAGS})
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${MSVC_CXX_FLAGS})
endif ()
target_compile_definitions(${LIB_TARGET_NAME} PUBLIC -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_ERROR_CODE_HEADER_ONLY)
if (JINJA2CPP_BUILD_SHARED)
target_compile_definitions(${LIB_TARGET_NAME} PRIVATE -DJINJA2CPP_BUILD_AS_SHARED PUBLIC -DJINJA2CPP_LINK_AS_SHARED)
endif ()
set_target_properties(${LIB_TARGET_NAME} PROPERTIES
set_target_properties(jinja2cppmedium PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
SOVERSION ${PROJECT_VERSION})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RAPIDJSON_CXX_FLAGS}")
target_include_directories(jinja2cppmedium PUBLIC
include/
${RAPIDJSON_INCLUDE_DIRS}
)
set_target_properties(${LIB_TARGET_NAME} PROPERTIES
CXX_STANDARD ${JINJA2CPP_CXX_STANDARD}
CXX_STANDARD_REQUIRED ON
target_link_libraries(jinja2cppmedium
fmt::fmt
${Boost_LIBRARIES}
${CMAKE_DL_LIBS}
)
set_property(TARGET ${LIB_TARGET_NAME} PROPERTY PUBLIC_HEADER ${PublicHeaders} ${JINJA2CPP_EXTRA_PUBLIC_HEADERS})
# install library
include(GNUInstallDirs)
install(TARGETS jinja2cppmedium
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
configure_file(jinja2cpp.pc.in ${CMAKE_BINARY_DIR}/jinja2cpp.pc @ONLY)
# install library headers
install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/jinja2cpp"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING
PATTERN "*.h"
)
if (JINJA2CPP_BUILD_TESTS)
enable_testing()
# install pkconfig helper
configure_file(jinja2cppmedium.pc.in jinja2cppmedium.pc @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/jinja2cppmedium.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
CollectSources(TestSources TestHeaders ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/test)
add_executable(jinja2cpp_tests ${TestSources} ${TestHeaders})
target_link_libraries(jinja2cpp_tests gtest gtest_main
nlohmann_json::nlohmann_json ${LIB_TARGET_NAME} ${EXTRA_TEST_LIBS} ${JINJA2CPP_PRIVATE_LIBS})
set_target_properties(jinja2cpp_tests PROPERTIES
CXX_STANDARD ${JINJA2CPP_CXX_STANDARD}
CXX_STANDARD_REQUIRED ON)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(jinja2cpp_tests PRIVATE /bigobj)
endif ()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_data/simple_template1.j2tpl
COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/test/test_data ${CMAKE_CURRENT_BINARY_DIR}/test_data
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test/test_data/simple_template1.j2tpl
COMMENT "Copy test data to the destination dir"
)
add_custom_target(CopyTestData ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/test_data/simple_template1.j2tpl
)
add_dependencies(jinja2cpp_tests CopyTestData)
add_test(NAME jinja2cpp_tests COMMAND jinja2cpp_tests)
endif ()
set (JINJA2CPP_INSTALL_CONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/${LIB_TARGET_NAME}")
set (JINJA2CPP_TMP_CONFIG_PATH "cmake/config")
macro (Jinja2CppGetTargetIncludeDir infix target)
message (STATUS "infix: ${infix} target: ${target}")
if (TARGET ${target})
set (_J2CPP_VAR_NAME JINJA2CPP_${infix}_INCLUDE_DIRECTORIES)
get_target_property(${_J2CPP_VAR_NAME} ${target} INTERFACE_INCLUDE_DIRECTORIES)
endif ()
endmacro ()
Jinja2CppGetTargetIncludeDir(EXPECTED-LITE expected-lite)
Jinja2CppGetTargetIncludeDir(VARIANT-LITE variant-lite)
Jinja2CppGetTargetIncludeDir(OPTIONAL-LITE optional-lite)
Jinja2CppGetTargetIncludeDir(STRING-VIEW-LITE string-view-lite)
# Workaround for #14444 bug of CMake (https://gitlab.kitware.com/cmake/cmake/issues/14444)
# We can't use EXPORT feature of 'install' as is due to limitation of subproject's targets installation
# So jinja2cpp-config.cmake should be written manually
install(
TARGETS
${LIB_TARGET_NAME}
EXPORT
InstallTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/jinja2cpp
)
install(
FILES
${CMAKE_BINARY_DIR}/jinja2cpp.pc
DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)
install(
EXPORT
InstallTargets
FILE
jinja2cpp-cfg.cmake
DESTINATION
${JINJA2CPP_INSTALL_CONFIG_DIR}
)
configure_package_config_file(
cmake/public/jinja2cpp-config.cmake.in
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config.cmake
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
configure_package_config_file(
cmake/public/jinja2cpp-config-deps-${JINJA2CPP_DEPS_MODE}.cmake.in
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config-deps.cmake
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config-deps.cmake
DESTINATION
${JINJA2CPP_INSTALL_CONFIG_DIR}
)
message(STATUS "[+] Boost")
message(STATUS " - version: ${Boost_VERSION}")
message(STATUS " - dirs: ${Boost_INCLUDE_DIRS}")
message(STATUS " - libs: ${Boost_LIBRARIES}")
message(STATUS "[+] RapidJSON")
message(STATUS " - dirs: ${RAPIDJSON_INCLUDE_DIRS}")
message(STATUS "[+] Fmt")
message(STATUS " - version: ${fmt_VERSION}")

393
README.md
View File

@ -1,340 +1,121 @@
<div align="center"><img width="200" src="https://avatars0.githubusercontent.com/u/49841676?s=200&v=4"></div>
# Jinja2С++
# Jinja2CppMedium
[![Language](https://img.shields.io/badge/language-C++-blue.svg)](https://isocpp.org/)
[![Standard](https://img.shields.io/badge/c%2B%2B-14-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[![Standard](https://img.shields.io/badge/c%2B%2B-17-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[![Standard](https://img.shields.io/badge/c%2B%2B-20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[![Coverage Status](https://codecov.io/gh/jinja2cpp/Jinja2Cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/jinja2cpp/Jinja2Cpp)
[![Github Releases](https://img.shields.io/github/release/jinja2cpp/Jinja2Cpp/all.svg)](https://github.com/jinja2cpp/Jinja2Cpp/releases)
[![Github Issues](https://img.shields.io/github/issues/jinja2cpp/Jinja2Cpp.svg)](http://github.com/jinja2cpp/Jinja2Cpp/issues)
[![GitHub License](https://img.shields.io/badge/license-Mozilla-blue.svg)](https://raw.githubusercontent.com/jinja2cpp/Jinja2Cpp/master/LICENSE)
[![conan.io](https://api.bintray.com/packages/conan/conan-center/jinja2cpp%3A_/images/download.svg?version=1.2.1%3A_) ](https://conan.io/center/jinja2cpp)
[![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Jinja2Cpp/Lobby)
A "medium-lightweight" version of [jinja2cpp](https://github.com/jinja2cpp/Jinja2Cpp/).
C++ implementation of the Jinja2 Python template engine. This library brings support of powerful Jinja2 template features into the C++ world, reports dynamic HTML pages and source code generation.
For an even more lightweight version, check
out [Jinja2CppLight](https://github.com/hughperkins/Jinja2CppLight). However,
that version is less Jinja2-complaint.
## Introduction
### Improvements
Main features of Jinja2C++:
- Easy-to-use public interface. Just load templates and render them.
- Conformance to [Jinja2 specification](http://jinja.pocoo.org/docs/2.10/)
- Full support of narrow- and wide-character strings both for templates and parameters.
- Built-in reflection for the common C++ types, nlohmann and rapid JSON libraries.
- Powerful full-featured Jinja2 expressions with filtering (via '|' operator) and 'if'-expressions.
- Control statements (`set`, `for`, `if`, `filter`, `do`, `with`).
- Templates extension, including and importing
- Macros
- Rich error reporting.
- Shared template environment with templates cache support
[jinja2cpp](https://github.com/jinja2cpp/Jinja2Cpp/)
has a rather convoluted and unnecessarily complex CMake build
script.
For instance, this simple code:
Our improvements are:
```c++
#include <jinja2cpp/template.h>
- A single and much simpler `CMakeLists.txt` (100 lines)
- Removed all git submodules - link against (system) libs instead:
- RapidJSON
- Boost (`system`, `filesystem`)
- fmt
- Some small header-only libraries are included in the repo as-is:
- `string-view-lite`, `optional-lite`, `variant-lite`, `expected-lite`
- Removed support for the `nlohmann/json` library (only support RapidJSON)
- Removed support for the Conan build system (only support CMake)
- Removed test suite and CI/CD definition(s)
- Added support for `ccache` (compilation cache)
- Removed documentation
std::string source = R"(
{{ ("Hello", 'world') | join }}!!!
{{ ("Hello", 'world') | join(', ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') }}!!!
{{ ("Hello", 'world') | join(d = '; ') | lower }}!!!
)";
### Installation
Template tpl;
tpl.Load(source);
install into `/usr/local/lib` and `/usr/local/include`:
std::string result = tpl.RenderAsString({}).value();
```cpp
cmake -Bbuild .
make -Cbuild -j4
sudo make -Cbuild install
```
produces the result string:
```
Helloworld!!!
Hello, world!!!
Hello; world!!!
hello; world!!!
```
## Getting started
To use Jinja2C++ in your project you have to:
* Clone the Jinja2C++ repository
* Build it according to the [instructions](https://jinja2cpp.github.io/docs/build_and_install.html)
* Link to your project.
Usage of Jinja2C++ in the code is pretty simple:
1. Declare the jinja2::Template object:
```c++
jinja2::Template tpl;
```
2. Populate it with template:
```c++
tpl.Load("{{ 'Hello World' }}!!!");
```
3. Render the template:
```c++
std::cout << tpl.RenderAsString({}).value() << std::endl;
```
and get:
`
Hello World!!!
`
That's all!
More detailed examples and features description can be found in the documentation: [https://jinja2cpp.dev/docs/usage](https://jinja2cpp.github.io/docs/usage)
## Current Jinja2 support
Currently, Jinja2C++ supports the limited number of Jinja2 features. By the way, Jinja2C++ is planned to be a fully [jinja2 specification](http://jinja.pocoo.org/docs/2.10/templates/)-conformant. The current support is limited to:
- expressions. You can use almost every expression style: simple, filtered, conditional, and so on.
- the big number of filters (**sort, default, first, last, length, max, min, reverse, unique, sum, attr, map, reject, rejectattr, select, selectattr, pprint, dictsort, abs, float, int, list, round, random, trim, title, upper, wordcount, replace, truncate, groupby, urlencode, capitalize, escape, tojson, striptags, center, xmlattr**)
- the big number of testers (**eq, defined, ge, gt, iterable, le, lt, mapping, ne, number, sequence, string, undefined, in, even, odd, lower, upper**)
- the number of functions (**range**, **loop.cycle**)
- 'if' statement (with 'elif' and 'else' branches)
- 'for' statement (with 'else' branch and 'if' part support)
- 'include' statement
- 'import'/'from' statements
- 'set' statement (both line and block)
- 'filter' statement
- 'extends'/'block' statements
- 'macro'/'call' statements
- 'with' statement
- 'do' extension statement
- recursive loops
- space control and 'raw'/'endraw' blocks
Full information about Jinja2 specification support and compatibility table can be found here: [https://jinja2cpp.dev/docs/j2_compatibility.html](https://jinja2cpp.github.io/docs/j2_compatibility.html).
## Supported compilers
Compilation of Jinja2C++ tested on the following compilers (with C++14 and C++17 enabled features):
- Linux gcc 5.5 - 9.0
- Linux clang 5.0 - 9
- MacOS X-Code 9
- MacOS X-Code 10
- MacOS X-Code 11 (C++14 in default build, C++17 with externally-provided boost)
- Microsoft Visual Studio 2015 - 2019 x86, x64
- MinGW gcc compiler 7.3
- MinGW gcc compiler 8.1
**Note:** Support of gcc version >= 9.x or clang version >= 8.0 depends on the version of the Boost library provided.
### Build status
| Compiler | Status |
|---------|---------:|
| **MSVC** 2015 (x86, x64), **MinGW** 7 (x64), **MinGW** 8 (x64) | [![Build status](https://ci.appveyor.com/api/projects/status/vu59lw4r67n8jdxl/branch/master?svg=true)](https://ci.appveyor.com/project/flexferrum/jinja2cpp-n5hjm/branch/master) |
| **X-Code** 9, 10, 11 | [![Build Status](https://travis-ci.org/jinja2cpp/Jinja2Cpp.svg?branch=master)](https://travis-ci.org/jinja2cpp/Jinja2Cpp) |
| **MSVC** 2017 (x86, x64), **MSVC** 2019 (x86, x64), C++14/C++17 | [![](https://github.com/jinja2cpp/Jinja2Cpp/workflows/CI-windows-build/badge.svg)](https://github.com/jinja2cpp/Jinja2Cpp/actions?query=workflow%3ACI-windows-build) |
| **g++** 5, 6, 7, 8, 9, 10, 11 **clang** 5, 6, 7, 8, 9, 10, 11, 12 C++14/C++17/C++20 | [![](https://github.com/jinja2cpp/Jinja2Cpp/workflows/CI-linux-build/badge.svg)](https://github.com/jinja2cpp/Jinja2Cpp/actions?query=workflow%3ACI-linux-build) |
## Build and install
Jinja2C++ has several external dependencies:
- `boost` library (at least version 1.65)
- `nonstd::expected-lite` [https://github.com/martinmoene/expected-lite](https://github.com/martinmoene/expected-lite)
- `nonstd::variant-lite` [https://github.com/martinmoene/variant-lite](https://github.com/martinmoene/variant-lite)
- `nonstd::optional-lite` [https://github.com/martinmoene/optional-lite](https://github.com/martinmoene/optional-lite)
- `nonstd::string-view-lite` [https://github.com/martinmoene/string-view-lite](https://github.com/martinmoene/string-view-lite)
- `fmtlib::fmt` [https://github.com/fmtlib/fmt](https://github.com/fmtlib/fmt)
Examples of build scripts and different build configurations could be found here: [https://github.com/jinja2cpp/examples-build](https://github.com/jinja2cpp/examples-build)
In simplest case to compile Jinja2C++ you need:
1. Install CMake build system (at least version 3.0)
2. Clone jinja2cpp repository:
```
> git clone https://github.com/flexferrum/Jinja2Cpp.git
```
3. Create build directory:
```
> cd Jinja2Cpp
> mkdir build
```
4. Run CMake and build the library:
```
> cd build
> cmake .. -DCMAKE_INSTALL_PREFIX=<path to install folder>
> cmake --build . --target all
```
"Path to install folder" here is a path to the folder where you want to install Jinja2C++ lib.
5. Install library:
```
> cmake --build . --target install
```
In this case, Jinja2C++ will be built with internally-shipped dependencies and install them respectively. But Jinja2C++ supports builds with externally-provided deps.
### Usage with conan.io dependency manager
Jinja2C++ can be used as conan.io package. In this case, you should do the following steps:
1. Install conan.io according to the documentation ( https://docs.conan.io/en/latest/installation.html )
2. Add a reference to Jinja2C++ package (`jinja2cpp/1.1.0`) to your conanfile.txt, conanfile.py or CMakeLists.txt. For instance, with the usage of `conan-cmake` integration it could be written this way:
Copy `cmake/public/FindJinja2CppMedium.cmake` to your project so you may do:
```cmake
include (../../cmake/conan.cmake)
if (NOT MSVC)
set (CONAN_SETTINGS SETTINGS compiler.libcxx=libstdc++11)
endif ()
conan_cmake_run(REQUIRES
jinja2cpp/1.1.0
gtest/1.7.0@bincrafters/stable
BASIC_SETUP
${CONAN_SETTINGS}
OPTIONS
jinja2cpp:shared=False
gtest:shared=False
BUILD missing)
set (TARGET_NAME jinja2cpp_build_test)
add_executable (${TARGET_NAME} main.cpp)
target_link_libraries (${TARGET_NAME} ${CONAN_LIBS})
set_target_properties (${TARGET_NAME} PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON)
find_package(Jinja2CppMedium REQUIRED)
target_include_directories(your_app PRIVATE ${Jinja2CppMedium_INCLUDE_DIRS})
target_link_libraries(your_app ${Jinja2CppMedium_LIBRARIES})
```
### Usage
### Additional CMake build flags
You can define (via -D command-line CMake option) the following build flags:
```cpp
#include <iostream>
#include <string>
- **JINJA2CPP_BUILD_TESTS** (default TRUE) - to build or not to Jinja2C++ tests.
- **JINJA2CPP_STRICT_WARNINGS** (default TRUE) - Enable strict mode compile-warnings(-Wall -Werror, etc).
- **JINJA2CPP_MSVC_RUNTIME_TYPE** (default /MD) - MSVC runtime type to link with (if you use Microsoft Visual Studio compiler).
- **JINJA2CPP_DEPS_MODE** (default "internal") - modes for dependency handling. Following values possible:
- `internal` In this mode Jinja2C++ build script uses dependencies (include `boost`) shipped as subprojects. Nothing needs to be provided externally.
- `external-boost` In this mode Jinja2C++ build script uses only `boost` as an externally-provided dependency. All other dependencies are taken from subprojects.
- `external` In this mode all dependencies should be provided externally. Paths to `boost`, `nonstd-*` libs, etc. should be specified via standard CMake variables (like `CMAKE_PREFIX_PATH` or libname_DIR)
- `conan-build` Special mode for building Jinja2C++ via conan recipe.
#include "jinja2cpp/template.h"
using namespace jinja2;
### Build with C++17 standard enabled
Jinja2C++ tries to use standard versions of `std::variant`, `std::string_view` and `std::optional` if possible.
int main(void) {
std::string source = R"(
{% if TrueVal %}
Hello from Jinja template!
{% endif %}
)";
## Acknowledgments
Thanks to **@manu343726** for CMake scripts improvement, bug hunting, and fixing and conan.io packaging.
Template tpl;
tpl.Load(source);
ValuesMap params = {
{"TrueVal", true},
{"FalseVal", true},
};
std::string result = tpl.RenderAsString(params).value();
std::cout << result << std::endl;
return 0;
}
```
Thanks to **@martinmoene** for the perfectly implemented xxx-lite libraries.
RapidJSON:
Thanks to **@vitaut** for the amazing text formatting library.
```cpp
#include <iostream>
#include <string>
Thanks to **@martinus** for the fast hash maps implementation.
#include "jinja2cpp/template.h"
#include <jinja2cpp/binding/rapid_json.h>
using namespace jinja2;
## Changelog
int main(void) {
const char *json = R"(
{
"message": "Hello World from Parser!",
"big_int": 100500100500100,
"bool_true": true
}
)";
### Version 1.1.0
#### Changes and improvements
- `batch` filter added
- `slice` filter added
- `format` filter added
- `tojson` filter added
- `striptags` filter added
- `center` filter added
- `xmlattr` filter added
- `raw`/`endraw` tags added
- repeat string operator added (e. g. `'a' * 5` will produce `'aaaaa'`)
- support for templates metadata (`meta`/`endmeta` tags) added
- `-fPIC` flag added to Linux build configuration
rapidjson::Document doc;
doc.Parse(json);
#### Fixed bugs
- Fix behavior of lstripblock/trimblocks global settings. Now it fully corresponds to the origina jinja2
- Fix bug with rendering parent `block` content if child doesn't override this block
- Fix compilation issues with user-defined callables with number of arguments more than 2
- Fix access to global Jinja2 functions from included/extended templates
- Fix point of evaluation of macro params
- Fix looping over the strings
- Cleanup warnings
std::string source = R"(
{{ json.message }}
)";
#### Breaking changes
- From now with C++17 standard enabled Jinja2C++ uses standard versions of types `variant`, `string_view` and `optional`
Template tpl;
tpl.Load(source);
### Version 1.0.0
#### Changes and improvements
- `default` attribute added to the `map` filter (#48)
- escape sequences support added to the string literals (#49)
- arbitrary ranges, generated sequences, input iterators, etc. now can be used with `GenericList` type (#66)
- nonstd::string_view is now one of the possible types for the `Value`
- `filter` tag support added to the template parser (#44)
- `escape` filter support added to the template parser (#140)
- `capitalize` filter support added to the template parser (#137)
- the multiline version of `set` tag added to the parser (#45)
- added built-in reflection for nlohmann JSON and RapidJSON libraries (#78)
- `loop.depth` and `loop.depth0` variables support added
- {fmt} is now used as a formatting library instead of iostreams
- robin hood hash map is now used for internal value storage
- rendering performance improvements
- template cache implemented in `TemplateEnv`
- user-defined callables now can accept global context via `*context` special param
- MinGW, clang >= 7.0, XCode >= 9, gcc >= 7.0 are now officially supported as a target compilers (#79)
ValuesMap params = {
{"json", Reflect(doc)},
};
#### Fixed bugs
- Fixed pipe (`|`) operator precedence (#47)
- Fixed bug in internal char <-> wchar_t converter on Windows
- Fixed crash in parsing `endblock` tag
- Fixed scope control for `include` and `for` tags
- Fixed bug with macros call within expression context
std::string result = tpl.RenderAsString(params).value();
std::cout << result << std::endl;
return 0;
}
```
#### Breaking changes
- MSVC runtime type is now defined by `JINJA2CPP_MSVC_RUNTIME_TYPE` CMake variable
### License
### Version 0.9.2
#### Major changes
- User-defined callables implemented. Now you can define your own callable objects, pass them as input parameters and use them inside templates as regular (global) functions, filters or testers. See details here: https://jinja2cpp.dev/docs/usage/ud_callables.html
- Now you can define global (template environment-wide) parameters that are accessible for all templates bound to this environment.
- `include`, `import` and `from` statements implemented. Now it's possible to include other templates and use macros from other templates.
- `with` statement implemented
- `do` statement implemented
- Sample build projects for various Jinja2C++ usage variants created: https://github.com/jinja2cpp/examples-build](https://github.com/jinja2cpp/examples-build)
- Documentation site created for Jinja2C++: https://jinja2cpp.dev/
#### Minor changes
- Render-time error handling added
- Dependency management mode added to the build script
- Fix bugs with error reporting during the parse time
- Upgraded versions of external dependencies
#### Breaking changes
- `RenderAsString` method now returns `nonstd::expected` instead of regular `std::string`
- Templates with `import`, `extends` and `include` generate errors if parsed without `TemplateEnv` set
- Release bundles (archives) are configured with `external` dependency management mode by default
### Version 0.9.1
- `applymacro` filter added which allows applying arbitrary macro as a filter
- dependencies to boost removed from the public interface
- CMake scripts improved
- Various bugs fixed
- Improve reflection
- Warnings cleanup
### Version 0.9
- Support of 'extents'/'block' statements
- Support of 'macro'/'call' statements
- Rich error reporting
- Support for recursive loops
- Support for space control before and after control blocks
- Improve reflection
### Version 0.6
- A lot of filters have been implemented. Full set of supported filters listed here: [https://github.com/flexferrum/Jinja2Cpp/issues/7](https://github.com/flexferrum/Jinja2Cpp/issues/7)
- A lot of testers have been implemented. Full set of supported testers listed here: [https://github.com/flexferrum/Jinja2Cpp/issues/8](https://github.com/flexferrum/Jinja2Cpp/issues/8)
- 'Concatenate as string' operator ('~') has been implemented
- For-loop with 'if' condition has been implemented
- Fixed some bugs in parser
MPL 2.0

View File

@ -1,95 +0,0 @@
version: 1.0.0.{build}
skip_commits:
message: /.*/
skip_branch_with_pr: true
skip_tags: true
skip_non_tags: true
os:
- Visual Studio 2015
- Visual Studio 2017
platform:
- Win32
- x64
configuration:
- Debug
- Release
environment:
BOOST_ROOT: C:\Libraries\boost_1_65_1
GENERATOR: "\"NMake Makefiles\""
DEPS_MODE: internal
matrix:
# - BUILD_PLATFORM: clang
# MSVC_RUNTIME_TYPE:
# GENERATOR: "\"Unix Makefiles\""
# DEPS_MODE: internal
# EXTRA_CMAKE_ARGS: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_MAKE_PROGRAM=mingw32-make.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DJINJA2CPP_STRICT_WARNINGS=OFF
- BUILD_PLATFORM: MinGW7
MSVC_RUNTIME_TYPE:
GENERATOR: "\"Unix Makefiles\""
DEPS_MODE: internal
EXTRA_CMAKE_ARGS: -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++.exe -DCMAKE_MAKE_PROGRAM=mingw32-make.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DJINJA2CPP_STRICT_WARNINGS=OFF
- BUILD_PLATFORM: MinGW8
MSVC_RUNTIME_TYPE:
GENERATOR: "\"Unix Makefiles\""
DEPS_MODE: internal
EXTRA_CMAKE_ARGS: -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++.exe -DCMAKE_MAKE_PROGRAM=mingw32-make.exe -DCMAKE_VERBOSE_MAKEFILE=ON -DJINJA2CPP_STRICT_WARNINGS=OFF
- BUILD_PLATFORM: x64
MSVC_RUNTIME_TYPE: /MD
- BUILD_PLATFORM: x64
MSVC_RUNTIME_TYPE: /MT
- BUILD_PLATFORM: x64
MSVC_RUNTIME_TYPE:
- BUILD_PLATFORM: x86
MSVC_RUNTIME_TYPE: /MD
- BUILD_PLATFORM: x86
MSVC_RUNTIME_TYPE: /MT
- BUILD_PLATFORM: x86
MSVC_RUNTIME_TYPE:
matrix:
fast_finish: false
exclude:
- os: Visual Studio 2015
BUILD_PLATFORM: MinGW7
- os: Visual Studio 2015
BUILD_PLATFORM: MinGW8
- os: Visual Studio 2015
BUILD_PLATFORM: clang
- os: Visual Studio 2017
BUILD_PLATFORM: x86
- os: Visual Studio 2017
BUILD_PLATFORM: x64
- platform: Win32
BUILD_PLATFORM: x64
- platform: Win32
BUILD_PLATFORM: MinGW7
- platform: Win32
BUILD_PLATFORM: MinGW8
- platform: Win32
BUILD_PLATFORM: clang
- platform: x64
BUILD_PLATFORM: x86
init:
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" if "%BUILD_PLATFORM%"=="MinGW7" set PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" if "%BUILD_PLATFORM%"=="MinGW8" set PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" if "%BUILD_PLATFORM%"=="clang" set PATH=%BOOST_ROOT%\lib64-msvc-14.1;C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;C:\Libraries\llvm-5.0.0\bin;%PATH% && call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" if "%BUILD_PLATFORM%"=="x86" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" if "%BUILD_PLATFORM%"=="x86" set PATH=%BOOST_ROOT%\lib32-msvc-14.0;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" if "%BUILD_PLATFORM%"=="x64" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" if "%BUILD_PLATFORM%"=="x64" set PATH=%BOOST_ROOT%\lib64-msvc-14.0;%PATH%
build_script:
- mkdir -p build && cd build
- cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%configuration% -DJINJA2CPP_MSVC_RUNTIME_TYPE=%MSVC_RUNTIME_TYPE% -DJINJA2CPP_DEPS_MODE=%DEPS_MODE% %EXTRA_CMAKE_ARGS%
- cmake --build . --target all --config %configuration%
test_script:
- ctest -C %configuration% -V

56
cmake/FindCcache.cmake Normal file
View File

@ -0,0 +1,56 @@
# Copyright (c) 2014-2020, The Monero Project
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are
# permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# - Try to find readline include dirs and libraries
#
# Automatically finds ccache build accelerator, if it's found in PATH.
#
# Usage of this module as follows:
#
# project(monero)
# include(FindCcache) # Include AFTER the project() macro to be able to reach the CMAKE_CXX_COMPILER variable
#
# Properties modified by this module:
#
# GLOBAL PROPERTY RULE_LAUNCH_COMPILE set to ccache, when ccache found
# GLOBAL PROPERTY RULE_LAUNCH_LINK set to ccache, when ccache found
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
if (${RET} EQUAL 0)
message("found usable ccache: ${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_FOUND}")
else()
message("found ccache ${CCACHE_FOUND}, but is UNUSABLE! Return code: ${RET}")
endif()
else()
message("ccache NOT found!")
endif()

97
cmake/Findrapidjson.cmake Normal file
View File

@ -0,0 +1,97 @@
# Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
# Copyright (c) 2013 Rafal Jeczalik (rjeczalik@gmail.com)
# Distributed under the MIT License (see license.txt file)
# -----------------------------------------------------------------------------------
#
# Finds the rapidjson library
#
# -----------------------------------------------------------------------------------
#
# Variables used by this module, they can change the default behaviour.
# Those variables need to be either set before calling find_package
# or exported as environment variables before running CMake:
#
# RAPIDJSON_INCLUDEDIR - Set custom include path, useful when rapidjson headers are
# outside system paths
# RAPIDJSON_USE_SSE2 - Configure rapidjson to take advantage of SSE2 capabilities
# RAPIDJSON_USE_SSE42 - Configure rapidjson to take advantage of SSE4.2 capabilities
#
# ----------------------------