0

In CMake most third party libraries don't require me to specify their include directory at all...they seem to take care of that for me behind the scenes. However, some third party libraries seem to put that work on my plate.

Are the differences I'm finding across third party libraries indicative of me doing something wrong? Or is CMake just a less structured environment where some third party libraries are going to hold your hand more than others? What is going on here? Best practices?

I'll give a couple examples. OpenCV makes things super easy, no need for me to mention their include directory:

set(OpenCV_DIR ${THIRD_PARTY_DIR}/OpenCV)
find_package(OpenCV REQUIRED)
...
add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})

However, Google's Protocol Buffer requires me to use the include_directories command in order to use their header files:

set(CMAKE_PREFIX_PATH ${THIRD_PARTY_PROTOBUF_DIR})
find_package(Protobuf ${THIRD_PARTY_DIR}/protobuf-2.6.1)
...
include_directories(${PROTOBUF_INCLUDE_DIRS})
add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})
Ed LaFave
  • 399
  • 3
  • 11
  • 1
    Probably, in the first case, you have OpenCV installed in your system as a system-wide package and thus headers are found in the standard paths. Try to uninstall it for a while and test it again. Let me know, if it's so I'll turn the comment in an answer. ;-) – skypjack Sep 23 '16 at 06:26
  • Thanks for the reply @skypjack but OpenCV and the other third party libraries I'm using aren't installed on a system wide level. I built the third parties from source (or downloaded pre-built binaries) and put their binaries/headers in a ThirdParty folder in my baseline. No installation. – Ed LaFave Sep 23 '16 at 15:42

1 Answers1

1

The target_include_directories() command was introduced with CMake version 2.8.11 in May 2013. That gave developers of libraries the possibility of self-propagating include paths.

But changing everything to target_include_directories() does break the backwards compatibility with previous versions of CMake (see target_include_directories prior to 2.8.12?).

So it's mainly a legacy issue I assume will vanish over time.

Most of time you can see what the library is using by the cmake_minimum_required() line at the top of the library's root CMakeLists.txt. And in case of e.g. the Protocol Buffers library, they do have updated to their CMakeLists.txt to cmake_minimum_required(VERSION 2.8.12) and do now make use of target_include_directories() (see commit from July 2015).

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149
  • For a more detailed discussion of how `target_include_directories()` and its other related `target_...` commands, [this article](https://crascit.com/2015/02/02/cmake-target-dependencies/) may be useful (disclosure: I wrote it). The article focuses more on `target_link_libraries()` but it shows the mechanism by which things like include directories can be attached to targets to be picked up automatically by things that link against it. – Craig Scott Sep 24 '16 at 00:00