[CMake] find_package with static library that uses pkg-config not working

Aurelien Richez aurelien.richez at inria.fr
Mon Mar 31 13:46:36 EDT 2014


Hello again

I'm not familiar with libFindMacros.cmake but it seems that it just handles 
libraries and headers, not compilation/linker flags. However 
"libfind_pkg_check_modules (hamlib_PKGCONF hamlib)" should generate several 
variables (for the shared library and for the static library), including 
"hamlib_PKGCONF_STATIC_LIBRARY_DIRS". 

so you can add in Findhamlib.cmake: 

find_library (hamlib_STATIC_LIBRARY 
NAMES libhamlib.a hamlib-2 
PATHS ${hamlib_PKGCONF_STATIC_LIBRARY_DIRS} 
) 

and at the end of the file : 

set (hamlib_STATIC_PROCESS_LIBS hamlib_STATIC_LIBRARY) 
libfind_process (hamlib_STATIC) 

It should find the static library. 

libfind_pkg_check_modules should also generate "hamlib_PKGCONF_STATIC_LDFLAGS" 
so you can try in Findhamlib.cmake : 

set(hamlib_STATIC_LDFLAGS ${hamlib_PKGCONF_STATIC_LDFLAGS}). 

After doing this, I think you should have hamlib_STATIC_FOUND, hamlib_STATIC_LDFLAGS and 
hamlib_STATIC_LIBRARIES set.

Regards

Aurélien 

----- Mail original ----- 

> De: "Bill Somerville" <bill at classdesign.com>
> À: "Aurelien Richez" <aurelien.richez at inria.fr>
> Cc: cmake at cmake.org
> Envoyé: Lundi 31 Mars 2014 18:25:02
> Objet: Re: [CMake] find_package with static library that uses pkg-config not
> working

> On 31/03/2014 10:18, Aurelien Richez wrote:
> > Hi,
> Hi Aurélien,

> I'm not sure I fully understand your suggestion. The Findxxxx.cmake is
> written by me and looks like this.

> Findhamlib.cmake:
> +++++++++++++++++++++++++++++++++++
> # - Try to find hamlib
> # Once done, this will define:
> #
> # hamlib_FOUND - system has Hamlib-2
> # hamlib_INCLUDE_DIRS - the Hamlib-2 include directories
> # hamlib_LIBRARIES - link these to use Hamlib-2

> include (LibFindMacros)

> # Use pkg-config to get hints about paths
> libfind_pkg_check_modules (hamlib_PKGCONF hamlib)

> # Include dirs
> find_path (hamlib_INCLUDE_DIR
> NAMES hamlib/rig.h
> PATHS ${hamlib_PKGCONF_INCLUDE_DIRS}
> )

> # The library
> find_library (hamlib_LIBRARY
> NAMES hamlib hamlib-2
> PATHS ${hamlib_PKGCONF_LIBRARY_DIRS}
> )

> # Set the include dir variables and the libraries and let
> libfind_process do the rest
> set (hamlib_PROCESS_INCLUDES hamlib_INCLUDE_DIR)
> set (hamlib_PROCESS_LIBS hamlib_LIBRARY)
> libfind_process (hamlib)
> --------------------------------------------------------------------

> it uses LibFincMacros.cmake which looks like this.

> LibFindMacros.cmake:
> ++++++++++++++++++++++++++++++++++++++++++++
> # Version 1.0 (2013-04-12)
> # Public Domain, originally written by Lasse Kärkkäinen <tronic at zi.fi>
> # Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries

> # If you improve the script, please modify the forementioned wiki page
> because
> # I no longer maintain my scripts (hosted as static files at zi.fi).
> Feel free
> # to remove this entire header if you use real version control instead.

> # Changelog:
> # 2013-04-12 Added version number (1.0) and this header, no other changes
> # 2009-10-08 Originally published

> # Works the same as find_package, but forwards the "REQUIRED" and
> "QUIET" arguments
> # used for the current package. For this to work, the first parameter
> must be the
> # prefix of the current package, then the prefix of the new package etc,
> which are
> # passed to find_package.
> macro (libfind_package PREFIX)
> set (LIBFIND_PACKAGE_ARGS ${ARGN})
> if (${PREFIX}_FIND_QUIETLY)
> set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
> endif (${PREFIX}_FIND_QUIETLY)
> if (${PREFIX}_FIND_REQUIRED)
> set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
> endif (${PREFIX}_FIND_REQUIRED)
> find_package(${LIBFIND_PACKAGE_ARGS})
> endmacro (libfind_package)

> # CMake developers made the UsePkgConfig system deprecated in the same
> release (2.6)
> # where they added pkg_check_modules. Consequently I need to support
> both in my scripts
> # to avoid those deprecated warnings. Here's a helper that does just that.
> # Works identically to pkg_check_modules, except that no checks are
> needed prior to use.
> macro (libfind_pkg_check_modules PREFIX PKGNAME)
> if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
> include(UsePkgConfig)
> pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS
> ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
> else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
> find_package(PkgConfig)
> if (PKG_CONFIG_FOUND)
> pkg_check_modules(${PREFIX} ${PKGNAME})
> endif (PKG_CONFIG_FOUND)
> endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
> endmacro (libfind_pkg_check_modules)

> # Do the final processing once the paths have been detected.
> # If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set
> to contain
> # all the variables, each of which contain one include directory.
> # Ditto for ${PREFIX}_PROCESS_LIBS and library files.
> # Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
> # Also handles errors in case library detection was required, etc.
> macro (libfind_process PREFIX)
> # Skip processing if already processed during this run
> if (NOT ${PREFIX}_FOUND)
> # Start with the assumption that the library was found
> set (${PREFIX}_FOUND TRUE)

