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@
> -@PC_REQUIRES_PRIVATE@
> +Requires: @POPPLER_CPP_REQUIRES_EXTRA@
> +@POPPLER_CPP_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-cpp
> Cflags: -I${includedir}/poppler/cpp
> +Libs: -L${libdir} -lpoppler-cpp @POPPLER_CPP_LIBS_EXTRA@
> +@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@
> -@PC_REQUIRES_PRIVATE@
> +Requires: glib-2.0 >= @GLIB_REQUIRED@ gobject-2.0 >= @GLIB_REQUIRED@ cairo
> >= @CAIRO_VERSION@ @POPPLER_GLIB_REQUIRES_EXTRA@
> +@POPPLER_GLIB_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-glib
> Cflags: -I${includedir}/poppler/glib
> +Libs: -L${libdir} -lpoppler-glib @POPPLER_GLIB_LIBS_EXTRA@
> +@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@
> -@PC_REQUIRES_PRIVATE@
> +Requires: @POPPLER_QT5_REQUIRES_EXTRA@
> +@POPPLER_QT5_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler-qt5
> Cflags: -I${includedir}/poppler/qt5
> +Libs: -L${libdir} -lpoppler-qt5 @POPPLER_QT5_LIBS_EXTRA@
> +@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@
> +@POPPLER_REQUIRES@
> +@POPPLER_REQUIRES_PRIVATE@
>
> -Libs: -L${libdir} -lpoppler
> Cflags: -I${includedir}/poppler
> +Libs: -L${libdir} -lpoppler @POPPLER_LIBS_EXTRA@
> +@POPPLER_LIBS_PRIVATE@
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..9a9e5a7
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,82 @@
+language: cpp
+
+script:
+ - pkg-config --list-all | sort
+ - mkdir build-shared && cd build-shared
+ - cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_GOBJECT_INTROSPECTION=OFF -DCMAKE_INSTALL_PREFIX=`pwd`/root ..
+ - cat poppler.pc
+ - cat poppler-cpp.pc
+ - test -r poppler-glib.pc && cat poppler-glib.pc || echo not found
+ - test -r poppler-qt5.pc && cat poppler-qt5.pc || echo not found
+ - cd ..
+ - mkdir build-static && cd build-static
+ - cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_GOBJECT_INTROSPECTION=OFF -DCMAKE_INSTALL_PREFIX=`pwd`/root ..
+ - cat poppler.pc
+ - cat poppler-cpp.pc
+ - test -r poppler-glib.pc && cat poppler-glib.pc || echo not found
+ - test -r poppler-qt5.pc && cat poppler-qt5.pc || echo not found
+ - env PKG_CONFIG_PATH=`pwd` pkg-config --libs poppler-cpp
+ - make install
+ - export PKG_CONFIG_PATH=`pwd`/root/lib/pkgconfig/
+
+matrix:
+ include:
+ - dist: trusty
+ compiler: gcc
+ before_install:
+ - for p in `dpkg -l | fgrep jpeg | fgrep dev | awk '{print $2}'` ; do echo "== " ${p} ; dpkg -L ${p} ; done
+ after_script:
+ - git clone git://github.com/jeroen/popplertest
+ - cd popplertest
+ - g++ -v -Wl,-v -std=c++11 encoding.cpp -o encoding $(pkg-config --cflags --libs poppler-cpp)
+ - ./encoding ./hello.pdf | cat -A
+
+# - dist: trusty
+# compiler: clang
+ - os: osx
+ osx_image: xcode9.2
+ before_install:
+ - ( brew install gettext && brew link --force gettext ) || true
+ - ( brew install libffi && brew link --force libffi ) || true
+ - ( brew install cmake && brew link --force cmake ) || true
+ - ( brew install pcre && brew link --force pcre ) || true
+# - ( brew install glib && brew link --force glib ) || true
+ - ( brew install freetype && brew link --force freetype ) || true
+ - ( brew install fontconfig && brew link --force fontconfig ) || true
+ - ( brew install pixman && brew link --force pixman ) || true
+ - ( brew install cairo && brew link --force cairo ) || true
+ - ( brew install jpeg && brew link --force jpeg ) || true
+ - ( brew install openjpeg && brew link --force openjpeg ) || true
+ - ( brew install libtiff && brew link --force libtiff ) || true
+ - ( brew install little-cms2 && brew link --force little-cms2 ) || true
+# - ( brew install gtk+ && brew link --force gtk+ ) || true
+ - brew remove gobject-introspection || true
+ after_script:
+ - git clone git://github.com/jeroen/popplertest
+ - cd popplertest
+ - g++ -v -Wl,-v -std=c++11 encoding.cpp -o encoding $(pkg-config --cflags --libs poppler-cpp)
+ - ./encoding ./hello.pdf | cat -e
+
+# - os: osx
+# osx_image: xcode8.3
+# before_install:
+# - brew install gettext
+# - brew install poppler --build-from-source
+# - brew remove poppler
+addons:
+ apt:
+ sources:
+ - sourceline: 'ppa:ricotz/testing'
+ - sourceline: 'ppa:aacid/openjp2trusty'
+ packages:
+ - cmake
+# - libglib2.0-dev
+# - libgtk2.0-dev
+ - libfontconfig1-dev
+ - libcairo2-dev
+ - libjpeg-dev
+ - libpng-dev
+ - libtiff-dev
+ - liblcms2-dev
+ - libfreetype6-dev
+ - libopenjp2-7-dev
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)
+
+#
+# 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)
+
if (WIN32)
message("-- Using win32 threads")
else()
@@ -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)
@@ -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.")
@@ -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()
@@ -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()
if(PNG_FOUND)
include_directories(${PNG_INCLUDE_DIR})
+ PKG_SEARCH_AVAILABLE_MODULE(PC_LIBPNG "libpng;libpng16;libpng12")
set(ENABLE_LIBPNG ON)
endif()
if(TIFF_FOUND)
include_directories(${TIFF_INCLUDE_DIR})
+ PKG_SEARCH_AVAILABLE_MODULE(PC_LIBTIFF "libtiff;libtiff-4")
set(ENABLE_LIBTIFF ON)
endif()
if(LIBOPENJPEG2_FOUND)
@@ -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 "")
+
+# 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 "")
+
+#
+# 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()
+
+# 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()
+
+#
+# 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()
+
+# 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()
+
+#
+# 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()
+
+# 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()
+
+# 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()
+
+# 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()
+
+# 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()
+
+# 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()
+
+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()
+
+string(REPLACE " -lc " "" cmake_pc_libs " ${cmake_pc_libs} ")
+string(REPLACE " -lc " "" cmake_pc_cpp_libs " ${cmake_pc_cpp_libs} ")
+string(STRIP "${cmake_pc_libs}" cmake_pc_libs)
+string(STRIP "${cmake_pc_cpp_libs}" cmake_pc_cpp_libs)
+
+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}")
+
+#
+# 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()
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@
-@PC_REQUIRES_PRIVATE@
+Requires: @POPPLER_CPP_REQUIRES_EXTRA@
+@POPPLER_CPP_REQUIRES_PRIVATE@
-Libs: -L${libdir} -lpoppler-cpp
Cflags: -I${includedir}/poppler/cpp
+Libs: -L${libdir} -lpoppler-cpp @POPPLER_CPP_LIBS_EXTRA@
+@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@
-@PC_REQUIRES_PRIVATE@
+Requires: glib-2.0 >= @GLIB_REQUIRED@ gobject-2.0 >= @GLIB_REQUIRED@ cairo >= @CAIRO_VERSION@ @POPPLER_GLIB_REQUIRES_EXTRA@
+@POPPLER_GLIB_REQUIRES_PRIVATE@
-Libs: -L${libdir} -lpoppler-glib
Cflags: -I${includedir}/poppler/glib
+Libs: -L${libdir} -lpoppler-glib @POPPLER_GLIB_LIBS_EXTRA@
+@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@
-@PC_REQUIRES_PRIVATE@
+Requires: @POPPLER_QT5_REQUIRES_EXTRA@
+@POPPLER_QT5_REQUIRES_PRIVATE@
-Libs: -L${libdir} -lpoppler-qt5
Cflags: -I${includedir}/poppler/qt5
+Libs: -L${libdir} -lpoppler-qt5 @POPPLER_QT5_LIBS_EXTRA@
+@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@
+@POPPLER_REQUIRES@
+@POPPLER_REQUIRES_PRIVATE@
-Libs: -L${libdir} -lpoppler
Cflags: -I${includedir}/poppler
+Libs: -L${libdir} -lpoppler @POPPLER_LIBS_EXTRA@
+@POPPLER_LIBS_PRIVATE@
_______________________________________________
poppler mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/poppler