Path declared in INTERFACE_INCLUDE_DIRECTORIES imported target seemingly not found

I’m working on a C++ project that exports a bunch of libraries and tries to make use of CMakePackageConfigHelpers to be findable using find_package. After installation, projects attempting to make use of it, like:

cmake_minimum_required(VERSION 3.18)
project(jsontoolkit_hello VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(JSONToolkit REQUIRED)
add_executable(jsontoolkit_hello hello.cc)
target_link_libraries(jsontoolkit_hello PRIVATE sourcemeta::jsontoolkit::json)

Face the following error:

CMake Error in CMakeLists.txt:
  Imported target "sourcemeta::jsontoolkit::json" includes non-existent path

    "/include"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.  

The find_package command correctly finds JSONToolkit, which on my system is located at: <prefix>/lib/cmake/jsontoolkit/JSONToolkitConfig.cmake. I can confirm this file is getting loaded if add any message() commands to it. This file does the following:

include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_jsontoolkit_json.cmake")

Which is located at lib/cmake/jsontoolkit/sourcemeta_jsontoolkit_json.cmake and correctly gets loaded. This file contains the following:

set_target_properties(sourcemeta::jsontoolkit::json PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "JSONTOOLKIT_BACKEND_RAPIDJSON"
  INTERFACE_COMPILE_OPTIONS "<..............>"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "rapidjson"
)

If I print ${_IMPORT_PREFIX}/include next to this declaration, I get: /Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include, which exists and matches the expected prefix:

$ tree /Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include
/Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include
└── jsontoolkit
    ├── json
    │   ├── iterators.h
    │   ├── rapidjson
    │   │   ├── common.h
    │   │   ├── iterators.h
    │   │   ├── read.h
    │   │   └── write.h
    │   ├── read.h
    │   └── write.h
    ├── json.h
    ├── jsonschema
    │   └── resolver.h
    └── jsonschema.h

5 directories, 10 files

So why can’t CMake find it? I can confirm the error is around the INTERFACE_INCLUDE_DIRECTORIES, as if I modify the declaration of that line, the error message is reflected accordingly.

Am I missing anything?

Relevant links, in case its useful:

Here is a GitHub Actions run highlighting steps being ran and a full example of the error: Make the project consumable by CMake `find_package()` · sourcemeta/jsontoolkit@ed13d9a · GitHub

Perhaps check whether something else may be changing the value of the INTERFACE_INCLUDE_DIRECTORIES property on the sourcemeta::jsontoolkit::json target. The output logged in the error suggests that the value of that property is just /include. Try printing the value of that property from your own project as late as possible to check.

From what I can tell, CMake will automatically replace the prefix directory (set with CMAKE_PREFIX_PATH) with / (perhaps for better readability?)

What I’m doing is:

  • Install the library in question under /Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist through cmake --install
  • Configure the project trying to utilize the library (with find_package()) by passing an appropriate prefix path through cmake -S <...> -B <...> -DCMAKE_PREFIX_PATH=Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist

The generated target export from my library has this:

INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"

Which results in the error being printed as /include. If I change it to ${_IMPORT_PREFIX}/xxx, I get the following (notice the absolute path):

CMake Error in CMakeLists.txt:
  Imported target "sourcemeta::jsontoolkit::json" includes non-existent path

    "/Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/xxx"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

If I hardcode the right path as follows:

INTERFACE_INCLUDE_DIRECTORIES "/Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include"

That again gets printed as it originally was:

CMake Error in CMakeLists.txt:
  Imported target "sourcemeta::jsontoolkit::json" includes non-existent path

    "/include"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

So there seems to be some replacement going on that I don’t fully understand.

I also tried fetching the INTERFACE_INCLUDE_DIRECTORIES of the imported target on the CMake project making use of it, and even then the path is correct, and exists:

get_target_property(X sourcemeta::jsontoolkit::json INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS "${X}")

This prints:

/Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include

Which definitely exists:

$ tree /Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include
/Users/jviotti/Projects/sourcemeta/jsontoolkit/build/dist/include
└── jsontoolkit
    ├── json
    │   ├── iterators.h
    │   ├── rapidjson
    │   │   ├── common.h
    │   │   ├── iterators.h
    │   │   ├── read.h
    │   │   └── write.h
    │   ├── read.h
    │   └── write.h
    ├── json.h
    ├── jsonschema
    │   └── resolver.h
    └── jsonschema.h

It is very weird that it complains it doesn’t exist.

I found the problem. The error is highly misleading. The include directory being corrupted was on a dependency of the interface library in question, where a CMake variable was getting expanded to anything.

It was a project problem, and easy to spot once past the confusing error. Ideally, the error message would point at the right library.