1

I am doing my first steps in CMake and I have a Hello World example where I would like to use libgit2. My directory structure is the following:

- main.cpp
- CMakeLists.txt
- cmake/Modules/Findlibgit2.cmake
- libs/libgit2/include/git2.h
- libs/libgit2/debug/git/git2.lib
- libs/libgit2/debug/git/git2.dll

I would like to link it either statically, or dynamically, at least it works for the beginning. But when I execute CMake, I receive the error message below. Could anyone help me with this?

Not searching for unused variables given on the command line.
[cmake] CMake Error at C:/Program Files/CMake/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
[cmake]   Could NOT find libgit2 (missing: GIT2_LIBRARY GIT2_INCLUDE_PATH)
[cmake] Call Stack (most recent call first):
[cmake]   C:/Program Files/CMake/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:445 (_FPHSA_FAILURE_MESSAGE)
[cmake]   cmake/Modules/Findlibgit2.cmake:15 (find_package_handle_standard_args)
[cmake]   CMakeLists.txt:6 (find_package)

Findlibgit2.cmake

# Find git2 Library
#
#  GIT2_INCLUDE_DIRS - where to find git2.h, etc.
#  GIT2_LIBRARIES    - List of libraries when using libgit2.
#  GIT2_FOUND        - True if libgit2 is found.

# GIT2_INCLUDE_PATH
find_path(GIT2_INCLUDE_PATH NAMES git2.h)
# GIT2_LIBRARY
find_library(GIT2_LIBRARY NAMES git2)

# handle the QUIETLY and REQUIRED arguments and set GIT2_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libgit2 REQUIRED_VARS GIT2_LIBRARY GIT2_INCLUDE_PATH)


if (GIT2_FOUND)
  set(GIT2_INCLUDE_DIR  ${GIT2_INCLUDE_PATH})
  set(GIT2_INCLUDE_DIRS ${GIT2_INCLUDE_PATH})
  set(GIT2_LIBRARIES    ${GIT2_LIBRARY})
endif()

mark_as_advanced(
  GIT2_INCLUDE_PATH
  GIT2_LIBRARY
)

CMakeLists.txt


cmake_minimum_required(VERSION 2.8.9)
project (backend)

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
find_package(libgit2 REQUIRED)

include_directories(${LIBGIT2_INCLUDE_DIR})
link_directories("backend/libs/libgit2/debug")
add_executable(backend main.cpp)
Kevin
  • 16,549
  • 8
  • 60
  • 74
Daniel Stephens
  • 2,371
  • 8
  • 34
  • 86
  • Cmake doesn't search for packages that are part of your directory structure unless you're manually changed the search path. Have you read the documentation around how some of those commands work? https://cmake.org/cmake/help/latest/command/find_path.html – Stephen Newell Jul 10 '20 at 04:03
  • Thank you! Does that mean it is meant to be for system libs? Do you have a simple example how to link against a lib? – Daniel Stephens Jul 12 '20 at 17:00

1 Answers1

1

It seems like libgit2 doesn't provide a CMake package configuration file, so it would be up to you to write a Find Module or find one on the internet. The Findlibgit2.cmake file you have is a good start.

I found another libgit2 Find Module online here: Findlibgit2.cmake. This one utilizes pkg-config, leveraging the .pc file provided by libgit2 itself, but, considering you're using Windows, would require you to install pkg-config manually. This may be more trouble than it's worth.

Regarding your error message:

Unless the libgit2 package is in the standard system path, CMake will not know where to look for it. So, you must explicitly tell CMake where to look. One simple way to do this is by modifying your Findlibgit2.cmake file, using HINTS for the find_* commands:

# GIT2_INCLUDE_PATH
find_path(GIT2_INCLUDE_PATH NAMES git2.h
    HINTS ${GIT2_INCLUDEDIR}
)
# GIT2_LIBRARY
find_library(GIT2_LIBRARY NAMES git2
    HINTS ${GIT2_LIBRARYDIR}
)

Now, we can populate these GIT2_INCLUDEDIR and GIT2_LIBRARYDIR variables to point to the installed libgit2 package. After doing so, find_package() should then succeed in finding the package components, and you can link to git2.lib using ${GIT2_LIBRARIES}.

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.9)
project (backend)

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")

# Set hints so CMake knows where libgit2 is located on your machine.
set(GIT2_INCLUDEDIR ${CMAKE_CURRENT_LIST_DIR}/libs/libgit2/include)
set(GIT2_LIBRARYDIR ${CMAKE_CURRENT_LIST_DIR}/libs/libgit2/debug/git)
find_package(libgit2 REQUIRED)

include_directories(${GIT2_INCLUDE_DIR})

# Don't need this line. Use of 'link_directories' is discouraged.
link_directories("backend/libs/libgit2/debug")

add_executable(backend main.cpp)
# Add this line to link against the libgit2 libraries.
target_link_libraries(backend PRIVATE ${GIT2_LIBRARIES})

A more portable way to set these HINTS variables is to instead set them when calling cmake on the command line:

cmake -DGIT2_INCLUDEDIR=C:/path/to/libgit2/include -DGIT2_LIBRARYDIR=D:/path/to/libgit2/lib ..

This way, if you have other developers working with the project, they can point to wherever they may have libgit2 installed on their machine, eliminating the need to modify the CMakeLists.txt file.

Kevin
  • 16,549
  • 8
  • 60
  • 74