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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/modules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build & Test with modules

on:
push:
branches: [master]
pull_request:
branches: [master]
paths:
- "CMakeLists.txt"
- "cmake/**"
- "include/jwt-cpp/**"
- "tests/cmake/**"
- ".github/actions/**"
- ".github/workflows/cmake.yml"

jobs:
build:
name: ${{ matrix.runs_on }}-${{ matrix.compiler }}-${{ matrix.configure_preset }}
runs-on: ${{ matrix.runs_on }}
strategy:
fail-fast: false
matrix:
include:
- runs_on: windows-2025-vs2026
compiler: msvc-14.50
configure_preset: "x64-vs-modules"
build_preset: "x64-vs-modules-build"
test_preset : "x64-vs-modules-test"
# To be uncommented once GitHub Actions adds GCC 15 with Ubuntu 26
# - runs_on: ubuntu-latest
# compiler: gcc-15
# configure_preset: "linux-debug"
# build_preset: "linux-debug-build"
# test_preset : "linux-debug-test"
# - runs_on: ubuntu-latest
# compiler: clang-18
# cc: clang
# cxx: clang++
# configure_preset: "linux-debug-modules"
# build_preset: "linux-debug-modules-build"
# test_preset : "linux-debug-modules-test"
steps:

- uses: actions/checkout@v6

- uses: lukka/get-cmake@latest

