DanBloomberg / leptonica

Leptonica is an open source library containing software that is broadly useful for image processing and image analysis applications. The official github repository for Leptonica is: danbloomberg/leptonica. See leptonica.org for more documentation.
Other
1.72k stars 384 forks source link

1.84.0 fails to build in FreeBSD 14.0 due missing reference to libm using CMake #724

Closed diizzyy closed 6 months ago

diizzyy commented 6 months ago
[ 68% 541/788] : && /usr/bin/cc -O2 -pipe -march=tigerlake  -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -O2 -pipe -march=tigerlake  -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing  -DNDEBUG -fstack-protector-strong prog/CMakeFiles/dna_reg.dir/dna_reg.c.o -o bin/dna_reg  -Wl,-rpath,/usr/ports/graphics/leptonica/work/.build/src:/usr/local/lib  src/libleptonica.so.6.0.0  -Wl,-rpath-link,/usr/local/lib && :
FAILED: bin/dna_reg
: && /usr/bin/cc -O2 -pipe -march=tigerlake  -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing -O2 -pipe -march=tigerlake  -fstack-protector-strong -isystem /usr/local/include -fno-strict-aliasing  -DNDEBUG -fstack-protector-strong prog/CMakeFiles/dna_reg.dir/dna_reg.c.o -o bin/dna_reg  -Wl,-rpath,/usr/ports/graphics/leptonica/work/.build/src:/usr/local/lib  src/libleptonica.so.6.0.0  -Wl,-rpath-link,/usr/local/lib && :
ld: error: undefined symbol: sin
>>> referenced by dna_reg.c
>>>               prog/CMakeFiles/dna_reg.dir/dna_reg.c.o:(main)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
*** Error code 1

Adding "-lm" to LDFLAGS fixes the build

DanBloomberg commented 6 months ago

Two other problems: I tried building in ubuntu 20.04 with cmake and it failed because it didn't know the correct compiler args for C-17. It also didn't find the installed openjpeg library 2.3.0.

cmake ..
-- The C compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
-- Found PNG: /usr/lib/x86_64-linux-gnu/libpng.so (found version "1.6.37") 
-- Found GIF: /usr/local/lib/libgif.so (found suitable version "5.1.4", minimum required is "5") 
-- Found JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (found version "80") 
-- Found TIFF: /usr/lib/x86_64-linux-gnu/libtiff.so (found version "4.1.0") 
-- Could NOT find WebP (missing: WebP_DIR)
-- Found non-cmake WebP: /usr/lib/x86_64-linux-gnu/libwebp.so
-- Found WebP: /usr/lib/x86_64-linux-gnu/libwebp.so;/usr/lib/x86_64-linux-gnu/libwebpmux.so ()
-- Could NOT find OpenJPEG (missing: OpenJPEG_DIR)
-- Setting build type to 'Release' as none was specified.
-- Looking for include file dlfcn.h
-- Looking for include file dlfcn.h - found
-- Looking for include file inttypes.h
-- Looking for include file inttypes.h - found
-- Looking for include file memory.h
-- Looking for include file memory.h - found
-- Looking for include file stdint.h
-- Looking for include file stdint.h - found
-- Looking for include file stdlib.h
-- Looking for include file stdlib.h - found
-- Looking for include file strings.h
-- Looking for include file strings.h - found
-- Looking for include file string.h
-- Looking for include file string.h - found
-- Looking for include file sys/stat.h
-- Looking for include file sys/stat.h - found
-- Looking for include file sys/types.h
-- Looking for include file sys/types.h - found
-- Looking for include file unistd.h
-- Looking for include file unistd.h - found
-- Looking for fmemopen
-- Looking for fmemopen - found
-- Looking for fstatat
-- Looking for fstatat - found
-- Check if the system is big endian
-- Searching 16 bit integer
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of unsigned short
-- Check size of unsigned short - done
-- Using unsigned short
-- Check if the system is big endian - little endian
-- 
-- General configuration for Leptonica 
-- --------------------------------------------------------
-- Build type: Release
-- Compiler: GNU
-- C compiler options:

