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

Bill Somerville bill at classdesign.com
Mon Mar 31 12:25:02 EDT 2014


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