jsoncpp icon indicating copy to clipboard operation
jsoncpp copied to clipboard

CMake FetchContent build error

Open mratzloff opened this issue 2 years ago • 3 comments

Describe the bug I'm attempting to switch my project's dependencies over to CMake's FetchContent functionality, but jsoncpp returns a build error. Full disclaimer, I'm just starting to experiment with the FetchContent functionality and I'm not an expert on CMake.

I'm using CMake 3.25.2. The version of CMake that introduced FetchContent_MakeAvailable, which downloads and builds external dependencies, was 3.14.

Here's the error:

λ cmake .
[...]
-- JsonCpp Version: 1.9.5
######################################################
# jsoncpp should not be configured & built in the jsoncpp source directory
# You must run cmake in a build directory.
# For example:
# mkdir jsoncpp-Sandbox ; cd jsoncpp-sandbox
# git clone https://github.com/open-source-parsers/jsoncpp.git # or download & unpack the source tarball
# mkdir jsoncpp-build
# this will create the following directory structure
#
# jsoncpp-Sandbox
#  +--jsoncpp
#  +--jsoncpp-build
#
# Then you can proceed to configure and build
# by using the following commands
#
# cd jsoncpp-build
# cmake ../jsoncpp # or ccmake, or cmake-gui
# make
#
# NOTE: Given that you already tried to make an in-source build
#       CMake have already created several files & directories
#       in your source tree. run 'git status' to find them and
#       remove them by doing:
#
#       cd jsoncpp-Sandbox/jsoncpp
#       git clean -n -d
#       git clean -f -d
#       git checkout --
#
######################################################
CMake Error at _deps/jsoncpp_dep-src/include/PreventInSourceBuilds.cmake:41 (message):
  Quitting configuration
Call Stack (most recent call first):
  _deps/jsoncpp_dep-src/include/PreventInSourceBuilds.cmake:45 (AssureOutOfSourceBuilds)
  _deps/jsoncpp_dep-src/CMakeLists.txt:81 (include)

To Reproduce Steps to reproduce the behavior:

  1. Include the following snippet in a project with a CMakeLists.txt file:
cmake_minimum_required (VERSION 3.14)
[...]
FetchContent_Declare (jsoncpp_dep
	GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp
	GIT_TAG 5defb4ed1a4293b8e2bf641e16b156fb9de498cc)

FetchContent_MakeAvailable (jsoncpp_dep)
  1. Run cmake . in the project directory.

Expected behavior The project would build as expected.

Desktop (please complete the following information):

  • OS: macOS 12.6.3 Monterey
  • CMake 3.25.2

mratzloff avatar Feb 09 '23 04:02 mratzloff

For anyone who might encounter the same issue, I resolved it with ExternalProject. I'm doing this after several FetchContent calls for other libraries, so if you don't do that, be sure to change jsoncpp_prefix.

include (ExternalProject)

set (jsoncpp_prefix ${FETCHCONTENT_BASE_DIR}/jsoncpp_dep)

ExternalProject_Add (jsoncpp_dep
	GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp
	GIT_TAG 5defb4ed1a4293b8e2bf641e16b156fb9de498cc
	PREFIX ${jsoncpp_prefix}
	CMAKE_CACHE_ARGS
		-DBUILD_SHARED_LIBS:BOOL=OFF
		-DBUILD_OBJECT_LIBS:BOOL=OFF
		-DJSONCPP_WITH_CMAKE_PACKAGE:BOOL=OFF
		-DJSONCPP_WITH_POST_BUILD_UNITTEST:BOOL=OFF
		-DJSONCPP_WITH_PKGCONFIG_SUPPORT:BOOL=OFF
		-DJSONCPP_WITH_TESTS:BOOL=OFF
	INSTALL_COMMAND "")

ExternalProject_Get_Property (jsoncpp_dep SOURCE_DIR BINARY_DIR)
set (jsoncpp_dep_SOURCE_DIR ${SOURCE_DIR})
set (jsoncpp_dep_BINARY_DIR ${BINARY_DIR})

set (jsoncpp_includes ${jsoncpp_dep_SOURCE_DIR}/include)
set (jsoncpp_lib ${jsoncpp_dep_BINARY_DIR}/lib)

target_link_libraries (my_project PRIVATE jsoncpp_object)
target_include_directories (my_project PRIVATE ${jsoncpp_includes})

If you're less familiar with CMake, jsoncpp_dep is my own name for the dependency, but jsoncpp_object comes from jsoncpp's CMakeLists.txt. It also defines and builds targets for jsoncpp_static and jsoncpp_lib, depending on what type of library you want to link to. I also wanted isolated builds, so I disabled the install step.

This could still be made to work with FetchContent, but I'll leave it up to the project maintainers on whether or not to close this ticket.

mratzloff avatar Feb 11 '23 00:02 mratzloff

Running into this same issue, it looks like by default FetchContent tries to build in the src dir instead of using a separate build dir, so this requirement breaks depending on this from FetchContent

nabilwadih avatar Apr 17 '23 19:04 nabilwadih

Well, there is no issue, and using FetchContent works perfectly. The cmake should not be built in the source directory as it warns in the message you pasted above. And it suggests the solution as well.

....
# jsoncpp should not be configured & built in the jsoncpp source directory
# You must run cmake in a build directory.
...

It is not something specific to the jsoncpp. It is how it the cmake works.

If you want to run it from the current directory you can tell it where to build stuff (aka: where is the working directory where the cmake can build its artefacts without polluting the source directory):

 # this will use the "dot" as the current source dir and create "build" dir with the results. The name of directory ("build") is arbitrary or course.
 # it will not compile anything yet - just prepare the files (like makefiles) for the compilation
cmake -S . -B build

# then you can compile the project like so:
cmake --build build

# you can find results in `./build/....` for execution.

opokatech avatar Jan 07 '25 16:01 opokatech