json: Fail to build when including json.hpp as a system include

  • What is the issue you have?

When including json.hpp if the include directory is marked as a system include (-isystem rather than -I) it will fail to build

I have to turn on CMAKE_NO_SYSTEM_FROM_IMPORTED and force the include path to be used as -I instead of -isystem. -isystem is used whenever nlohmann is provided as part of an imported CMake target. This happened to me due to using nlohmann from hunter with LLVM for Windows.

  • Please describe the steps to reproduce the issue. Can you provide a small but working code example?

Sample CMake script

project(test)
cmake_minimum_required(VERSION 3.14)

add_executable(test main.cpp)
target_include_directories(test SYSTEM PRIVATE "<path/to/nlohmann/json>")

Simple C++

#include <nlohmann/json.hpp>

int main()
{
// Don't even have to call anything
return 0;
}
  • What is the expected behavior?

Program compiles successfully

  • And what is the actual behavior instead?

A ton of errors along the line of error: expected '>'enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and

Clang 9.0.0 but the same behavior occurs with 8.0.0/8.0.1

This is with LLVM for Windows and happens with the ClangCL toolset for VS2019 and the Ninja generator in CMake 3.15+

  • Did you use a released version of the library or the version from the develop branch?

Version 3.6.1 and 3.7.0 release versions have the same problem

Nope

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 55 (25 by maintainers)

Commits related to this issue

Most upvoted comments

Oki I tested from the develop branch, everything is green, great!

Unfortunately I don’t have the clang setup on my PC (I am using linux), it’s on a remote PC build machine with special rights. I hope today or tomorrow I can replicate it on my PC and try to replicate. 👍

The easiest way to fix this would just be to remove all instances of the alternate identifiers.

I’m really hesitant to making this change as these operators are valid C++ and we even include the <ciso646> header which should convince noncompliant compilers about this…

@Rogiel Could you provide a MWE?

Sure, here it is: https://github.com/Rogiel/nlohmann-json-pch-bug

If you comment out the hack at the end of CMakeLists.txt (that defines and, or and not to their respective operators) everything works fine but that is hacky and will 100% break on any non-toy example.

I have only managed to reproduce this with Windows clang++.exe (NOT clang-cl.exe).

Hey! Sorry for the late reply on this. I’ve just whipped up a MWE cmake project. Not sure how to do this sort of include pattern on godbolt. test.zip

If you build with main.cpp including “bad.h” build will fail. If you include “good.h” instead it will work.

Here’s bad.h:

#pragma once

#include <type_traits>
#include <iostream>
#include <ciso646>

template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

template<typename T, typename = enable_if_t<std::is_pod<T>::value and std::is_trivial<T>::value>>
bool square(T param) {
    return param and param;
}

And good.h

#pragma once

#include <type_traits>
#include <iostream>

template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

template<typename T, typename = enable_if_t<std::is_pod<T>::value && std::is_trivial<T>::value>>
bool square(T param) {
    return param && param;
}

Edit: Just to clarify with LLVM for Windows and Ninja installed I configure with: cmake -GNinja -Bbuild and build with cmake --build build

This only fails with clang as MSVC does not have a “system” include concept

I haven’t tested this on Linux or macos yet but I can if that would be helpful