Experimenting with FetchContent - issue with Jansson

Starting to wrap my head around FetchContent, so tried some demo code using Jansson library.

App CMakeLists.txt:

cmake_minimum_required( VERSION 3.24 )

project( FetchContentTest
	VERSION 0.1
	DESCRIPTION "Test use of FetchContent"
	LANGUAGES C
)

include( cmake/FetchRules.cmake )


FetchContent_MakeAvailable(
	jansson
)


add_executable( json_test )

target_sources( json_test PRIVATE
	src/main.c
)

target_link_libraries( json_test PRIVATE jansson )

The ‘cmake/FetchRules.cmake’ include:

include( FetchContent )
FetchContent_Declare(
	jansson
	GIT_REPOSITORY https://github.com/akheron/jansson.git
	GIT_TAG 684e18c927e89615c2d501737e90018f4930d6c5 # v2.14
)

Then I run cmake -S source -B Build/my_build_dir -G Xcode

CMake process completes successfully, but when I try to compile I get an error that #include "jansson.h" - not found. “” or <> makes no difference. I can see the Jansson library has been downloaded and built in _deps, but I’m not getting a -I path to it in the Xcode build.

Jansson doesn’t use an alias, so I can’t tell whether CMake is not finding the target (and thus assuming its linking to an existing binary library) or something else is broken.

Any guidance?

1 Like

@craig.scott?

Use jansson::jansson (with NAMESPACE)

The jansson project doesn’t follow good CMake practice. It uses include_directories() instead of target_include_directories() to add its header search paths. As a result, it doesn’t propagate the necessary header search paths to anything that links to the jansson target. You will have to add those yourself, or better would be to patch the upstream jansson project to use target_include_directories() instead.

Ah, that makes sense. Thank you.

Exploring a bit further (and apologies for implicit request to debug a third party library by proxy):

In the _deps folder are three folders:

  • jansson-src
  • jansson-subbuild
  • jansson-build

I assume jansson-build is the interesting one as far as output is concerned. When I switch to the jansson target in Xcode and “build”, this is the directory that gets a libjansson.a created.

jansson-build/janssonConfig.cmake and jansson-build/cmake/janssonConfig.cmake both refer to ${CMAKE_CURRENT_LIST_DIR}/janssonTargets.cmake. The only janssonTargets.cmake I can find is in jansson-build/CMakeFiles/Export/9b80b8ed102b5ab69af1c2960c090ea5/janssonTargets.cmake.

This file (assuming it is executed) contains the following lines:

# Create imported target jansson::jansson
add_library(jansson::jansson STATIC IMPORTED)

set_target_properties(jansson::jansson PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)

I assumed this would define jansson::jansson and add the appropriate per-target library paths. But when I change the dependency line to target_link_libraries( json_test PRIVATE jansson::jansson ) then CMake complains that jansson::jansson is not found.

I picked the Jansson library to begin experimenting with because I wanted the functionality, not because it was the cleanest CMake example. That may have been a mistake. I think I’ll fork it and try hacking on the CMake files to see what happens.

Made some mods - moving add_definitions to target_compile_definitions and include_directories to target_include_directories with distinct build and install rules. Seems to work now.