How can I introduce external non-CMake project?

I’m attempted to introduce flat_hash_map and emhash to my CMake project.

As you can see, flat_hash_map is a header-only library and doesn’t support any build system, so there is unneeded to build. I think add the source directory to target_include_directories just fine.

Additionally, emhash is a strange project which doesn’t provides target like emhash5::HashMap. CMakeLists.txt in emhash seems just use it to build benchmark programs.

Is there any way to introduce these properly?

For the flat_hash_map, I’d probably create an INTERFACE library right after calling FetchContent_MakeAvailable. That will be much nicer to use.

For the emhash I’d probably do the same (it’s also header-only, right?), but also add SOURCE_SUBDIR disable_cmake to the FetchContent_Declare, which should avoid bringing the unwanted targets into your build.

Thanks for your inspiration. Another question, why does flat_hash_map_SOURCE_DIR is not defined in the following snippets?

cmake_minimum_required(VERSION 4.0)
project(test CXX)

include(FetchContent)

FetchContent_Declare(
    flat_hash_map
    GIT_REPOSITORY https://github.com/skarupke/flat_hash_map.git
    GIT_TAG 2c4687431f978f02a3780e24b8b701d22aa32d9c
    GIT_SHALLOW TRUE
)

FetchContent_Declare(
    emhash
    GIT_REPOSITORY https://github.com/ktprime/emhash.git
    GIT_TAG b7ff3147a5b206d6fccd52cd3d63cdbfc4acf8fd
    GIT_SHALLOW TRUE
    SOURCE_SUBDIR disable_cmake
)

FetchContent_MakeAvailable(emhash flat_hash_map)

add_library(flat_hash_map INTERFACE)
target_include_directories(flat_hash_map ${flat_hash_map_SOURCE_DIR})

add_library(emhash INTERFACE)
target_sources(emhash INTERFACE
    FILE_SET HEADERS
        BASE_DIRS ${emhash_SOURCE_DIR}
        FILES *.hpp
)

add_executable(example main.cc)
target_link_libraries(example 
    PRIVATE
    flat_hash_map
    emhash
)

I’ve tested it and the variable is set. I guess what you’re struggling with is the error message:

CMake Error at CMakeLists.txt:25 (target_include_directories):
  target_include_directories called with invalid arguments

That’s because you only can set INTERFACE include directories on an INTERFACE target.
Try:

target_include_directories(flat_hash_map INTERFACE "${flat_hash_map_SOURCE_DIR}")
1 Like