Skip to content

meson build does not install nlohmann_json*.cmake files #3885

@heitbaum

Description

@heitbaum

Description

Issue identified that meson build does not install nlohmann_json*.cmake files into /usr/share/cmake/nlohmann_json, so packages expecting these .cmake files are unable to build.

Ref: LibreELEC/LibreELEC.tv#7250

we have reverted back to cmake builds for the time being. ** Our package build system prefers meson over cmake

Reproduction steps

Complete a meson build

Expected vs. actual results

Use a cmake build

Minimal code example

Na

Error messages

Na

Compiler and operating system

LibreELEC :master / gcc 12.2

Library version

3.11.2

Validation

  • The bug also occurs if the latest version from the develop branch is used.
    I can successfully compile and run the unit tests.

Activity

nlohmann

nlohmann commented on Dec 17, 2022

@nlohmann
Owner

I am not an expert on Meson. PRs welcome!

eli-schwartz

eli-schwartz commented on Dec 18, 2022

@eli-schwartz
Contributor

Is there a static cmake file that can be installed?

heitbaum

heitbaum commented on Dec 18, 2022

@heitbaum
Author

Ok: having a more detailed look:

meson install_pkg

./usr/lib/pkgconfig/nlohmann_json.pc
./usr/include/nlohmann/json_fwd.hpp
./usr/include/nlohmann/json.hpp

cmake install_pkg

./usr/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake
./usr/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake
./usr/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake
./usr/share/pkgconfig/nlohmann_json.pc
./usr/include/nlohmann/detail/string_concat.hpp
./usr/include/nlohmann/detail/string_escape.hpp
./usr/include/nlohmann/detail/value_t.hpp
./usr/include/nlohmann/detail/macro_scope.hpp
./usr/include/nlohmann/detail/abi_macros.hpp
./usr/include/nlohmann/detail/iterators
./usr/include/nlohmann/detail/iterators/iter_impl.hpp
./usr/include/nlohmann/detail/iterators/primitive_iterator.hpp
./usr/include/nlohmann/detail/iterators/json_reverse_iterator.hpp
./usr/include/nlohmann/detail/iterators/iteration_proxy.hpp
./usr/include/nlohmann/detail/iterators/iterator_traits.hpp
./usr/include/nlohmann/detail/iterators/internal_iterator.hpp
./usr/include/nlohmann/detail/hash.hpp
./usr/include/nlohmann/detail/input/lexer.hpp
./usr/include/nlohmann/detail/input/json_sax.hpp
./usr/include/nlohmann/detail/input/input_adapters.hpp
./usr/include/nlohmann/detail/input/position_t.hpp
./usr/include/nlohmann/detail/input/binary_reader.hpp
./usr/include/nlohmann/detail/input/parser.hpp
./usr/include/nlohmann/detail/exceptions.hpp
./usr/include/nlohmann/detail/conversions/to_json.hpp
./usr/include/nlohmann/detail/conversions/from_json.hpp
./usr/include/nlohmann/detail/conversions/to_chars.hpp
./usr/include/nlohmann/detail/json_ref.hpp
./usr/include/nlohmann/detail/output/serializer.hpp
./usr/include/nlohmann/detail/output/binary_writer.hpp
./usr/include/nlohmann/detail/output/output_adapters.hpp
./usr/include/nlohmann/detail/json_pointer.hpp
./usr/include/nlohmann/detail/meta/is_sax.hpp
./usr/include/nlohmann/detail/meta/type_traits.hpp
./usr/include/nlohmann/detail/meta/identity_tag.hpp
./usr/include/nlohmann/detail/meta/detected.hpp
./usr/include/nlohmann/detail/meta/cpp_future.hpp
./usr/include/nlohmann/detail/meta/void_t.hpp
./usr/include/nlohmann/detail/meta/call_std
./usr/include/nlohmann/detail/meta/call_std/end.hpp
./usr/include/nlohmann/detail/meta/call_std/begin.hpp
./usr/include/nlohmann/detail/meta/std_fs.hpp
./usr/include/nlohmann/detail/macro_unscope.hpp
./usr/include/nlohmann/adl_serializer.hpp
./usr/include/nlohmann/json_fwd.hpp
./usr/include/nlohmann/thirdparty/hedley/hedley_undef.hpp
./usr/include/nlohmann/thirdparty/hedley/hedley.hpp
./usr/include/nlohmann/ordered_map.hpp
./usr/include/nlohmann/json.hpp
./usr/include/nlohmann/byte_container_with_subtype.hpp
eli-schwartz

eli-schwartz commented on Dec 18, 2022

@eli-schwartz
Contributor

nlohmann_jsonTargets.cmake is most likely a very complicated file autogenerated from scratch by the cmake program itself. Its job is basically to do add_library() and create an imported target defining the right include directory. If it could be statically generated, then Meson could simply install it as a file. The other two cmake files can be processed by Meson -- one is a template inside the repository, the other is a template inside cmake's installation directory. See https://mesonbuild.com/CMake-module.html#cmake-configuration-files

