2

When you install many packages through vcpkg (such as vcpkg install cairo), at the end of this process, you are told what find_package and target_link_libraries CMake commands to use in order to link to the package that was installed. And this works fine; you can even re-execute the install command to see these CMake commands again.

However, some packages installed through vcpkg don't have these. After installing Pango for example, there is no list of CMake commands to actually use the library. I found the target CMake file for find_package in several of the vcpkg package directories, but the Pango directory has no CMake file for the package.

For some reason, example code using Pango can still compile (ie: it can find Pango's headers), but it fails to link due to not linking to the right libraries.

So how is this supposed to work? Do I have to list the include directories, library directories, and library files through a variety of CMake interfaces for Pango? Or is there some alternative inclusion mechanism that takes care of the details like most other vcpkg packages?

Note that I'm using Visual Studio 2019's built-in CMake functionality to try to build with these.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Looks like they prepare [CMakeLists.txt](https://github.com/microsoft/vcpkg/blob/master/ports/pango/CMakeLists.txt) as a part of Pango port for vcpkg. Since this `CMakeLists.txt` doesn't EXPORT targets, you cannot directly include this package with `find_package`. Not sure about their expectations for using this package in your CMake code. Probably, they expect you to download (from somewhere) a script `FindPango.cmake`, so `find_package(Pango)` will be available for you. – Tsyvarev Apr 05 '21 at 18:04
  • @Tsyvarev, it's not the solution, you just need link manualy – RashidLadj_Winux Apr 05 '21 at 20:51
  • 1
    @RashidLadjouzi: Why using a script `FindXXX.cmake` is not a solution? Such scripts usually do `find_path` and `find_library` - the same commands you use in your answer's code. An advantage of "Find" script that it knows all possible names of libraries, all (relative) locations of libraries and headers. Some of such scripts are also aware about dependent libraries. Some of such scripts are able to extract the package's version. Why prefer manual scripting to using already existing scripts? – Tsyvarev Apr 05 '21 at 21:30

2 Answers2

3

find_package finds a particular kind of .cmake file that is usually shipped with vcpkg packages. These .cmake files do the work of setting include directories and libraries to link with.

As such, if a vcpkg package does not include such a file, you will need to essentially do the work that the file would have done. Fortunately, CMake and vcpkg know where the headers and library build files are for the various configurations. What you need to do is find those directories and libraries, then add them to your project (along with any other special compiler options that the package requires, which requires some familiarity with the package).

To find the include directory containing a library's header, use find_path to set a variable, giving it the name of a header file to search for. For example:

find_path(PANGO_INCLUDE_DIR pango/pango.h)

This header directory can then be set as part of the include path:

target_include_directories(project_name_here PRIVATE ${PANGO_INCLUDE_DIR})

Libraries are a bit harder, since you have to track down the full name (minus extensions) of the actual library. And if the package involves multiple libraries, you need to track down all of those which are applicable to you.

Given the name of a library or libraries of interest, you can find them one at a time with find_library, setting those libraries into variables:

find_library(PANGO_LIBRARY pango-1.0)
find_library(PANGOCAIRO_LIBRARY pangocairo-1.0)

You can then link with those libraries via target_link_libraries:

target_link_libraries(cairo_vcpkg PRIVATE
    ...
    ${PANGO_LIBRARY}
    ${PANGOCAIRO_LIBRARY}
    )
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
-1

Indeed, some packages installed via vcpkg do not export a .cmake file like Pango for you and SDL for me. I want to clarify that I have been trying to use vcpkg for two days, I share with you the cmakelist.txt that I use on my side so that SDL works as if I had used find_package (SDL Required)

cmake_minimum_required(VERSION 3.16)
project(xxxx)

### Specify the C++ standard ###

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)

### To find and use SDL ###

# find path of include and lib
find_path(SDL_INCLUDE_DIR SDL/SDL.h)
find_library(SDL_LIBRARY SDL)

# find pat of manual-link library
set (LIBRARIES_TO_LINK C:/dev/vcpkg/installed:/x64-windows/lib/manual-link)
find_library(SDL1_TEST SDLmain HINTS ${LIBRARIES_TO_LINK})

....
RashidLadj_Winux
  • 810
  • 1
  • 6
  • 17
  • I don't really understand what this is supposed to accomplish. What is `SDL_INCLUDE_DIR`? None of the rest of your code uses it. Is `SDL/SDL.h` supposed to be a header, and should I substitute one of Pango's headers? – Nicol Bolas Apr 05 '21 at 21:36
  • check this https://stackoverflow.com/questions/62224769/vcpkg-pango-cmake-build-fails-missing-header-file – RashidLadj_Winux Apr 06 '21 at 19:36