- name: "Build & Test"
uses: lukka/run-cmake@v10
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
with:
configurePreset: ${{ matrix.configure_preset }}
buildPreset: ${{ matrix.build_preset }}
testPreset: ${{ matrix.test_preset }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
out/

# Visual Studio 2015 cache/options directory
.vs/
Expand Down
91 changes: 72 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ if(POLICY CMP0135) # DOWNLOAD_EXTRACT_TIMESTAMP
cmake_policy(SET CMP0135 NEW)
endif()

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to make this an default value then users can override the value by cmake's -D option during configuraton.


# HUNTER_ENABLED is always set if this package is included in a project using hunter (HunterGate sets it) In this case
# we will use hunter as well to stay consistent. If not the use can supply it on configure to force using hunter.
if(HUNTER_ENABLED)
Expand All @@ -20,6 +22,8 @@ option(JWT_BUILD_TESTS "Configure CMake to build tests (or not)" OFF)
option(JWT_BUILD_DOCS "Adds a target for building the doxygen documentation" OFF)
option(JWT_ENABLE_COVERAGE "Enable code coverage testing" OFF)
option(JWT_ENABLE_FUZZING "Enable fuzz testing" OFF)
option(JWT_ENABLE_MODULES "Build C++ modules" OFF)
option(JWT_USE_IMPORT_STD "Use import std" OFF)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a requirement, but asking for "import std" to be available will reduce the complexity.


option(JWT_DISABLE_PICOJSON "Do not provide the picojson template specialiaze" OFF)
option(JWT_DISABLE_BASE64 "Do not include the base64 implementation from this library" OFF)
Expand Down Expand Up @@ -92,50 +96,95 @@ endif()

set(JWT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/jwt.h)
set(JWT_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)
foreach(traits ${JWT_JSON_TRAITS_OPTIONS})
list(APPEND JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/traits/${traits}/defaults.h
${JWT_INCLUDE_PATH}/jwt-cpp/traits/${traits}/traits.h)
endforeach()

if(NOT JWT_DISABLE_BASE64)
list(APPEND JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/base.h)
list(APPEND JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/base.h)
endif()

add_library(jwt-cpp INTERFACE)
if (JWT_ENABLE_MODULES)
if(CMAKE_VERSION VERSION_LESS "4.3")
message(FATAL_ERROR "CMake >= 4.3 is required to build with modules")
endif()

set(CMAKE_CXX_SCAN_FOR_MODULES ON)

if(JWT_USE_IMPORT_STD)
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
set(CMAKE_CXX_MODULE_STD 1)
endif()
endif()
endif()

if (JWT_ENABLE_MODULES)
add_library(jwt-cpp STATIC)
set(JWT_LIBRARY_TYPE PUBLIC)
else()
add_library(jwt-cpp INTERFACE)
set(JWT_LIBRARY_TYPE INTERFACE)
endif()
add_library(jwt-cpp::jwt-cpp ALIAS jwt-cpp) # To match export
target_compile_features(jwt-cpp INTERFACE cxx_std_11)

if(NOT JWT_ENABLE_MODULES)
target_compile_features(jwt-cpp ${JWT_LIBRARY_TYPE} cxx_std_11)
else()
if(NOT JWT_USE_IMPORT_STD)
target_compile_features(jwt-cpp ${JWT_LIBRARY_TYPE} cxx_std_20)
else()
target_compile_features(jwt-cpp ${JWT_LIBRARY_TYPE} cxx_std_23)
target_compile_definitions(jwt-cpp PRIVATE JWT_USE_IMPORT_STD)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was public, could we remove the extra defines in the examples and test apps?

endif()
target_sources(jwt-cpp
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES
BASE_DIRS ${JWT_MODULE_PATH}
FILES ${JWT_MODULE_PATH}/jwt.cppm
)
endif()

if(JWT_DISABLE_BASE64)
target_compile_definitions(jwt-cpp INTERFACE JWT_DISABLE_BASE64)
target_compile_definitions(jwt-cpp ${JWT_LIBRARY_TYPE} JWT_DISABLE_BASE64)
endif()
if(JWT_DISABLE_PICOJSON)
target_compile_definitions(jwt-cpp INTERFACE JWT_DISABLE_PICOJSON)
target_compile_definitions(jwt-cpp ${JWT_LIBRARY_TYPE} JWT_DISABLE_PICOJSON)
endif()


source_group(
TREE "${JWT_INCLUDE_PATH}"
PREFIX "Implementation files"
FILES ${JWT_HEADER_FILES}
)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
target_include_directories(jwt-cpp INTERFACE $<BUILD_INTERFACE:${JWT_INCLUDE_PATH}>
target_include_directories(jwt-cpp ${JWT_LIBRARY_TYPE} $<BUILD_INTERFACE:${JWT_INCLUDE_PATH}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

if(${JWT_SSL_LIBRARY} MATCHES "OpenSSL")
target_link_libraries(jwt-cpp INTERFACE OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(jwt-cpp ${JWT_LIBRARY_TYPE} OpenSSL::SSL OpenSSL::Crypto)
endif()

if(${JWT_SSL_LIBRARY} MATCHES "LibreSSL")
target_link_libraries(jwt-cpp INTERFACE LibreSSL::TLS)
target_link_libraries(jwt-cpp ${JWT_LIBRARY_TYPE} LibreSSL::TLS)
endif()

if(${JWT_SSL_LIBRARY} MATCHES "wolfSSL")
target_link_libraries(jwt-cpp INTERFACE PkgConfig::wolfssl)
target_link_libraries(jwt-cpp ${JWT_LIBRARY_TYPE} PkgConfig::wolfssl)
# This is required to access OpenSSL compatibility API
target_include_directories(jwt-cpp INTERFACE ${wolfssl_INCLUDE_DIRS})
# This flag is required to have the mandatory header included automatically
target_include_directories(jwt-cpp ${JWT_LIBRARY_TYPE} ${wolfssl_INCLUDE_DIRS})
# This flag is required to have the mandatory header included automatically
# https://github.com/Thalhammer/jwt-cpp/pull/352#discussion_r1627971786
# https://github.com/wolfSSL/wolfssl/blob/3b74a6402998a8b8839e25e31ba8ac74749aa9b0/wolfssl/wolfcrypt/settings.h#L58
target_compile_definitions(jwt-cpp INTERFACE EXTERNAL_OPTS_OPENVPN)
target_compile_definitions(jwt-cpp ${JWT_LIBRARY_TYPE} EXTERNAL_OPTS_OPENVPN)
endif()

if(NOT JWT_DISABLE_PICOJSON AND JWT_EXTERNAL_PICOJSON)
target_link_libraries(jwt-cpp INTERFACE picojson::picojson)
target_link_libraries(jwt-cpp ${JWT_LIBRARY_TYPE} picojson::picojson)
endif()

# Hunter needs relative paths so the files are placed correctly
Expand All @@ -146,18 +195,22 @@ endif()
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/jwt-cpp-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config.cmake
INSTALL_DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake VERSION 0.7.2
COMPATIBILITY ExactVersion)

install(TARGETS jwt-cpp EXPORT jwt-cpp-targets PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake VERSION 0.7.2 COMPATIBILITY ExactVersion)
if (JWT_ENABLE_MODULES)
install(TARGETS jwt-cpp EXPORT jwt-cpp-targets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILE_SET cxx_modules DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/modules)
else()
install(TARGETS jwt-cpp EXPORT jwt-cpp-targets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
install(EXPORT jwt-cpp-targets NAMESPACE jwt-cpp:: FILE jwt-cpp-targets.cmake
DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})
install(DIRECTORY ${JWT_INCLUDE_PATH}/jwt-cpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(NOT JWT_EXTERNAL_PICOJSON AND NOT JWT_DISABLE_PICOJSON)
install(FILES ${JWT_INCLUDE_PATH}/picojson/picojson.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/picojson)
endif()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake
Comment thread
DockedFerret800 marked this conversation as resolved.
DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})

if(JWT_BUILD_EXAMPLES)
add_subdirectory(example)
Expand Down
57 changes: 57 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,77 @@
"JWT_BUILD_EXAMPLES": "ON",
"JWT_BUILD_TESTS": "ON"
}
},
{
"name": "windows-vs-base",
"hidden": true,
"generator": "Visual Studio 18 2026",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-vs-modules",
"displayName": "x64 (VS generator) with Modules",
"inherits": "windows-vs-base",
"architecture": "x64",
"cacheVariables": {
"JWT_ENABLE_MODULES": "ON",
"JWT_USE_IMPORT_STD": "ON",
"JWT_BUILD_EXAMPLES": "ON"
}
},
{
"name": "linux-debug-modules",
"displayName": "Linux Debug with Modules",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"JWT_ENABLE_MODULES": "ON",
"JWT_USE_IMPORT_STD": "ON",
"JWT_BUILD_EXAMPLES": "ON"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
}
],
"buildPresets": [
{
"name": "dev",
"configurePreset": "dev",
"configuration": "Debug"
},
{
"name": "x64-vs-modules-build",
"configurePreset": "x64-vs-modules"
},
{
"name": "linux-debug-modules-build",
"configurePreset": "linux-debug-modules"
}
],
"testPresets": [
{
"name": "dev",
"displayName": "Run all tests",
"configurePreset": "dev"
},
{
"name": "x64-vs-modules-test",
"configurePreset": "x64-vs-modules"
},
{
"name": "linux-debug-modules-test",
"configurePreset": "linux-debug-modules"
}
]
}
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ If you are looking to issue or verify more unique tokens, checkout out the [exam

Building on the goal of providing flexibility.

#### Modules support
jwt-cpp supports C++20/23 modules. There are two configuration options: `JWT_ENABLE_MODULES` to enable modules (С++20) and `JWT_USE_IMPORT_STD` to use `import std` (С++23).
CMake example:
```cmake
set(JWT_ENABLE_MODULES ON)
set(JWT_USE_IMPORT_STD ON)
```
You can now `import jwt_cpp;`.

#### SSL Compatibility

jwt-cpp supports [OpenSSL](https://github.com/openssl/openssl), [LibreSSL](https://github.com/libressl-portable/portable), and [wolfSSL](https://github.com/wolfSSL/wolfssl). For a listed of tested versions, check [this page](docs/ssl.md) for more details.
Expand Down
9 changes: 9 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ It's strongly recommended to use a package manager, as JWT-CPP has dependencies

When manually adding this dependency, and the dependencies this has, check the GitHub Actions and Workflows for some inspiration about how to go about it.

#### Modules support
jwt-cpp supports C++20/23 modules. There are two configuration options: `JWT_ENABLE_MODULES` to enable modules (С++20) and `JWT_USE_IMPORT_STD` to use `import std` (С++23).
CMake example:
```cmake
set(JWT_ENABLE_MODULES ON)
set(JWT_USE_IMPORT_STD ON)
```
You can now `import jwt_cpp;`.

### Package Manager

- Conan: <https://conan.io/center/recipes/jwt-cpp>
Expand Down
20 changes: 19 additions & 1 deletion example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.15)
project(jwt-cpp-examples)

if(NOT TARGET jwt-cpp)
Expand All @@ -14,25 +14,43 @@ endif()
add_executable(print-claims print-claims.cpp)
target_link_libraries(print-claims jwt-cpp::jwt-cpp)
add_custom_target(print-claims-run COMMAND print-claims)
if (JWT_ENABLE_MODULES)
target_compile_definitions(print-claims PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(private-claims private-claims.cpp)
target_link_libraries(private-claims jwt-cpp::jwt-cpp)
add_custom_target(private-claims-run COMMAND private-claims)
if (JWT_ENABLE_MODULES)
target_compile_definitions(private-claims PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(rsa-create rsa-create.cpp)
target_link_libraries(rsa-create jwt-cpp::jwt-cpp)
add_custom_target(rsa-create-run COMMAND rsa-create)
if (JWT_ENABLE_MODULES)
target_compile_definitions(rsa-create PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(rsa-verify rsa-verify.cpp)
target_link_libraries(rsa-verify jwt-cpp::jwt-cpp)
add_custom_target(rsa-verify-run COMMAND rsa-verify)
if (JWT_ENABLE_MODULES)
target_compile_definitions(rsa-verify PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(jwks-verify jwks-verify.cpp)
target_link_libraries(jwks-verify jwt-cpp::jwt-cpp)
add_custom_target(jwks-verify-run COMMAND jwks-verify)
if (JWT_ENABLE_MODULES)
target_compile_definitions(jwks-verify PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(es256k es256k.cpp)
target_link_libraries(es256k jwt-cpp::jwt-cpp)
if (JWT_ENABLE_MODULES)
target_compile_definitions(es256k PRIVATE JWT_ENABLE_MODULES)
endif()

add_executable(partial-claim-verifier partial-claim-verifier.cpp)
target_link_libraries(partial-claim-verifier jwt-cpp::jwt-cpp nlohmann_json::nlohmann_json)
Loading