heitbaum

heitbaum commented on Dec 18, 2022

@heitbaum
Author

ls -l
total 16
-rw-r--r-- 1 docker docker 620 Dec 18 08:07 nlohmann_jsonConfig.cmake
-rw-r--r-- 1 docker docker 676 Dec 18 08:07 nlohmann_jsonConfigVersion.cmake
-rw-r--r-- 1 docker docker 4449 Dec 18 08:07 nlohmann_jsonTargets.cmake

the below is created from cmake/config.cmake.in / text replacement…

::::::::::::::
nlohmann_jsonConfig.cmake
::::::::::::::
include(FindPackageHandleStandardArgs)
set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE})
find_package_handle_standard_args(nlohmann_json CONFIG_MODE)

if(NOT TARGET nlohmann_json::nlohmann_json)
    include("${CMAKE_CURRENT_LIST_DIR}/nlohmann_jsonTargets.cmake")
    if((NOT TARGET nlohmann_json) AND
       (NOT nlohmann_json_FIND_VERSION OR
        nlohmann_json_FIND_VERSION VERSION_LESS 3.2.0))
        add_library(nlohmann_json INTERFACE IMPORTED)
        set_target_properties(nlohmann_json PROPERTIES
            INTERFACE_LINK_LIBRARIES nlohmann_json::nlohmann_json
        )
    endif()
endif()

below is just a simple text version replacement from cmake/nlohmann_jsonConfigVersion.cmake.in

::::::::::::::
nlohmann_jsonConfigVersion.cmake
::::::::::::::
# This is essentially cmake's BasicConfigVersion-SameMajorVersion.cmake.in but
# without the 32/64-bit check.  Since json is a header-only library, it doesn't
# matter if it was built on a different platform than what it is used on (see
# https://github.com/nlohmann/json/issues/1697).
set(PACKAGE_VERSION "3.11.2")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()

  if(PACKAGE_FIND_VERSION_MAJOR STREQUAL "3")
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  endif()

  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
      set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()
::::::::::::::
nlohmann_jsonTargets.cmake
::::::::::::::
# Generated by CMake

if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
   message(FATAL_ERROR "CMake >= 2.8.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
   message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...3.23)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS nlohmann_json::nlohmann_json)
  list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
  if(TARGET "${_cmake_expected_target}")
    list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
  else()
    list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
  endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
  unset(_cmake_targets_defined)
  unset(_cmake_targets_not_defined)
  unset(_cmake_expected_targets)
  unset(CMAKE_IMPORT_FILE_VERSION)
  cmake_policy(POP)
  return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
  string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
  string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)


# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
  set(_IMPORT_PREFIX "")
endif()

# Create imported target nlohmann_json::nlohmann_json
add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)

set_target_properties(nlohmann_json::nlohmann_json PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "\$<\$<NOT:\$<BOOL:ON>>:JSON_USE_GLOBAL_UDLS=0>;\$<\$<NOT:\$<BOOL:ON>>:JSON_USE_IMPLICIT_CONVERSIONS=0>;\$<\$<BOOL:OFF>:JSON_DISABLE_ENUM_SERIALIZATION=1>;\$<\$<BOOL:OFF>:JSON_DIAGNOSTICS=1>;\$<\$<BOOL:OFF>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>"
  INTERFACE_COMPILE_FEATURES "cxx_std_11"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
)

if(CMAKE_VERSION VERSION_LESS 3.0.0)
  message(FATAL_ERROR "This file relies on consumers using CMake 3.0.0 or greater.")
endif()

# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/nlohmann_jsonTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
  include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)

# Cleanup temporary variables.
set(_IMPORT_PREFIX)

# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
  foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
    if(NOT EXISTS "${_cmake_file}")
      message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
   \"${_cmake_file}\"
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
   \"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
    endif()
  endforeach()
  unset(_cmake_file)
  unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)

# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
dcbaker

dcbaker commented on Jan 19, 2025

@dcbaker
Contributor

This is a far more complicated set of CMake config files than Meson knows how to generate currently, and I'm not interested in adding support, or even really in reviewing it. It's sort of a well known problem that pkg-config has limited expressiveness and CMake targets are CMake specific, and theres work on going to develop something that is vendor neutral but more expressive called CPS. Given that both Meson and CMake are working to support CPS, I'm disinclined to spend time teaching Meson to output these more complex CMake configs

heitbaum

heitbaum commented on Jan 20, 2025

@heitbaum
Author

With the #4452 fix both pvr.freebox and pvr.vuplus are building with nlohmann_json, (so the pkgconfig seems to be enough.)

-- Found nlohmann_json: /var/media/DATA/home-rudi/LibreELEC.tv/build.LibreELEC-Generic.x86_64-13.0-devel/toolchain/x86_64-libreelec-linux-gnu/sysroot/usr/include

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @nlohmann@dcbaker@heitbaum@eli-schwartz

        Issue actions

          meson build does not install nlohmann_json*.cmake files · Issue #3885 · nlohmann/json