0

I have the following cmake command:

include(FindPkgConfig)


# ditto for tesseract
pkg_search_module(LEPT lept)
find_library(
        LEPT
        NAMES leptonica liblept liblept-dev lept
        HINTS ${LEPT_INCLUDE_DIRS} ${LEPT_LIBRARY_DIRS}
)


// ditto for tesseract
target_include_dirs(tess_api PRIVATE ${LEPT_INCLUDE_DIRS})
target_link_libraries(tess_api LINK_PRIVATE ${LEPT})

And the following status report:

message(STATUS "LEPT: ${LEPT}")
message(STATUS "LEPT::INCLUDE: ${LEPT_INCLUDE_DIRS}")
message(STATUS "LEPT::LIBRARY: ${LEPT_LDFLAGS}")
message(STATUS "LEPT::CFLAGS: ${LEPT_CFLAGS}")

With the output:

-- LEPTONICA: /usr/local/Cellar/leptonica/1.82.0/lib/liblept.dylib
-- LEPTONICA::INCLUDE: /usr/local/Cellar/leptonica/1.82.0/include/leptonica
-- LEPTONICA::LIBRARY: -L/usr/local/Cellar/leptonica/1.82.0/lib;-llept
-- LEPTONICA::CFLAGS: -I/usr/local/Cellar/leptonica/1.82.0/include/leptonica

Where the leptonica inclusion is all the way into the leptonica source directory, rather than one stop before it (correct? incorrect?).


OK, great. However, one big issue. My C++ source file requires me to drop the leptonica in my inclusion:

#include "tesseract/..."  // like a charm
// #include "leptonica/allheaders.h" // WRONG!
#include "allheaders.h" // well this works :(

Which I would, in a dev machine on a non-cross-platform make, kludge.


However, ideally this project has best cross-platform practices implemented such that the leptonica path remains in the inclusion.

I am not sure how to achieve this, given that CMake + leptonica, and the source example from tesseract all have this disagreement about how leptonica ought to be included... (and in fact I disagree with the idea of including 3rd party headers as if they are in the local source directory).

Chris
  • 28,822
  • 27
  • 83
  • 158
  • This is clearly a bug with either Leptonica upstream's PkgConfig files or with the way Homebrew sets up the build. `LEPT_INCLUDE_DIRS` shouldn't include the last `leptonica` component. – Alex Reinking Jan 28 '22 at 17:57
  • Also `LINK_PRIVATE` is deprecated. Just use `PRIVATE`. – Alex Reinking Jan 28 '22 at 17:59
  • "and in fact I disagree with the idea of including 3rd party headers as if they are in the local source directory" ... the `-I` flags let you use `#include <...>` already. – Alex Reinking Jan 28 '22 at 18:19

2 Answers2

1

However, ideally this project has best cross-platform practices implemented...

That would be this:

find_package(PkgConfig)  # Never include(Find<Anything>)

pkg_search_module(Tesseract REQUIRED IMPORTED_TARGET ...)
pkg_search_module(Leptonica REQUIRED IMPORTED_TARGET lept)

target_link_libraries(tess_api 
    PRIVATE PkgConfig::Tesseract PkgConfig::Leptonica)

Always link to libraries via imported targets. You basically never need find_library outside of an actual Find module.

... implemented such that the leptonica path remains in the inclusion.

Now, upstream leptonica injects both the include/leptonica and include directories into your include path, but it seems Homebrew has patched (bugged) out the plain one. One way to fix this would be to write

pkg_search_module(Leptonica ...)

# Work around common Leptonica packaging bugs...
if (";${Leptonica_INCLUDE_DIRS};" MATCHES ";([^;]+)[/\\]leptonica[/\\]?;")
    target_include_directories(
        PkgConfig::Leptonica BEFORE INTERFACE "${CMAKE_MATCH_1}")
endif ()

This will try to match a path ending in "[/\]leptonica" and add its parent to the start of the includes list for the imported target.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
1

If you are serious about cross-platform, so forget PkgConfig. Why not use just cmake?

find_package(Leptonica REQUIRED)
user898678
  • 2,994
  • 2
  • 18
  • 17