Skip to content

Commit 634dbf0

Browse files
authored
Cmake deps mode (#102)
* Add JINJA2CPP_DEPS_MODE setting for CMakeLists.txt * Add 'external-boost' deps mode * Add 'external' deps management mode * Add explicit nothrow ctors for ErrorInfo/ParserError * Update submodules refs * fix ref * Add nothrow move-ctor for jinja2::Value * Fix nothrow move-ctor for ErrorInfoTpl * Fix error handling issues * Add 'conan-build' dependency management mode * Fix library list propagation * Remove boost::optional from the public headers * Fix conan package libs reference * Fix 'conan-build' deps management mode * Adopt conan-build mode for 'cmake-find-package' generator * Rework installation scenario for 'internal' deps management mode * Fix installation scripts * Fix build for some installation scenarios * Fix installation for "conan-*" dep management modes * Clean up cmake modules * Fix build
1 parent 79e043b commit 634dbf0

26 files changed

+517
-171
lines changed

CMakeLists.txt

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
cmake_minimum_required(VERSION 3.0.2)
1+
cmake_minimum_required(VERSION 3.0.1)
22
project(Jinja2Cpp VERSION 0.9.1)
33

44
if (${CMAKE_VERSION} VERSION_GREATER "3.12")
55
cmake_policy(SET CMP0074 OLD)
66
endif ()
77

8+
set (JINJA2CPP_DEPS_MODE "internal" CACHE STRING "Jinja2Cpp dependency management mode (internal | external | external-boost | conan-build). See documentation for details. 'interal' is default.")
9+
if (NOT JINJA2CPP_DEPS_MODE)
10+
set (JINJA2CPP_DEPS_MODE "internal")
11+
endif ()
12+
13+
include(CMakePackageConfigHelpers)
14+
include(GNUInstallDirs)
15+
816
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
917

1018
if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE_ENABLED)
@@ -48,6 +56,7 @@ endif()
4856
option(JINJA2CPP_BUILD_TESTS "Build Jinja2Cpp unit tests" ${JINJA2CPP_IS_MAIN_PROJECT})
4957
option(JINJA2CPP_STRICT_WARNINGS "Enable additional warnings and treat them as errors" ON)
5058
option(JINJA2CPP_BUILD_SHARED "Build shared linkage version of Jinja2Cpp" OFF)
59+
5160
if (JINJA2CPP_BUILD_SHARED)
5261
set(LIB_LINK_TYPE SHARED)
5362
else()
@@ -72,10 +81,12 @@ set(CURRENT_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BUILD_CFG_NAME}}")
7281

7382
include(thirdparty/CMakeLists.txt)
7483

75-
target_link_libraries(${LIB_TARGET_NAME} PUBLIC expected-lite variant-lite value-ptr-lite optional-lite boost_variant boost_filesystem boost_algorithm)
84+
target_link_libraries(${LIB_TARGET_NAME} PUBLIC ${JINJA2CPP_PUBLIC_LIBS} PRIVATE ${JINJA2CPP_PRIVATE_LIBS})
7685

7786
target_include_directories(${LIB_TARGET_NAME}
78-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
87+
PUBLIC
88+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
89+
$<INSTALL_INTERFACE:include>)
7990

8091
if(JINJA2CPP_STRICT_WARNINGS)
8192
if(NOT MSVC)
@@ -89,9 +100,17 @@ if (COVERAGE_ENABLED AND NOT MSVC)
89100
endif ()
90101

91102
target_compile_definitions(${LIB_TARGET_NAME} PUBLIC variant_CONFIG_SELECT_VARIANT=variant_VARIANT_NONSTD)
103+
92104
set_target_properties(${LIB_TARGET_NAME} PROPERTIES
93105
CXX_STANDARD 14
94-
CXX_STANDARD_REQUIRED ON)
106+
CXX_STANDARD_REQUIRED ON
107+
VERSION ${PROJECT_VERSION}
108+
SOVERSION 1
109+
)
110+
111+
set_property(TARGET ${LIB_TARGET_NAME} PROPERTY PUBLIC_HEADER ${PublicHeaders} ${JINJA2CPP_EXTRA_PUBLIC_HEADERS})
112+
113+
configure_file(jinja2cpp.pc.in jinja2cpp.pc @ONLY)
95114

