[poppler] Requires.private field missing in poppler.pc
suzuki toshiya
mpsuzuki at hiroshima-u.ac.jp
Thu Mar 29 08:17:47 UTC 2018
Hi,
I've posted my question to cmake mailing list, asking for
2 features to help the construction of pkg-config pc files.
https://cmake.org/pipermail/cmake/2018-March/067289.html
But it seems that nobody could remember appropriate and
existing solutions; on the other hand, the majority of the
responses to my question were suggesting to get rid of
pkg-config and native cmake package system.
So, here I post my current patch. The patch itself is
attached, but I want to explain in detail.
Regards,
mpsuzuki
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index efa6c3f..361951e 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -10,6 +10,43 @@ include(MacroOptionalFindPackage)
> find_package(PkgConfig)
> include(MacroEnsureVersion)
> include(MacroBoolTo01)
> +
> +#
> +# PKG_SEARCH_AVAILABLE_MODULE([var-name-of-found-module] [modules])
> +#
> +# there is pkg_search_module(), but it does not clarify
> +# which module was found.
> +#
> +# this function does not set xxx_CFLAGS xxx_LIBS etc.
> +#
> +function(PKG_SEARCH_AVAILABLE_MODULE _found_pkg pkg_list)
> + set(_PKG_FOUND FALSE)
> + foreach(_pkg IN LISTS pkg_list)
> + pkg_check_modules(_PKG "${_pkg}")
> + if (_PKG_FOUND)
> + set("${_found_pkg}_FOUND" TRUE PARENT_SCOPE)
> + set("${_found_pkg}_MODULE_NAME" "${_pkg}" PARENT_SCOPE)
> + return()
> + endif()
> + endforeach(_pkg)
> +endfunction(PKG_SEARCH_AVAILABLE_MODULE)
above is the function to find the first available module
from a list. pkg_check_modules() or pkg_search_module()
can do similar, but we have to write same list twice
(please find my example in
https://cmake.org/pipermail/cmake/2018-March/067292.html ).
to reduce the maintainability, I defined this function.
> +#
> +# MAKE_LDFLAGS_FROM_LIBPATH([var-ldflags+libs] [libpath])
> +#
> +function(MAKE_LDFLAGS_FROM_LIBPATHS _ldflags _libpaths)
> + foreach(_libpath IN LISTS _libpaths)
> + get_filename_component(_libdir "${_libpath}" DIRECTORY)
> + get_filename_component(_lib "${_libpath}" NAME)
> +
> + string(REGEX REPLACE "(\\${CMAKE_STATIC_LIBRARY_SUFFIX}|\\${CMAKE_SHARED_LIBRARY_SUFFIX})$" "" _lib "${_lib}")
> + string(REGEX REPLACE "^lib" "" _lib "${_lib}")
> +
> + set(__ldflags "${__ldflags} ${CMAKE_LIBRARY_PATH_FLAG}${_libdir} ${CMAKE_LINK_LIBRARY_FLAG}${_lib}")
> + endforeach(_libpath)
> + set("${_ldflags}" "${__ldflags}" PARENT_SCOPE)
> +endfunction(MAKE_LDFLAGS_FROM_LIBPATH)
above is the function to divide full pathname of the library
into its dirname and its basename, and constructs LDFLAGS
and LIBS style string.
> @@ -188,6 +225,7 @@ if(ENABLE_CPP)
> endif()
> if(ENABLE_ZLIB)
> find_package(ZLIB)
> + pkg_check_modules(PC_ZLIB zlib)
> set(ENABLE_ZLIB ${ZLIB_FOUND})
> endif()
> if(ENABLE_ZLIB_UNCOMPRESS AND NOT ENABLE_ZLIB)
FindZLIB.cmake does not check the availability of
pkg-config module "zlib", so here I check. not to
bother current building setting, the prefix is set
to PC_ZLIB.
> @@ -197,6 +235,7 @@ endif()
> set(WITH_OPENJPEG FALSE)
> if(ENABLE_LIBOPENJPEG STREQUAL "openjpeg2")
> find_package(LIBOPENJPEG2)
> + pkg_check_modules(PC_LIBOPENJP2 libopenjp2)
> set(WITH_OPENJPEG ${LIBOPENJPEG2_FOUND})
> if(NOT LIBOPENJPEG2_FOUND)
> message(FATAL_ERROR "Install libopenjpeg2 before trying to build poppler. You can also decide to use the internal unmaintained JPX decoder or none at all.")
If LIBOPENJPEG2_LIBRARIES and LIBOPENJPEG2_INCLUDE_DIR
are set manually, FindLIBOPENJP2.cmake sets
LIBOPENJPEG2_FOUND true without check the existence
of pkg-config module for libopenjpeg2 (so we cannot
know pkg-config moule exists or not from LIBOPENJP2_FOUND).
Thus, here I inserted a variable just checking module
availability, PC_LIBOPENJP2.
> @@ -221,6 +260,7 @@ endif()
> if(ENABLE_LIBCURL)
> find_package(CURL)
> if(CURL_FOUND)
> + pkg_check_modules(PC_LIBCURL libcurl)
> include_directories(${CURL_INCLUDE_DIR})
> set(POPPLER_HAS_CURL_SUPPORT ON)
> else()
FindCURL.cmake does not use pkg-config, so we check
the module availability explicitly (as zlib case).
> @@ -262,13 +302,16 @@ if (NSS3_FOUND)
> endif()
> if(JPEG_FOUND)
> include_directories(${JPEG_INCLUDE_DIR})
> + PKG_SEARCH_AVAILABLE_MODULE(PC_LIBJPEG "libjpeg;libjpeg8-turbo;libjpeg8;libjpeg9;libjpeg62")
> endif()
FindJPEG.cmake does not use pkg-config, so we check
the module availability explicitly (as zlib case).
> if(PNG_FOUND)
> include_directories(${PNG_INCLUDE_DIR})
> + PKG_SEARCH_AVAILABLE_MODULE(PC_LIBPNG "libpng;libpng16;libpng12")
> set(ENABLE_LIBPNG ON)
> endif()
FindPNG.cmake does not use pkg-config, so...
> if(TIFF_FOUND)
> include_directories(${TIFF_INCLUDE_DIR})
> + PKG_SEARCH_AVAILABLE_MODULE(PC_LIBTIFF "libtiff;libtiff-4")
> set(ENABLE_LIBTIFF ON)
> endif()
FindTIFF.cmake does not use pkg-config, so...
> @@ -676,12 +719,175 @@ if(PKG_CONFIG_EXECUTABLE)
> exec_program(${PKG_CONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _output_VAR)
> macro_ensure_version("0.18" "${_output_VAR}" PKG_CONFIG_VERSION_0_18)
> endif()
> -if(PKG_CONFIG_VERSION_0_18)
> - set(PC_REQUIRES "")
> - set(PC_REQUIRES_PRIVATE "Requires.private: poppler = ${POPPLER_VERSION}")
> -else()
> - set(PC_REQUIRES "poppler = ${POPPLER_VERSION}")
> - set(PC_REQUIRES_PRIVATE "")
The Requires & Libs are constructed from now, so
the pkg-config version checks would be postponed.
> +
> +# if archive library of poppler is being built, it cannot hold
> +# the dependency. collect dependencies managed by pkg-config,
> +# write to Requires. other dependencies (e.g. no appropriate
> +# pkg-config module is found), write to Libs.
> +
> +set(cmake_pc_requires "")
> +set(cmake_pc_libs "")
> +
The empty skeletons are prepared.
> +#
> +# dependencies checked by pkg-config only
> +#
> +# FindNSS3 just invokes pkg-config, returns cmake list of --libs
> +if (NSS3_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} nss")
> +endif()
NSS is just checked by pkg-config, so just pass the known
name to additional Requires.
> +# FindLIBOPENJPEG2 just invokes pkg-config, if LIBOPENJPEG2_xxx are not given.
> +if (LIBOPENJPEG2_FOUND)
> + if (PC_LIBOPENJP2_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} libopenjp2")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_libopenjpeg2_ldflags "${LIBOPENJPEG2_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_libopenjpeg2_ldflags}")
> + endif()
> +endif()
Even if OpenJPEG2 pkg-config module is not found, manual setting
of LIBOPENJPEG2_LIBRARIES can help. For such case (non-pkg-config
OpenJPEG2 is found), LDFLAGS + LIBS are constructed by
LIBOPENJPEG2_LIBRARIES.
> +#
> +# dependencies checked by pkg-config but sometimes different
> +#
> +
> +# FindFontconfig tries pkg-config too, but constructs library pathname
> +# even if PC_FONTCONFIG_FOUND is false, FONTCONFIG_FOUND could be true.
> +#
> +if (FONTCONFIG_FOUND)
> + if (PC_FONTCONFIG_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} fontconfig")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_fontconfig_ldflags "${FONTCONFIG_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_fontconfig_ldflags}")
> + endif()
> +endif()
As OpenJPEG2, even if pkg-config cannot find fontconfig,
FONTCONFIG_LIBRARIES can help. Do same as OpenJPEG2 case.
> +# FindLCMS2 tries pkg-config too, but constructs library pathname
> +# even if PC_LCMS2_FOUND is false, LCMS2_FOUND could be true.
> +#
> +if (LCMS2_FOUND)
> + if (PC_LCMS2_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} lcms2")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_lcms2_ldflags "${LCMS2_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_lcms2_ldflags}")
> + endif()
> +endif()
For lcms2, even if pkg-config cannot find it, and no
LCMS2_LIBRARIES is specified, FindLCMS2 search the library
by itself. So, if pkg-config cannot find it, some tweaks are
expected.
> +#
> +# dependencies checked without pkg-config
> +#
> +
> +# find_package(ZLIB) constructs library pathname
> +if (ENABLE_ZLIB)
> + if (PC_ZLIB_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} zlib")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_zlib_ldflags "${ZLIB_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_zlib_ldflags}")
> + endif()
> +endif()
FindZLIB.cmake does not use pkg-config at all. Do as
previous cases.
> +# FindCURL does not use pkg-config, constructs library pathname
> +if (CURL_FOUND)
> + if (PC_LIBCURL_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} libcurl")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_curl_ldflags "${CURL_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_curl_ldflags}")
> + endif()
> +endif()
FindCURL.cmake does not use pkg-config at all. Do as
previous cases.
> +# FindJPEG does not use pkg-config, constructs library pathname
> +if (WITH_JPEG)
> + if (PC_LIBJPEG_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} ${PC_LIBJPEG_MODULE_NAME}")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_jpeg_ldflags "${JPEG_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_jpeg_ldflags}")
> + endif()
> +endif()
FindJPEG.cmake does not use pkg-config at all. Do as
previous cases.
> +# FindTIFF does not use pkg-config, constructs library pathname
> +if (WITH_TIFF)
> + if (PC_LIBTIFF_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} ${PC_LIBTIFF_MODULE_NAME}")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_tiff_ldflags "${TIFF_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_tiff_ldflags}")
> + endif()
> +endif()
FindJPEG.cmake does not use pkg-config at all. Do as
previous cases.
> +# FindPNG does not use pkg-config, constructs library pathname
> +if (WITH_PNG)
> + if (PC_LIBPNG_FOUND)
> + set(cmake_pc_requires "${cmake_pc_requires} ${PC_LIBPNG_MODULE_NAME}")
> + else()
> + MAKE_LDFLAGS_FROM_LIBPATHS(_png_ldflags "${PNG_LIBRARIES}")
> + set(cmake_pc_libs "${cmake_pc_libs} ${_png_ldflags}")
> + endif()
> +endif()
FindJPEG.cmake does not use pkg-config at all. Do as
previous cases.
> +# extra dependencies without no pc files are provided
> +if (ICONV_FOUND)
> + # remove uneeded -lc from ICONV_LIBRARIES (the pathname of libiconv, not -liconv)
> + set(_iconv_libraries "${ICONV_LIBRARIES}")
> + string(REGEX REPLACE "^.*/[Ll][Ii][Bb][Cc]\\${CMAKE_SHARED_LIBRARY_SUFFIX}\$" "" _iconv_libraries "${_iconv_libraries}")
> + string(REGEX REPLACE "^.*/[Ll][Ii][Bb][Cc]\\${CMAKE_STATIC_LIBRARY_SUFFIX}\$" "" _iconv_libraries "${_iconv_libraries}")
> + MAKE_LDFLAGS_FROM_LIBPATHS(_iconv_ldflags "${_iconv_libraries}")
> + set(cmake_pc_cpp_libs "${cmake_pc_cpp_libs} ${_iconv_ldflags}")
> +endif()
In the case that libc itself has built-in iconv(),
like GNU libc, ${ICONV_LIBRARIES} could be "/usr/lib/libc.so".
It is not needed.
> +if (CMAKE_USE_PTHREADS_INIT)
> + string(FIND "/libpthread${CMAKE_SHARED_LIBRARY_SUFFIX}" "${poppler_LIBS}" _pos)
> + if (_pos LESS 0)
> + string(FIND "/libpthread${CMAKE_STATIC_LIBRARY_SUFFIX}" "${poppler_LIBS}" _pos)
> + endif()
> +
> + if (_pos LESS 0)
> + set(cmake_pc_libs "${cmake_pc_libs} -pthread")
> + else()
> + set(cmake_pc_libs "${cmake_pc_libs} -lpthread")
> + endif()
> +endif()
If poppler_LIBS includes the full pathnames of libpthread,
convert it to LDFLAGS + LIBS styles.
> +string(REPLACE " -lc " "" cmake_pc_libs " ${cmake_pc_libs} ")
> +string(REPLACE " -lc " "" cmake_pc_cpp_libs " ${cmake_pc_cpp_libs} ")
Remove unexpected linker flags.
> +string(STRIP "${cmake_pc_libs}" cmake_pc_libs)
> +string(STRIP "${cmake_pc_cpp_libs}" cmake_pc_cpp_libs)
Remove beginning & following spaces.
> +string(REPLACE ";" " " cmake_pc_requires "${cmake_pc_requires}")
> +string(REPLACE ";" " " cmake_pc_libs "${cmake_pc_libs}")
> +string(REPLACE ";" " " cmake_pc_cpp_libs "${cmake_pc_cpp_libs}")
If there is special linker flags, it could be separated
by ";" to pack as list in cmake.
> +#
> +# to guarantee "pkg-config --libs poppler" always valid,
> +# we use Requires + Libs instead of Requires.private,
> +# if archive library is being built.
> +#
> +if(WIN32)
> +
> +elseif(BUILD_SHARED_LIBS AND PKG_CONFIG_VERSION_0_18)
> + #
> + # too old pkg-config-0.18 cannot hold private values
> + #
> + set(POPPLER_REQUIRES_PRIVATE "Requires.private: ${cmake_pc_requires}")
> + set(POPPLER_LIBS_PRIVATE "Libs.private: ${cmake_pc_libs}")
> + set(POPPLER_CPP_REQUIRES_PRIVATE "Requires.private: poppler = ${POPPLER_VERSION} ${cmake_pc_cpp_requires}")
> + set(POPPLER_CPP_LIBS_PRIVATE "Libs.private: ${cmake_pc_cpp_libs}")
> + set(POPPLER_GLIB_REQUIRES_PRIVATE "Requires.private: poppler = ${POPPLER_VERSION}")
> + set(POPPLER_QT5_REQUIRES_PRIVATE "Requires.private: poppler = ${POPPLER_VERSION}")
> +
> +elseif(NOT(BUILD_SHARED_LIBS))
> + set(POPPLER_REQUIRES "Requires: ${cmake_pc_requires}")
> + set(POPPLER_LIBS_EXTRA "${cmake_pc_libs}")
> +
> + set(POPPLER_CPP_REQUIRES_EXTRA "poppler = ${POPPLER_VERSION} ${cmake_pc_cpp_requires}")
> + set(POPPLER_CPP_LIBS_EXTRA "${cmake_pc_cpp_libs}")
> + set(POPPLER_GLIB_REQUIRES_EXTRA "poppler = ${POPPLER_VERSION}")
> + set(POPPLER_QT5_REQUIRES_EXTRA "poppler = ${POPPLER_VERSION}")
> +
> endif()
Finally expand to pkg-config files.
> poppler_create_install_pkgconfig(poppler.pc ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
> diff --git a/poppler-cpp.pc.cmake b/poppler-cpp.pc.cmake
> index 3eb68b3..e91ffd8 100644
> --- a/poppler-cpp.pc.cmake
> +++ b/poppler-cpp.pc.cmake
> @@ -5,8 +5,9 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
> Name: poppler-cpp
> Description: cpp backend for Poppler PDF rendering library
> Version: @POPPLER_VERSION@
> -Requires: @PC_REQUIRES@
> - at PC_REQUIRES_PRIVATE@
> +Requires: @POPPLER_CPP_REQUIRES_EXTRA@
> + at POPPLER_CPP_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-cpp
> Cflags: -I${includedir}/poppler/cpp
> +Libs: -L${libdir} -lpoppler-cpp @POPPLER_CPP_LIBS_EXTRA@
> + at POPPLER_CPP_LIBS_PRIVATE@
> diff --git a/poppler-glib.pc.cmake b/poppler-glib.pc.cmake
> index ac24819..e3040fc 100644
> --- a/poppler-glib.pc.cmake
> +++ b/poppler-glib.pc.cmake
> @@ -5,8 +5,9 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
> Name: poppler-glib
> Description: GLib wrapper for poppler
> Version: @POPPLER_VERSION@
> -Requires: glib-2.0 >= @GLIB_REQUIRED@ gobject-2.0 >= @GLIB_REQUIRED@ cairo >= @CAIRO_VERSION@
> - at PC_REQUIRES_PRIVATE@
> +Requires: glib-2.0 >= @GLIB_REQUIRED@ gobject-2.0 >= @GLIB_REQUIRED@ cairo >= @CAIRO_VERSION@ @POPPLER_GLIB_REQUIRES_EXTRA@
> + at POPPLER_GLIB_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-glib
> Cflags: -I${includedir}/poppler/glib
> +Libs: -L${libdir} -lpoppler-glib @POPPLER_GLIB_LIBS_EXTRA@
> + at POPPLER_GLIB_LIBS_PRIVATE@
> diff --git a/poppler-qt5.pc.cmake b/poppler-qt5.pc.cmake
> index 9463689..1ac5809 100644
> --- a/poppler-qt5.pc.cmake
> +++ b/poppler-qt5.pc.cmake
> @@ -5,8 +5,9 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
> Name: poppler-qt5
> Description: Qt5 bindings for poppler
> Version: @POPPLER_VERSION@
> -Requires: @PC_REQUIRES@
> - at PC_REQUIRES_PRIVATE@
> +Requires: @POPPLER_QT5_REQUIRES_EXTRA@
> + at POPPLER_QT5_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-qt5
> Cflags: -I${includedir}/poppler/qt5
> +Libs: -L${libdir} -lpoppler-qt5 @POPPLER_QT5_LIBS_EXTRA@
> + at POPPLER_QT5_LIBS_PRIVATE@
> diff --git a/poppler.pc.cmake b/poppler.pc.cmake
> index 00b7348..ab3aeee 100644
> --- a/poppler.pc.cmake
> +++ b/poppler.pc.cmake
> @@ -5,6 +5,9 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
> Name: poppler
> Description: PDF rendering library
> Version: @POPPLER_VERSION@
> + at POPPLER_REQUIRES@
> + at POPPLER_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler
> Cflags: -I${includedir}/poppler
> +Libs: -L${libdir} -lpoppler @POPPLER_LIBS_EXTRA@
> + at POPPLER_LIBS_PRIVATE@
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fix-pc-for-static-build_20180329-1650.diff
Type: text/x-patch
Size: 15456 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/poppler/attachments/20180329/d664a6d0/attachment-0001.bin>
More information about the poppler
mailing list