c++cmaketesseractleptonica

How does one link and include lib-leptonica in a cross platform make file?


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).


Solution

  • 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.