> # Process all includes and set _FOUND to false if any are missing
> foreach (i ${${PREFIX}_PROCESS_INCLUDES})
> if (${i})
> set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
> mark_as_advanced(${i})
> else (${i})
> set (${PREFIX}_FOUND FALSE)
> endif (${i})
> endforeach (i)

> # Process all libraries and set _FOUND to false if any are missing
> foreach (i ${${PREFIX}_PROCESS_LIBS})
> if (${i})
> set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
> mark_as_advanced(${i})
> else (${i})
> set (${PREFIX}_FOUND FALSE)
> endif (${i})
> endforeach (i)

> # Print message and/or exit on fatal error
> if (${PREFIX}_FOUND)
> if (NOT ${PREFIX}_FIND_QUIETLY)
> message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
> endif (NOT ${PREFIX}_FIND_QUIETLY)
> else (${PREFIX}_FOUND)
> if (${PREFIX}_FIND_REQUIRED)
> foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
> message("${i}=${${i}}")
> endforeach (i)
> message (FATAL_ERROR "Required library ${PREFIX} NOT
> FOUND.\nInstall the library (dev version) and try again. If the library
> is already installed, use ccmake to set the missing variables manually.")
> endif (${PREFIX}_FIND_REQUIRED)
> endif (${PREFIX}_FOUND)
> endif (NOT ${PREFIX}_FOUND)
> endmacro (libfind_process)

> macro(libfind_library PREFIX basename)
> set(TMP "")
> if(MSVC80)
> set(TMP -vc80)
> endif(MSVC80)
> if(MSVC90)
> set(TMP -vc90)
> endif(MSVC90)
> set(${PREFIX}_LIBNAMES ${basename}${TMP})
> if(${ARGC} GREATER 2)
> set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
> string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
> set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
> endif(${ARGC} GREATER 2)
> find_library(${PREFIX}_LIBRARY
> NAMES ${${PREFIX}_LIBNAMES}
> PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
> )
> endmacro(libfind_library)

> ------------------------------------------------------

> I don't see anything here that resembles static linking requirements.
> >
> >
> > pkg_check_modules used by find_package should generate MYLIBPREFIX_CFLAGS
> > and MYLIBPREFIX_STATIC_CFLAGS according to the documentation.
> >
> > You can try HAMLIB_STATIC_LIBRARIES. However, the finders often use
> > "PC_MYLIB" as prefix using pkg_check_modules. So may be
> > PC_HAMLIB_STATIC_LIBRARIES will work (or you can check out your
> > Findhamlib.cmake to find which prefix is used by pkg_check_modules). I
> > don't know if it is a good idea to directly use package config defined
> > variables in a cmake file so if you can edit your Findhamlib.cmake, may be
> > you should set HAMLIB_STATIC_{LIBRARIES,CFLAGS,...} to their corresponding
> > PC_HAMLIB_STATIC_{...} (I am no expert about this, so I don't really know
> > which are the good practices to write a finder).
> Is there some way to get the UsePkgConfig.cmake module to deliver static
> linking requirements. I assume it needs to get both dynamic and static
> linking requirements as I believe at the time it runs the decision as to
> which type of link is required has not been made.
> >
> > Hope this helps.
> >
> > Aurélien
> Regards
> Bill Somerville.
> >
> > ----- Mail original -----
> >> De: "Bill Somerville" <bill at classdesign.com>
> >> À: cmake at cmake.org
> >> Envoyé: Dimanche 30 Mars 2014 12:45:32
> >> Objet: [CMake] find_package with static library that uses pkg-config not
> >> working
> >>
> >> Hi,
> >>
> >> I am using find_package to configure a library that uses pkg-config.
> >> When I configure and build a static only version of the library the link
> >> commands generated for my project are wrong.
> >>
> >> The problem boils down to the fact that for static link of a library
> >> pkg-config needs to be called with the '--static' option to extract the
> >> correct compile switches and link libraries.
> >>
> >> In my case the library libdl needs to be linked because the external
> >> library uses run time library loading. For example:
> >>
> >> $ pkg-config --cflags --libs hamlib
> >> -pthread -I/home/bill/test-install/hamlib/include
> >> -L/home/bill/test-install/hamlib/lib -lhamlib
> >>
> >> $ pkg-config --cflags --libs --static hamlib
> >> -pthread -I/home/bill/test-install/hamlib/include
> >> -L/home/bill/test-install/hamlib/lib -lhamlib -lm -ldl -lusb
> >>
> >> So how do I get find_package to use the correct pkg-config invocation
> >> when there is no shared library version of the external library or if I
> >> want to force static linking of this external library?
> >>
> >> TIA
> >> Bill Somerville.
> >> --
> >>
> >> Powered by www.kitware.com
> >>
> >> Please keep messages on-topic and check the CMake FAQ at:
> >> http://www.cmake.org/Wiki/CMake_FAQ
> >>
> >> Kitware offers various services to support the CMake community. For more
> >> information on each offering, please visit:
> >>
> >> CMake Support: http://cmake.org/cmake/help/support.html
> >> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> >> CMake Training Courses: http://cmake.org/cmake/help/training.html
> >>
> >> Visit other Kitware open-source projects at
> >> http://www.kitware.com/opensource/opensource.html
> >>
> >> Follow this link to subscribe/unsubscribe:
> >> http://www.cmake.org/mailman/listinfo/cmake
> >>


More information about the CMake mailing list