0

I'm in the process of putting together a small c++ project using CMake for the first time. My current project structure is

├── bch
│   ├── CMakeLists.txt
│   ├── gf
│   │   ├── CMakeLists.txt
│   │   ├── include
│   │   │   └── gf.h
│   │   └── src
│   │       └── gf.cpp
│   ├── include
│   │   └── bch.h
│   └── src
│       └── bch.cpp
├── bsc
│   ├── CMakeLists.txt
│   ├── include
│   │   └── bsc.h
│   └── src
│       └── bsc.cpp
├── CMakeLists.txt
├── .gitignore
└── main.cpp

Currently I have gf as a subdirectory of bch. The contents of bch/CMakeLists is

cmake_minimum_required(VERSION 3.17)
project(bch VERSION 0.1.0)

# Targets
add_library(bch STATIC src/bch.cpp)

# Dependant
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/gf)
target_link_libraries(bch PUBLIC gf)

# Export to dependants
target_include_directories(bch PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

I would like to take the gf CMake project and place outside of the directory path of bch. This doesn't seem to be a supported structure when using the add_subdirectory command unless I'm missing something. Generally, what would be the current "Best Practice" for accomplishing my goal of decoupling the directory structure from the dependency tree?

ytgsyk4h
  • 25
  • 5
  • "I would like to take the `gf` CMake project and place outside of the directory path of `bch`. This doesn't seem to be a supported structure when using the `add_subdirectory` command" - **Why** do you think it is not supported? If you get an error `add_subdirectory not given a binary directory`, then see [that question](https://stackoverflow.com/q/50408169/3440745) and the answer about the way to resolve it. – Tsyvarev Jul 19 '20 at 18:36
  • That's the current configuration that I've opted for until I can get around to packaging the `gf` library into a module. I'm using the `bch/build` directory for the `gf` binaries which seems to work. The various blog posts I was reading seemed to imply that `add_subdirectory` is recommended for tightly coupled projects in-tree. – ytgsyk4h Jul 19 '20 at 19:12

1 Answers1

1

If you want to decouple the project from dependencies, then I would suggest splitting cmake project into two separate, exporting the dependent target and then importing it with 'find_package'. Here is quick google find for that topic: https://visualgdb.com/tutorials/linux/cmake/find_package

[edit]

For a more general approach I suggest cmake documentation:

https://cmake.org/cmake/help/latest/command/find_package.html#command:find_package

https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html

https://cmake.org/cmake/help/v3.18/command/install.html#export

The idea is:

  1. In a dependency project to generate a '*ConfigVersion.cmake' file, install all needed files (headers, binaries and *ConfigVersion.cmake) using the 'EXPORT' in parameter the 'install' command.

  2. In a final project use 'find_package' to import the dependency.

For bigger library projects I also suggest using namespaces to allow importing only selected parts of the library.

b00rt00s
  • 114
  • 5
  • Thanks for the link, though the walkthrough is pretty tightly coupled to VS environment. The issue I see with find_package() functionality is all the additional cruft necessary to cleanly package up the project. Even with the added complexity, it may end up being the way to go. I found [this](https://stackoverflow.com/questions/33534115/preferred-cmake-project-structure) while searching for some answers. – ytgsyk4h Jul 19 '20 at 18:26
  • I've updated the answer with a more general description. I hope it will help You. – b00rt00s Jul 19 '20 at 18:55