Search code examples
c++shellcmaketesseractconan

Trouble setting up TesseractOCR with Conan (& cmake)


I've been looking at the Conan 2 documentations, issues and threads, but I cannot manage to get Tesseract working with Conan. Let me show you my setup:

App
└── main.cpp
CMakeLists.txt
conanfile.txt

main.cpp is the most basic PoC I could come up with:

#include <tesseract/baseapi.h>

int main(void) {
    tesseract::TessBaseAPI api;
    return 0;
}

My CMakeLists.txt:

cmake_minimum_required(VERSION 3.11)

# --------------------------------- Setup project config
set(PROJECT_NAME foo)
project(${PROJECT_NAME} CXX)
set(CMAKE_CXX_STANDARD 20)

# --------------------------------- Set project flags and optimization
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g3 -O0 -W -Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -g0 -O3")

# --------------------------------- Fetch sources
set(SOURCES App/main.cpp)

# --------------------------------- Fetch dependencies
find_package(Tesseract REQUIRED)

message(STATUS "Tesseract_INCLUDE_DIRS: ${Tesseract_INCLUDE_DIRS}")
message(STATUS "Tesseract_LIBRARIES: ${Tesseract_LIBRARIES}")
message(STATUS "Tesseract_VERSION: ${Tesseract_VERSION}")

# --------------------------------- Build binary
add_executable(${PROJECT_NAME} ${SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/App
    ${Tesseract_INCLUDE_DIRS}
)

And finally my conanfile.txt (Leptonica is a direct dependecy of Tesseract):

[requires]
tesseract/5.3.0
leptonica/1.82.0

[generators]
CMakeDeps
CMakeToolchain

Finally I just run the following commands (I usually do it with cmake then make, but these are the exact commands from the documentation):

conan install . --output-folder=build/ --build=missing
# [...]
# Install finished successfully

cmake -B build/ -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug
# [...]
# -- Tesseract_INCLUDE_DIRS: /Users/foo/.conan2/p/b/tesse4be5a6b24f5df/p/include
# -- Tesseract_LIBRARIES: Tesseract::libtesseract
# -- Tesseract_VERSION: 5.3.0
# [...]
# -- Configuring done (0.9s)
# -- Generating done (0.0s)
# -- Build files have been written to: /Users/foo/Desktop/test_tesseract/build

cmake --build build/ -j 4 -v
# [...]
# Change Dir: '/Users/foo/Desktop/test_tesseract/build'
# Run Build Command(s): /opt/homebrew/Cellar/cmake/3.27.0/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile -j4
# /opt/homebrew/Cellar/cmake/3.27.0/bin/cmake -S/Users/foo/Desktop/test_tesseract -B/Users/foo/Desktop/test_tesseract/build --check-build-system CMakeFiles/Makefile.cmake 0
# /opt/homebrew/Cellar/cmake/3.27.0/bin/cmake -E cmake_progress_start /Users/foo/Desktop/test_tesseract/build/CMakeFiles /Users/foo/Desktop/test_tesseract/build//CMakeFiles/progress.marks
# /Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/Makefile2 all
# /Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/toto.dir/build.make CMakeFiles/toto.dir/depend
# cd /Users/foo/Desktop/test_tesseract/build && /opt/homebrew/Cellar/cmake/3.27.0/bin/cmake -E cmake_depends "Unix Makefiles" /Users/foo/Desktop/test_tesseract /Users/foo/Desktop/test_tesseract /Users/foo/Desktop/test_tesseract/build /Users/foo/Desktop/test_tesseract/build /Users/foo/Desktop/test_tesseract/build/CMakeFiles/toto.dir/DependInfo.cmake "--color="
# /Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/toto.dir/build.make CMakeFiles/toto.dir/build
# [ 50%] Building CXX object CMakeFiles/toto.dir/App/main.cpp.o
# /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -I/Users/foo/Desktop/test_tesseract/App -I/Users/foo/.conan2/p/b/tesse4be5a6b24f5df/p/include -stdlib=libc++ -stdlib=libc++ -g3 -O0 -W -Wall -Wextra -std=gnu++20 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -MD -MT CMakeFiles/toto.dir/App/main.cpp.o -MF CMakeFiles/toto.dir/App/main.cpp.o.d -o CMakeFiles/toto.dir/App/main.cpp.o -c /Users/foo/Desktop/test_tesseract/App/main.cpp
# [100%] Linking CXX executable toto
# /opt/homebrew/Cellar/cmake/3.27.0/bin/cmake -E cmake_link_script CMakeFiles/toto.dir/link.txt --verbose=1
# /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -stdlib=libc++ -stdlib=libc++ -g3 -O0 -W -Wall -Wextra -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/toto.dir/App/main.cpp.o -o toto 
# ld: Undefined symbols:
#   tesseract::TessBaseAPI::TessBaseAPI(), referenced from:
#       _main in main.cpp.o
#   tesseract::TessBaseAPI::~TessBaseAPI(), referenced from:
#       _main in main.cpp.o
# clang: error: linker command failed with exit code 1 (use -v to see invocation)
# make[2]: *** [toto] Error 1
# make[1]: *** [CMakeFiles/toto.dir/all] Error 2
# make: *** [all] Error 2

At first I had an error where #include <tesseract/baseapi.h> in the main.cpp was not found, but that was just my fault, I forgot to link the library trough the CMakeLists.txt.

When I fixed that, I just cannot manage to get a -L, -I, or even -l in the build commands (looking with -v verbose mode), I just get undefined symbol errors.

To try and force at least a -l I tried setting the target_link_libraries() in the CMakeLists.txt, like so:

target_link_libraries(${PROJECT_NAME}
    PRIVATE ${Tesseract_LIBRARIES}
)

This yields the same result, and finally I manually forced it to write -ltesseract with the following:

target_link_libraries(${PROJECT_NAME}
    PRIVATE ${Tesseract_LIBRARIES}
    tesseract
)

This actually works and appends a the -l at the end, but I get an even worse error:

ld: library 'tesseract' not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)

For reference I am on arm64 architecture (MacOS), but I don't see why that would be the problem.


Solution

  • Conan takes into account the build type (Release/Debug/...)

    By default the conan profile detect command sets the configuration for build_type=Release, I was building my cmake with the -DCMAKE_BUILD_TYPE=Debug flag.

    Conan setup everything in the a path dedicated to the Release and cmake was looking in the path dedicated to Debug.

    Switching to -DCMAKE_BUILD_TYPE=Release fixed it.