PROJ icon indicating copy to clipboard operation
PROJ copied to clipboard

build failed if -DENABLE_TIFF=ON

Open leleliu008 opened this issue 3 years ago • 6 comments

https://github.com/OSGeo/PROJ/releases/download/9.1.0/proj-9.1.0.tar.gz

report error messages:

/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_initCStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_freeCStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_lzma_preset'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_code'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_end'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_maxCLevel'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_createCStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_isError'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_getErrorName'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_memusage'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_endStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_createDStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_initDStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_freeDStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_stream_encoder'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_compressStream'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `lzma_stream_decoder'
/opt/ppkg/installing/proj/bin/ld: lib/libproj.so.25.9.1.0: undefined reference to `ZSTD_decompressStream'
collect2: error: ld returned 1 exit status

reason: it seems that FindTIFF can not find liblzma and libzstd, which is depended by libtiff for some reason.

cat /etc/os-release

PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

leleliu008 avatar Sep 09 '22 11:09 leleliu008

9 out of 10 times reports like these are resolved by installing the -dev version of the dependencies. So if you haven't installed libtiff-dev try that first. Make sure that you've read the installation guide carefully: https://proj.org/install.html#compilation-and-installation-from-source-code

Next, you need to include more information. A snippet of error messages is not enough. Include everything you did to get to that stage. You haven't even included the call to CMake that generated this message. In other words: Help us help you. Otherwise this issue won't get much attention.

kbevers avatar Sep 09 '22 11:09 kbevers

Please provide the exact way on how to reproduce this. For example as a set of commands to be executed in a ubuntu:22.04 Docker image.

My own attempt work: docker run --rm -it ubuntu:22.04 and inside the docker container

apt update
apt install cmake libtiff-dev libsqlite3-dev sqlite3 wget libcurl4-gnutls-dev g++
wget http://download.osgeo.org/proj/proj-9.1.0.tar.gz
tar xvzf proj-9.1.0.tar.gz
cd proj-9.1.0
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j12

rouault avatar Sep 09 '22 12:09 rouault

cmake provided module FindTIFF.cmake do not handle dependencies. it just find libtiff itself.

I reoslve this problem by adding my own FindTIFF.cmake in project's cmake dir

# https://cmake.org/cmake/help/latest/module/FindTIFF.html

if (TIFF_INCLUDE_DIRS AND TIFF_LIBRARIES)
    set(TIFF_FOUND TRUE)
else()
    include(FindPkgConfig)
    pkg_check_modules(PKG_CONFIG_TIFF QUIET libtiff-4)

    if (PKG_CONFIG_TIFF_FOUND)
        if (PKG_CONFIG_TIFF_INCLUDE_DIRS)
        	set(TIFF_INCLUDE_DIRS "${PKG_CONFIG_TIFF_INCLUDE_DIRS}")
	    elseif (PKG_CONFIG_TIFF_INCLUDEDIR)
        	set(TIFF_INCLUDE_DIRS "${PKG_CONFIG_TIFF_INCLUDEDIR}")
	    else()
		    find_path(TIFF_INCLUDE_DIRS tiff.h)
	    endif()

        set(TIFF_LIBRARIES )

        foreach(item ${PKG_CONFIG_TIFF_LINK_LIBRARIES})
            # https://sourceware.org/bugzilla/show_bug.cgi?id=21264
                if(item MATCHES ".*libm\\.a")
            elseif(item MATCHES ".*libpthread\\.a")
            else()
                get_filename_component(LIBRARIE_FILENAME ${item} NAME)

                if (NOT TARGET  TIFF::${LIBRARIE_FILENAME})
                    add_library(TIFF::${LIBRARIE_FILENAME} UNKNOWN IMPORTED)
                    set_target_properties(TIFF::${LIBRARIE_FILENAME} PROPERTIES IMPORTED_LOCATION "${item}")
                endif()

                list(APPEND TIFF_LIBRARIES TIFF::${LIBRARIE_FILENAME})
            endif()
        endforeach()

        if (NOT TARGET  TIFF::TIFF)
            add_library(TIFF::TIFF INTERFACE IMPORTED)
            set_target_properties(TIFF::TIFF PROPERTIES
                INTERFACE_INCLUDE_DIRECTORIES "${TIFF_INCLUDE_DIRS}"
                INTERFACE_LINK_LIBRARIES      "${TIFF_LIBRARIES}"
            )
        endif()

        if (PKG_CONFIG_TIFF_VERSION)
            set(TIFF_VERSION ${PKG_CONFIG_TIFF_VERSION})
        endif()
    endif()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TIFF REQUIRED_VARS TIFF_LIBRARIES TIFF_INCLUDE_DIRS VERSION_VAR TIFF_VERSION)

mark_as_advanced(TIFF_INCLUDE_DIRS TIFF_LIBRARIES)
sed -i 's|${TIFF_LIBRARY}|TIFF::TIFF|' src/lib_proj.cmake

leleliu008 avatar Sep 09 '22 12:09 leleliu008

when libtiff is shared library, there is no problem, because shared library has DT_NEEDED, but if libtiff is static library, libtiff has no dependencies infomations, linker will report undefined reference.

I suggest you use TIFF::TIFF or ${TIFF_LIBRARIES} instead of ${TIFF_LIBRARY} and write own FindTIFF.cmake

leleliu008 avatar Sep 09 '22 12:09 leleliu008

reproduce steps

docker run --rm -it ubuntu:22.04

following shell code run in the docker container

step1. install dependencies

apt -y update
apt -y install cmake make g++ curl sqlite3 libsqlite3-dev libcurl4-gnutls-dev

step2. export build environment variable

export CFLAGS='-fPIC'

step3. build libz from source

cd
curl -LO https://zlib.net/zlib-1.2.12.tar.gz
tar vxf zlib-1.2.12.tar.gz
cd zlib-1.2.12
cmake \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=$HOME/libz-installed \
        -S . \
        -B build.d
cmake --build build.d
cmake --install build.d

step4. build liblzma from source

cd
curl -LO https://tukaani.org/xz/xz-5.2.6.tar.gz
tar vxf xz-5.2.6.tar.gz
cd xz-5.2.6
./configure --prefix=$HOME/liblzma-installed
make
make install

step5. build libtiff.a from source

cd
curl -LO https://download.osgeo.org/libtiff/tiff-4.4.0.tar.gz
tar vxf tiff-4.4.0.tar.gz
cd tiff-4.4.0
cmake \
        -Dzlib=ON \
        -Dzstd=OFF \
        -Dlzma=ON \
        -Dlzw=OFF \
        -Dwebp=OFF \
        -Djpeg=OFF \
        -Djbig=OFF \
        -Dlerc=OFF \
        -Dtiff-docs=OFF \
        -Dtiff-tools=OFF \
        -Dtiff-tests=OFF \
        -DBUILD_SHARED_LIBS=OFF \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_FIND_ROOT_PATH="$HOME/libz-installed;$HOME/liblzma-installed" \
        -DCMAKE_INSTALL_PREFIX=$HOME/libtiff-installed \
        -S . \
        -B build.d
cmake --build build.d
cmake --install build.d

step6. build proj from source

cd
curl -LO http://download.osgeo.org/proj/proj-9.1.0.tar.gz
tar xvf proj-9.1.0.tar.gz
cd proj-9.1.0
cmake -S. -B build.d -DCMAKE_FIND_ROOT_PATH=$HOME/libtiff-installed
cmake --build build.d

leleliu008 avatar Sep 09 '22 17:09 leleliu008

when libtiff is shared library, there is no problem, because shared library has DT_NEEDED, but if libtiff is static library, libtiff has no dependencies infomations, linker will report undefined reference.

I suggest you use TIFF::TIFF or ${TIFF_LIBRARIES} instead of ${TIFF_LIBRARY}

Indeed. <Pkg>_LIBRARY should be used only as an input variable. Either <Pkg>_LIBRARIES should be used for the actual linking, or the target. Howver, the latter a) often requires a minimum version of CMake, b) requires find_dependency in the exported CMake config and c) cannot be used in the Libs.private field of pkg-config files.

The same problem exists for Curl. vcpkg patches proj to use targets for both dependencies, and Requires.private for the pkg-config file.

write own FindTIFF.cmake

Please don't.

dg0yt avatar Sep 12 '22 05:09 dg0yt

I believe this has been fixed with #3374

kbevers avatar Feb 22 '23 10:02 kbevers