96115
if (JINJA2CPP_BUILD_TESTS)
97116
enable_testing()
@@ -130,10 +149,58 @@ if (JINJA2CPP_BUILD_TESTS)
130149
add_test(NAME jinja2cpp_tests COMMAND jinja2cpp_tests)
131150
endif ()
132151

133-
install(TARGETS ${LIB_TARGET_NAME}
134-
RUNTIME DESTINATION bin
135-
LIBRARY DESTINATION lib
136-
ARCHIVE DESTINATION lib/static)
152+
set (JINJA2CPP_INSTALL_CONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/${LIB_TARGET_NAME})
153+
set (JINJA2CPP_TMP_CONFIG_PATH cmake/config)
137154

138-
install (DIRECTORY include/ DESTINATION include)
139-
install (FILES cmake/public/FindJinja2Cpp.cmake DESTINATION cmake)
155+
156+
macro (Jinja2CppGetTargetIncludeDir infix target)
157+
message (STATUS "infix: ${infix} target: ${target}")
158+
159+
if (TARGET ${target})
160+
set (_J2CPP_VAR_NAME JINJA2CPP_${infix}_INCLUDE_DIRECTORIES)
161+
get_target_property(${_J2CPP_VAR_NAME} ${target} INTERFACE_INCLUDE_DIRECTORIES)
162+
endif ()
163+
endmacro ()
164+
165+
Jinja2CppGetTargetIncludeDir(EXPECTED-LITE expected-lite)
166+
Jinja2CppGetTargetIncludeDir(VARIANT-LITE variant-lite)
167+
Jinja2CppGetTargetIncludeDir(OPTIONAL-LITE optional-lite)
168+
Jinja2CppGetTargetIncludeDir(VALUE-PTR-LITE value-ptr-lite)
169+
170+
# Workaround for #14444 bug of CMake (https://gitlab.kitware.com/cmake/cmake/issues/14444)
171+
# We can't use EXPORT feature of 'install' as is due to limitation of subproject's targets installation
172+
# So jinja2cpp-config.cmake should be written manually
173+
174+
install(TARGETS ${LIB_TARGET_NAME}
175+
EXPORT InstallTargets
176+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
177+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
178+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static
179+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/jinja2cpp
180+
)
181+
182+
install (FILES ${CMAKE_BINARY_DIR}/jinja2cpp.pc
183+
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
184+
185+
install(EXPORT InstallTargets
186+
FILE jinja2cpp-cfg.cmake
187+
DESTINATION ${JINJA2CPP_INSTALL_CONFIG_DIR})
188+
189+
configure_package_config_file(
190+
cmake/public/jinja2cpp-config.cmake.in
191+
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config.cmake
192+
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
193+
NO_CHECK_REQUIRED_COMPONENTS_MACRO
194+
)
195+
196+
configure_package_config_file(
197+
cmake/public/jinja2cpp-config-deps-${JINJA2CPP_DEPS_MODE}.cmake.in
198+
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config-deps.cmake
199+
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
200+
NO_CHECK_REQUIRED_COMPONENTS_MACRO
201+
)
202+
203+
install (FILES
204+
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config.cmake
205+
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config-deps.cmake
206+
DESTINATION ${JINJA2CPP_INSTALL_CONFIG_DIR})

cmake/public/jinja2cpp-config-deps-conan-build.cmake.in

Whitespace-only changes.

cmake/public/jinja2cpp-config-deps-conan.cmake.in

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
macro (Jinja2CppAddBoostDep name)
2+
if (TARGET Boost::${name})
3+
list (APPEND JINJA2CPP_INTERFACE_LINK_LIBRARIES $<LINK_ONLY:Boost::${name}>)
4+
elseif (TARGET boost_${name})
5+
list (APPEND JINJA2CPP_INTERFACE_LINK_LIBRARIES $<LINK_ONLY:boost_${name}>)
6+
endif ()
7+
endmacro ()
8+
9+
Jinja2CppAddBoostDep(variant)
10+
Jinja2CppAddBoostDep(filesystem)
11+
Jinja2CppAddBoostDep(algorithm)
12+
13+
set_property(TARGET jinja2cpp PROPERTY
14+
INTERFACE_LINK_LIBRARIES ${JINJA2CPP_INTERFACE_LINK_LIBRARIES}
15+
)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Create imported target expected-lite
2+
add_library(expected-lite INTERFACE IMPORTED)
3+
4+
set_target_properties(expected-lite PROPERTIES
5+
INTERFACE_INCLUDE_DIRECTORIES "@JINJA2CPP_EXPECTED-LITE_INCLUDE_DIRECTORIES@"
6+
)
7+
8+
# Create imported target variant-lite
9+
add_library(variant-lite INTERFACE IMPORTED)
10+
11+
set_target_properties(variant-lite PROPERTIES
12+
INTERFACE_INCLUDE_DIRECTORIES "@JINJA2CPP_VARIANT-LITE_INCLUDE_DIRECTORIES@"
13+
)
14+
15+
# Create imported target optional-lite
16+
add_library(optional-lite INTERFACE IMPORTED)
17+
18+
set_target_properties(optional-lite PROPERTIES
19+
INTERFACE_INCLUDE_DIRECTORIES "@JINJA2CPP_OPTIONAL-LITE_INCLUDE_DIRECTORIES@"
20+
)
21+
22+
# Create imported target value-ptr-lite
23+
add_library(value-ptr-lite INTERFACE IMPORTED)
24+
25+
set_target_properties(value-ptr-lite PROPERTIES
26+
INTERFACE_INCLUDE_DIRECTORIES "@JINJA2CPP_VALUE-PTR-LITE_INCLUDE_DIRECTORIES@"
27+
)
28+
29+
set (JINJA2CPP_INTERFACE_LINK_LIBRARIES expected-lite variant-lite value-ptr-lite optional-lite)
30+
31+
macro (Jinja2CppAddBoostDep name)
32+
if (TARGET Boost::${name})
33+
list (APPEND JINJA2CPP_INTERFACE_LINK_LIBRARIES $<LINK_ONLY:Boost::${name}>)
34+
elseif (TARGET boost_${name})
35+
list (APPEND JINJA2CPP_INTERFACE_LINK_LIBRARIES $<LINK_ONLY:boost_${name}>)
36+
endif ()
37+
endmacro ()
38+
39+
Jinja2CppAddBoostDep(variant)
40+
Jinja2CppAddBoostDep(filesystem)
41+
Jinja2CppAddBoostDep(algorithm)
42+
43+
set_property(TARGET jinja2cpp PROPERTY
44+
INTERFACE_LINK_LIBRARIES ${JINJA2CPP_INTERFACE_LINK_LIBRARIES}
45+
)

cmake/public/jinja2cpp-config-deps-internal.cmake.in

Whitespace-only changes.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Based on generated file by CMake
2+
3+
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
4+
message(FATAL_ERROR "CMake >= 2.6.0 required")
5+
endif()
6+
cmake_policy(PUSH)
7+
cmake_policy(VERSION 2.6)
8+
9+
#----------------------------------------------------------------
10+
# Generated CMake target import file.
11+
#----------------------------------------------------------------
12+
13+
# Commands may need to know the format version.
14+
set(CMAKE_IMPORT_FILE_VERSION 1)
15+
16+
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
17+
set(_targetsDefined)
18+
set(_targetsNotDefined)
19+
set(_expectedTargets)
20+
foreach(_expectedTarget jinja2cpp)
21+
list(APPEND _expectedTargets ${_expectedTarget})
22+
if(NOT TARGET ${_expectedTarget})
23+
list(APPEND _targetsNotDefined ${_expectedTarget})
24+
endif()
25+
if(TARGET ${_expectedTarget})
26+
list(APPEND _targetsDefined ${_expectedTarget})
27+
endif()
28+
endforeach()
29+
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
30+
unset(_targetsDefined)
31+
unset(_targetsNotDefined)
32+
unset(_expectedTargets)
33+
set(CMAKE_IMPORT_FILE_VERSION)
34+
cmake_policy(POP)
35+
return()
36+
endif()
37+
if(NOT "${_targetsDefined}" STREQUAL "")
38+
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
39+
endif()
40+
unset(_targetsDefined)
41+
unset(_targetsNotDefined)
42+
unset(_expectedTargets)
43+
44+
45+
# Compute the installation prefix relative to this file.
46+
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
47+
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
48+
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
49+
if(_IMPORT_PREFIX STREQUAL "/")
50+
set(_IMPORT_PREFIX "")
51+
endif()
52+
53+
# Create imported target jinja2cpp
54+
add_library(jinja2cpp STATIC IMPORTED)
55+
56+
set_target_properties(jinja2cpp PROPERTIES
57+
INTERFACE_COMPILE_DEFINITIONS "variant_CONFIG_SELECT_VARIANT=variant_VARIANT_NONSTD"
58+
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
59+
)
60+
61+
# INTERFACE_LINK_LIBRARIES "nonstd::expected-lite;nonstd::variant-lite;nonstd::value_ptr-lite;nonstd::optional-lite;\$<LINK_ONLY:boost::variant>;\$<LINK_ONLY:boost::filesystem>;\$<LINK_ONLY:boost::algorithm>"
62+
63+
if(CMAKE_VERSION VERSION_LESS 2.8.12)
64+
message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
65+
endif()
66+
67+
# Load information for each installed configuration.
68+
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
69+
file(GLOB CONFIG_FILES "${_DIR}/jinja2cpp-cfg-*.cmake")
70+
foreach(f ${CONFIG_FILES})
71+
include(${f})
72+
endforeach()
73+
74+
include(${_DIR}/jinja2cpp-config-deps.cmake)
75+
76+
# Cleanup temporary variables.
77+
set(_IMPORT_PREFIX)
78+
79+
# Commands beyond this point should not need to know the version.
80+
set(CMAKE_IMPORT_FILE_VERSION)
81+
cmake_policy(POP)

include/jinja2cpp/error_info.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <iostream>
77
#include <vector>
8+
#include <type_traits>
89

910
namespace jinja2
1011
{
@@ -57,6 +58,38 @@ class ErrorInfoTpl
5758
: m_errorData(std::move(data))
5859
{}
5960

61+
~ErrorInfoTpl() noexcept
62+
{
63+
static_assert(std::is_nothrow_move_constructible<ErrorCode>::value, "Should be nothrow-moveable");
64+
static_assert(std::is_nothrow_move_constructible<SourceLocation>::value, "Should be nothrow-moveable");
65+
static_assert(std::is_nothrow_move_constructible<std::vector<SourceLocation>>::value, "Should be nothrow-moveable");
66+
static_assert(std::is_nothrow_move_constructible<Value>::value, "Should be nothrow-moveable");
67+
static_assert(std::is_nothrow_move_constructible<std::vector<Value>>::value, "Should be nothrow-moveable");
68+
static_assert(std::is_nothrow_move_constructible<std::basic_string<CharT>>::value, "Should be nothrow-moveable");
69+
static_assert(std::is_nothrow_move_constructible<Data>::value, "Should be nothrow-moveable");
70+
static_assert(std::is_nothrow_move_constructible<ErrorInfoTpl<CharT>>::value, "Should be nothrow-moveable");
71+
static_assert(std::is_nothrow_move_assignable<ErrorInfoTpl<CharT>>::value, "Should be nothrow-moveable");
72+
}
73+
ErrorInfoTpl(const ErrorInfoTpl<CharT>&) = default;
74+
ErrorInfoTpl(ErrorInfoTpl<CharT>&& val) noexcept
75+
: m_errorData(std::move(val.m_errorData))
76+
{ }
77+
78+
79+
ErrorInfoTpl& operator =(const ErrorInfoTpl<CharT>&) = default;
80+
ErrorInfoTpl& operator =(ErrorInfoTpl<CharT>&& val) noexcept
81+
{
82+
if (this == &val)
83+
return *this;
84+
85+
std::swap(m_errorData.code, val.m_errorData.code);
86+
std::swap(m_errorData.srcLoc, val.m_errorData.srcLoc);
87+
std::swap(m_errorData.relatedLocs, val.m_errorData.relatedLocs);
88+
std::swap(m_errorData.extraParams, val.m_errorData.extraParams);
89+
std::swap(m_errorData.locationDescr, val.m_errorData.locationDescr);
90+
91+
return *this;
92+
}
6093

6194
ErrorCode GetCode() const
6295
{

include/jinja2cpp/reflected_value.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
#define JINJA2_REFLECTED_VALUE_H
33

44
#include "value.h"
5+
6+
#include <nonstd/optional.hpp>
7+
58
#include <vector>
69
#include <set>
710
#include <cstddef>
811
#include <string>
912
#include <type_traits>
1013
#include <memory>
11-
#include <boost/optional.hpp>
1214

1315
namespace jinja2
1416
{
@@ -80,11 +82,13 @@ class ReflectedMapImpl : public ReflectedMapImplBase<ReflectedMapImpl<T>>
8082
template<typename Fn>
8183
Value GetField(Fn&& accessor) const
8284
{
83-
return accessor(m_valuePtr ? *m_valuePtr : m_value.get());
85+
if (!m_valuePtr && !m_value)
86+
return Value();
87+
return accessor(m_valuePtr ? *m_valuePtr : m_value.value());
8488
}
8589

8690
private:
87-
boost::optional<T> m_value;
91+
nonstd::optional<T> m_value;
8892
const T* m_valuePtr = nullptr;
8993
};
9094

include/jinja2cpp/value.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ class Value
120120

121121
Value();
122122
Value(const Value& val);
123-
Value(Value&& val);
123+
Value(Value&& val) noexcept;
124124
~Value();
125125

126126
Value& operator =(const Value&);
127-
Value& operator =(Value&&);
127+
Value& operator =(Value&&) noexcept;
128128
template<typename T>
129129
Value(T&& val, typename std::enable_if<!AnyOf<T, Value, ValuesList, UserCallable>::value>::type* = nullptr)
130130
: m_data(std::forward<T>(val))
@@ -272,10 +272,20 @@ inline Value GenericList::GetValueByIndex(int64_t index) const
272272

273273
inline Value::Value() = default;
274274
inline Value::Value(const Value& val) = default;
275-
inline Value::Value(Value&& val) = default;
275+
inline Value::Value(Value&& val) noexcept
276+
: m_data(std::move(val.m_data))
277+
{
278+
}
276279
inline Value::~Value() = default;
277280
inline Value& Value::operator =(const Value&) = default;
278-
inline Value& Value::operator =(Value&&) = default;
281+
inline Value& Value::operator =(Value&& val) noexcept
282+
{
283+
if (this == &val)
284+
return *this;
285+
286+
m_data.swap(val.m_data);
287+
return *this;
288+
}
279289

280290

281291
} // jinja2

0 commit comments

Comments
 (0)