-- Linker options: 

-- Install directory: /usr/local
-- 
-- Build with sw [SW_BUILD]: OFF
-- Build utility programs [BUILD_PROG]: OFF
-- Used ZLIB library: /usr/lib/x86_64-linux-gnu/libz.so
-- Used PNG library:  /usr/lib/x86_64-linux-gnu/libpng.so;/usr/lib/x86_64-linux-gnu/libz.so
-- Used JPEG library: /usr/lib/x86_64-linux-gnu/libjpeg.so
-- Used OpenJPEG library: 
-- Used TIFF library: /usr/lib/x86_64-linux-gnu/libtiff.so
-- Used GIF library:  /usr/local/lib/libgif.so
-- Used WebP library: /usr/lib/x86_64-linux-gnu/libwebp.so;/usr/lib/x86_64-linux-gnu/libwebpmux.so
-- --------------------------------------------------------
-- 
-- Configuring done
CMake Error in src/CMakeLists.txt:
  Target "leptonica" requires the language dialect "C17" (with compiler
  extensions), but CMake does not know the compile flags to use to enable it.
zdenop commented 6 months ago

@DanBloomberg : Last cmake GA job works fine for Ubuntu 20.04 https://github.com/DanBloomberg/leptonica/actions/runs/7313600843/job/19925360933

Can you check your installation? What is your gcc, openjeg versions?

zdenop commented 6 months ago

@diizzyy : Is autotools build working properly?

Can you please add to prog/CMakeLists.txt the following code if it works on FreeBSD:

if(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD.*|DragonFly.*|FreeBSD")
  check_library_exists(m sin "" HAVE_LIBM)
  if(HAVE_LIBM)
    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} m)
  endif (HAVE_LIBM)
