How to correctly define CMakeLists.txt for Tesseract?

I want to compile and build with CMake this simple tesseract C++ code:

#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>

int main()
    char *outText;

    tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
    // Initialize tesseract-ocr with English, without specifying tessdata path
    if (api->Init(NULL, "eng")) {
        fprintf(stderr, "Could not initialize tesseract.\n");

    // Open input image with leptonica library
    Pix *image = pixRead("phototest.tif");
    // Get OCR result
    outText = api->GetUTF8Text();
    printf("OCR output:\n%s", outText);

    // Destroy used object and release memory
    delete api;
    delete [] outText;

    return 0;

With this CMakeLists.txt file:

cmake_minimum_required(VERSION 3.5)


find_package(PkgConfig REQUIRED)

pkg_check_modules(tesseract REQUIRED IMPORTED_TARGET tesseract)
pkg_check_modules(leptonica REQUIRED IMPORTED_TARGET lept)
pkg_check_moduleS(libcurl REQUIRED IMPORTED_TARGET libcurl)

add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE BasicExample.cpp)

target_link_libraries(BasicExample PUBLIC

I’m getting these errors:

raphy@raohy:~/tesseract/Examples$ cmake -B builddir
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.8.1")
-- Checking for module 'tesseract'
--   Found tesseract, version 5.3.4
-- Checking for module 'lept'
--   Found lept, version 1.82.0
-- Checking for module 'libcurl'
--   Found libcurl, version 8.2.1
-- Configuring done (0.3s)
-- Generating done (0.0s)
-- Build files have been written to: /home/raphy/tesseract/Examples/builddir
raphy@raohy:~/tesseract/Examples$ cmake --build builddir/
[ 50%] Building CXX object CMakeFiles/BasicExample.dir/BasicExample.cpp.o
[100%] Linking CXX executable BasicExample
/usr/bin/ld: /usr/local/lib/libtesseract.a(baseapi.cpp.o): in function `tesseract::TessBaseAPI::ProcessPagesInternal(char const*, char const*, int, tesseract::TessResultRenderer*)::{lambda(char const*)#1}::operator()(char const*) const':
baseapi.cpp:(.text+0x13): undefined reference to `curl_easy_strerror'
/usr/bin/ld: baseapi.cpp:(.text+0x3b): undefined reference to `curl_easy_cleanup'
/usr/bin/ld: /usr/local/lib/libtesseract.a(baseapi.cpp.o): in function `tesseract::TessBaseAPI::ProcessPagesInternal(char const*, char const*, int, tesseract::TessResultRenderer*)':
baseapi.cpp:(.text+0xad07): undefined reference to `curl_easy_init'
/usr/bin/ld: baseapi.cpp:(.text+0xad48): undefined reference to `curl_easy_setopt'
/usr/bin/ld: baseapi.cpp:(.text+0xad5d): undefined reference to `curl_easy_strerror'
/usr/bin/ld: baseapi.cpp:(.text+0xad89): undefined reference to `curl_easy_cleanup'
/usr/bin/ld: baseapi.cpp:(.text+0xb26f): undefined reference to `curl_easy_setopt'
/usr/bin/ld: baseapi.cpp:(.text+0xb298): undefined reference to `curl_easy_setopt'
/usr/bin/ld: baseapi.cpp:(.text+0xb2c1): undefined reference to `curl_easy_setopt'
/usr/bin/ld: baseapi.cpp:(.text+0xb2fa): undefined reference to `curl_easy_setopt'
/usr/bin/ld: baseapi.cpp:(.text+0xb324): undefined reference to `curl_easy_setopt'
/usr/bin/ld: /usr/local/lib/libtesseract.a(baseapi.cpp.o):baseapi.cpp:(.text+0xb3c9): more undefined references to `curl_easy_setopt' follow
/usr/bin/ld: /usr/local/lib/libtesseract.a(baseapi.cpp.o): in function `tesseract::TessBaseAPI::ProcessPagesInternal(char const*, char const*, int, tesseract::TessResultRenderer*)':
baseapi.cpp:(.text+0xb455): undefined reference to `curl_easy_perform'
/usr/bin/ld: baseapi.cpp:(.text+0xb6b0): undefined reference to `curl_easy_cleanup'
/usr/bin/ld: /usr/local/lib/libtesseract.a(tessdatamanager.cpp.o): in function `tesseract::TessdataManager::LoadArchiveFile(char const*)':
tessdatamanager.cpp:(.text+0x199): undefined reference to `archive_read_new'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x1ad): undefined reference to `archive_read_support_filter_all'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x1b5): undefined reference to `archive_read_support_format_all'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x1c5): undefined reference to `archive_read_open_filename'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x1e6): undefined reference to `archive_entry_pathname'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x1f6): undefined reference to `archive_read_next_header'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x208): undefined reference to `archive_read_free'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x294): undefined reference to `archive_entry_size'
/usr/bin/ld: tessdatamanager.cpp:(.text+0x2e1): undefined reference to `archive_read_data'
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/BasicExample.dir/build.make:99: BasicExample] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/BasicExample.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2

But this CMakeLists.txt :

cmake_minimum_required(VERSION 3.5)


find_package(PkgConfig REQUIRED)

pkg_check_modules(libcurl REQUIRED IMPORTED_TARGET libcurl)

add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE url2file.c)

target_link_libraries(${PROJECT_NAME} PUBLIC

for this libcurl usage example:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <curl/curl.h>

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
  size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
  return written;

int main(int argc, char *argv[])
  CURL *curl_handle;
  static const char *pagefilename = "page.out";
  FILE *pagefile;

  if(argc < 2) {
    printf("Usage: %s <URL>\n", argv[0]);
    return 1;


  /* init the curl session */
  curl_handle = curl_easy_init();

  /* set URL to get here */
  curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]);

  /* Switch on full protocol/debug output while testing */
  curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);

  /* disable progress meter, set to 0L to enable it */
  curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);

  /* send all data to this function  */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

  /* open the file */
  pagefile = fopen(pagefilename, "wb");
  if(pagefile) {

    /* write the page body to this file handle */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);

    /* get it! */

    /* close the header file */

  /* cleanup curl stuff */


  return 0;

works fine :

raphy@raohy:~/curlExample$ cmake --build builddir/
[ 50%] Building C object CMakeFiles/Url2File.dir/url2file.c.o
[100%] Linking C executable Url2File
[100%] Built target Url2File

What am I missing ? How to make the CMakeLists.txt work for the tesseract C++ code example?

Does it work if you use the PkgConfig::libcurl target you requested above?

Though the errors seem to indicate that you have static libraries. IIRC, there are some issues around this. This issue looks relevant.

Thanks Ben

I solved the issue thanks to the suggestions and explanation received in StackOverFlow: c++ - How to correctly define CMakeLists.txt for Tesseract? - Stack Overflow

The problem was that curl and archive are requested and required by Tesseract itself, and, therefore, I had to make this explicitly:

set_property(TARGET PkgConfig::tesseract APPEND PROPERTY INTERFACE_LINK_LIBRARIES curl archive)