endif(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD.*|DragonFly.*|FreeBSD")
DanBloomberg commented 6 months ago

gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0.

I can get it to compile by removing two lines in CMakeLists.txt:

# set(CMAKE_C_STANDARD 17)
# set(CMAKE_C_STANDARD_REQUIRED ON)

I have been using libopenjp2 2.3.0. I downloaded and built 2.5.0, and it now finds the library. However when trying to build the library it gets the same error as was found a few days ago with 2.5.0, due to some fragile and obsolete code for building with 2.0.

/tmp/git3/src/jp2kio.c:938:5: error: too few arguments to function ‘opj_stream_set_user_data’
  938 |     opj_stream_set_user_data(l_stream, fp);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /tmp/git3/src/jp2kio.c:117:
/usr/local/include/openjpeg-2.5/openjpeg.h:1235:27: note: declared here
 1235 | OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream,
      |                           ^~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [src/CMakeFiles/leptonica.dir/build.make:1077: src/CMakeFiles/leptonica.dir/jp2kio.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:8841: src/CMakeFiles/leptonica.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

I'm surprised others haven't reported this. It is fixed by commenting out the code in jp2kio.c leading to the 2-arg function:

// #if OPJ_VERSION_MINOR == 0
//     opj_stream_set_user_data(l_stream, fp);
// #else
    opj_stream_set_user_data(l_stream, fp,
                             (opj_stream_free_user_data_fn)NULL);
// #endif
zdenop commented 6 months ago

Well gcc9 seems not to support the c17 standard so you can not use it for building Tesseract, e.g. everybody uses recent version...

More interesting is that in Github action I see nothing about a compiler, so I would expect that it uses the default 20.04 compiler...

I use libopenjp2 2.5.0 on Windows and there was no problem to compile leptonica. However GA that uses openjp2 from git reports and there is the problem: https://github.com/DanBloomberg/leptonica/actions/runs/7313482066/job/19925104247

DanBloomberg commented 6 months ago

I have cleaned up jp2kio.c, removing all references to openjpeg library versions before 2.1. So 2.1+ is now a requirement. I will push the change to master if you agree that we will no longer support openjpeg library version 2.0.

OK, so Tesseract requires at least gcc10, which is later than the 9.4 compiler that came with ubuntu 20.04. I have now downloaded and installed gcc 13.1.0. However, I'm still getting the C17 error with the new compiler:

cmake ..
-- The C compiler identification is GNU 13.1.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
-- Found PNG: /usr/lib/x86_64-linux-gnu/libpng.so (found version "1.6.37") 
-- Found GIF: /usr/local/lib/libgif.so (found suitable version "5.1.4", minimum required is "5") 
-- Found JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (found version "80") 
-- Found TIFF: /usr/lib/x86_64-linux-gnu/libtiff.so (found version "4.1.0") 
-- Could NOT find WebP (missing: WebP_DIR)
-- Found non-cmake WebP: /usr/lib/x86_64-linux-gnu/libwebp.so
-- Found WebP: /usr/lib/x86_64-linux-gnu/libwebp.so;/usr/lib/x86_64-linux-gnu/libwebpmux.so ()
-- Found OpenJPEG: openjp2 (2.5.0)
-- Setting build type to 'Release' as none was specified.
-- Looking for include file dlfcn.h
-- Looking for include file dlfcn.h - found
-- Looking for include file inttypes.h
-- Looking for include file inttypes.h - found
-- Looking for include file memory.h
-- Looking for include file memory.h - found
-- Looking for include file stdint.h
-- Looking for include file stdint.h - found
-- Looking for include file stdlib.h
-- Looking for include file stdlib.h - found
-- Looking for include file strings.h
-- Looking for include file strings.h - found
-- Looking for include file string.h
-- Looking for include file string.h - found
-- Looking for include file sys/stat.h
-- Looking for include file sys/stat.h - found
-- Looking for include file sys/types.h
-- Looking for include file sys/types.h - found
-- Looking for include file unistd.h
-- Looking for include file unistd.h - found
-- Looking for fmemopen
-- Looking for fmemopen - found
-- Looking for fstatat
-- Looking for fstatat - found
-- Check if the system is big endian
-- Searching 16 bit integer
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of unsigned short
-- Check size of unsigned short - done
-- Using unsigned short
-- Check if the system is big endian - little endian
-- 
-- General configuration for Leptonica 
-- --------------------------------------------------------
-- Build type: Release
-- Compiler: GNU
-- C compiler options:

-- Linker options: 

-- Install directory: /usr/local
-- 
-- Build with sw [SW_BUILD]: OFF
-- Build utility programs [BUILD_PROG]: OFF
-- Used ZLIB library: /usr/lib/x86_64-linux-gnu/libz.so
-- Used PNG library:  /usr/lib/x86_64-linux-gnu/libpng.so;/usr/lib/x86_64-linux-gnu/libz.so
-- Used JPEG library: /usr/lib/x86_64-linux-gnu/libjpeg.so
-- Used OpenJPEG library: openjp2
-- Used TIFF library: /usr/lib/x86_64-linux-gnu/libtiff.so
-- Used GIF library:  /usr/local/lib/libgif.so
-- Used WebP library: /usr/lib/x86_64-linux-gnu/libwebp.so;/usr/lib/x86_64-linux-gnu/libwebpmux.so
-- --------------------------------------------------------
-- 
-- Configuring done
CMake Error in src/CMakeLists.txt:
  Target "leptonica" requires the language dialect "C17" (with compiler
  extensions), but CMake does not know the compile flags to use to enable it.
DanBloomberg commented 6 months ago

And ... cmake is version 3.16.3

diizzyy commented 6 months ago

@zdenop Not out of the box, this works on my end

    if(${target} MATCHES "dna_reg|extrema_reg|insert_reg|locminmax_reg|numa1_reg|otsutest1|plottest|pta_reg|rotatefastalt|watershed_reg")
      if(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD.*|DragonFly.*|FreeBSD")
        check_library_exists(m sin "" HAVE_LIBM)
        if(HAVE_LIBM)
          target_link_libraries       (${target} leptonica -lm)
        endif()
      endif()
    else()
      target_link_libraries       (${target} leptonica)
    endif()
zdenop commented 6 months ago

Is there a problem with linking shared libm to all programs? I do not like to maintain a list of example progs just because of FreeBSD ...

Regarding your snippet - the first test (if) should be for FreeBSD - there is no reason why any extra test should be run for other platforms.

Also target_link_libraries should be target_link_libraries(${target} leptonica m) - see

So it should look like:

if(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD.*|DragonFly.*|FreeBSD")
  check_library_exists(m sin "" HAVE_LIBM)
  if(HAVE_LIBM)
    SET(EXTRA_LIBS "m")
  endif(HAVE_LIBM)
endif(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD.*|DragonFly.*|FreeBSD")

...
target_link_libraries           (${target} leptonica ${EXTRA_LIBS})
diizzyy commented 6 months ago

While it's not a huge issue in this case overlinking is concidered bad in general. There is -Wl,-as-needed however my understand is that it's discouraged in general compared to linking correctly from the start and it may come with unintended side effects?

Indeed, my example could use some optimization :)

amitdo commented 6 months ago

I have cleaned up jp2kio.c, removing all references to openjpeg library versions before 2.1. So 2.1+ is now a requirement. I will push the change to master if you agree that we will no longer support openjpeg library version 2.0.

2.1.0 was released in Apr 2014.

amitdo commented 6 months ago

Well gcc9 seems not to support the c17 standard so you can not use it for building Tesseract, e.g. everybody uses recent version...

Tesseract 5.x requires C++17. It works fine on GCC 9.

DanBloomberg commented 6 months ago

I knew that libopenjp2 2.1 is 10 years old. Just want your permission to end support for 2.0. Given this, I will make a new leptonica release 1.84.1 that solves the problem with 2.5.

Also,the problem on my old laptop with cmake and C17 is a configuration issue, because I still have the problem with gcc 13.1. So this is not a leptonica issue.

zdenop commented 6 months ago

If I got this right Ubuntu support openjp >= 2.3.1. If it is correct, I would not care about supporting the older version.

amitdo commented 6 months ago

Regarding openjpeg >= 2.1. No problem, IMO.

RHEL 8/9. Ubuntu 20.04/22.04(/24.04) and the latest 2 Debian releases all have openjpeg >= 2.1 in their repos.

The above distros versions also have GCC >= 8 which is the minimal requirement for the latest Tesseract version.

DanBloomberg commented 6 months ago

1.84.1 has been released.

@diizzyy Sorry for spamming your issue #724.

As for overlinking, I suspect that linkers are now smart enough to ignore libraries that are not used. see, eg.

diizzyy commented 6 months ago

In theory that works but then again... https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed

DanBloomberg commented 6 months ago

The gentoo page says the "as needed" flag doesn't work in FreeBSD. I would still be surprised if the FreeBSD linker includes unnecessary libraries in static executables.

diizzyy commented 6 months ago

As needed does indeed work with both LLVM/Clang and GCC however I was more trying to point out that linkers in general are still trying to be "safe".

zdenop commented 6 months ago

@diizzyy : can you check the current master code?

diizzyy commented 6 months ago

Hi,

Unfortunately this breaks build like @stweil reported

include(CheckLibraryExists) Needs to be added

Best regards, Daniel

stweil commented 6 months ago

Hi Daniel, I fixed that. It now works for Ubuntu (and hopefully for FreeBSD, too).

zdenop commented 6 months ago

@diizzyy : IMO this issue is fixed (e.g. it could be closed)

diizzyy commented 6 months ago

Agreed, thanks for the help