Supply *.pc file for pkg-config - pkg-config

Hi I got a problem with my newly installed Fedora linux distribution. pkg-config is supposed to provide linker flags, something like pkg-config --cflags libboost-dev. But pkg-config cannot find most of the library packages. pkg-config --list-all shows that it can find only a few packages.
I searched online and learned that pkg-config finds packages by searching in the pre-defined paths for the *.pc files. However for most packages (both pre-installed and user-installed), there are no such .pc file. So the *.pc file is not generated everytime when a package installs.
1, How can I provide a .pc file for each of the packages that has already been installed?
2, How can I make sure that for each time a new package is installed, the .pc file is provided?

The Fedora packaging guidelines give information about the way in which packages should be created, and the files they should contain.
The section about -devel packages is particularly relevant.
To highlight some parts
There are some types of files which almost always belong in a -devel package:
Header files (foo.h), usually found in /usr/include
Static library files when the package does not provide any matching shared library files. See Packaging:Guidelines#Packaging_Static_Libraries for more information about this scenario.
Unversioned shared system library files, when a matching versioned shared system library file is also present.
In the next section, regarding Pkgconfig Files, the page informs the reader that
The placement of pkgconfig(.pc) files depends on their usecase. Since they are almost always used for development purposes, they should be placed in a -devel package.
A reasonable exception is when the main package itself is a development tool not installed in a user runtime, e.g. gcc or gdb.
As a result, in order to get either header files to #include, or .pc files to tell you compiler flags, you will need the xyz-devel package, where xyz is the name of the standard package.
A useful website to find the appropriate names of packages to install, if you can't/don't want to guess them, is the Fedora Packages search page.

Related

Finding vcpkg packages that don't have `find_package` documentation

When you install many packages through vcpkg (such as vcpkg install cairo), at the end of this process, you are told what find_package and target_link_libraries CMake commands to use in order to link to the package that was installed. And this works fine; you can even re-execute the install command to see these CMake commands again.
However, some packages installed through vcpkg don't have these. After installing Pango for example, there is no list of CMake commands to actually use the library. I found the target CMake file for find_package in several of the vcpkg package directories, but the Pango directory has no CMake file for the package.
For some reason, example code using Pango can still compile (ie: it can find Pango's headers), but it fails to link due to not linking to the right libraries.
So how is this supposed to work? Do I have to list the include directories, library directories, and library files through a variety of CMake interfaces for Pango? Or is there some alternative inclusion mechanism that takes care of the details like most other vcpkg packages?
Note that I'm using Visual Studio 2019's built-in CMake functionality to try to build with these.
find_package finds a particular kind of .cmake file that is usually shipped with vcpkg packages. These .cmake files do the work of setting include directories and libraries to link with.
As such, if a vcpkg package does not include such a file, you will need to essentially do the work that the file would have done. Fortunately, CMake and vcpkg know where the headers and library build files are for the various configurations. What you need to do is find those directories and libraries, then add them to your project (along with any other special compiler options that the package requires, which requires some familiarity with the package).
To find the include directory containing a library's header, use find_path to set a variable, giving it the name of a header file to search for. For example:
find_path(PANGO_INCLUDE_DIR pango/pango.h)
This header directory can then be set as part of the include path:
target_include_directories(project_name_here PRIVATE ${PANGO_INCLUDE_DIR})
Libraries are a bit harder, since you have to track down the full name (minus extensions) of the actual library. And if the package involves multiple libraries, you need to track down all of those which are applicable to you.
Given the name of a library or libraries of interest, you can find them one at a time with find_library, setting those libraries into variables:
find_library(PANGO_LIBRARY pango-1.0)
find_library(PANGOCAIRO_LIBRARY pangocairo-1.0)
You can then link with those libraries via target_link_libraries:
target_link_libraries(cairo_vcpkg PRIVATE
...
${PANGO_LIBRARY}
${PANGOCAIRO_LIBRARY}
)
Indeed, some packages installed via vcpkg do not export a .cmake file like Pango for you and SDL for me.
I want to clarify that I have been trying to use vcpkg for two days, I share with you the cmakelist.txt that I use on my side so that SDL works as if I had used find_package (SDL Required)
cmake_minimum_required(VERSION 3.16)
project(xxxx)
### Specify the C++ standard ###
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)
### To find and use SDL ###
# find path of include and lib
find_path(SDL_INCLUDE_DIR SDL/SDL.h)
find_library(SDL_LIBRARY SDL)
# find pat of manual-link library
set (LIBRARIES_TO_LINK C:/dev/vcpkg/installed:/x64-windows/lib/manual-link)
find_library(SDL1_TEST SDLmain HINTS ${LIBRARIES_TO_LINK})
....

How to enable cmake to exclude a subdirectory from install?

I have been trying to build RPM packages for libc++ 3.3 on a RHEL 6.4 box. I need both static and shared libraries. So, I learned some basics of cmake and then modified the bundled CMakeList.txt. Got that part to work.
But since in RHEL 6.x, all 64-bit libraries should go to /usr/lib64 instead of /usr/lib, I have been attempting to use the following to get the job done:
(A) During building, I use
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
to have all library files (*.so* and *.a) located in lib64 rather than lib.
(B) Using a ADD_LIBRARY... command as shown below
ADD_LIBRARY(c++ STATIC ...
together with
set_target_properties(c++ PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
INSTALL(TARGETS c++
ARCHIVE DESTINATION lib${LIB_SUFFIX})
to get the static library installed in /usr/lib64.
(C) In addition, with
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so DESTINATION lib${LIB_SUFFIX})
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so.1 DESTINATION lib${LIB_SUFFIX})
INSTALL(FILES ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/libc++.so.1.0 DESTINATION lib${LIB_SUFFIX})
to have shared libary also installed in /usr/lib64 too.
But a copy of the shared library is still installed in /usr/lib in the resulting RPM. How can I prevent it?
If I were to write a RPM spec file, the _libdir macro automatically handles this. With cmake, given the fact that I am still new to it, I would appreciate a hint/pointer as to the right directive to use.
Actually, with a helpful person in the cmake mailing list, I am now able to rid of the %dir /usr/lib in the generated spec file. It's actually quite simple: just cd to $CMAKE_SOURCE_DIR/lib and edit the CMakeLists.txt there. Append ${LIB_SUFFIX} to the two install DESTINATIONs. Regenerate the Makefile in the build subdirectory, and then make && make package. All library files go into /usr/lib64 as desired.
What I can see:
1) There's a missing space in ARCHIVE_OUTPUT_DIRECTORY${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}), should be ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
2) When are your .so files going to be build if you use ADD_LIBRARY(c++ STATIC ...?

Boost 1.48.0 on Fedora Core 16

I'm trying to install ONLY the Boost Libraries 1.48.0 that are 100% complete from FC17 on an FC16 system. I have scoured the net but can't figure out how to do it. I have attempted to upgrade to rawhide but there are too many broken dependencies. I was hoping to just be able to upgrade that one package, as hopefully I don't believe I have too many programs installed that depend on Boost libraries (just the ones I'm coding).
I need to use the new features in 1.48.0. If I can't install them via an RPM, can I compile them as a normal user, store them in ~/lib and link against them?
I'm on FC16 x86_64.
Yes you can. You just need to export several shell environment variables in your shell profile to tell the compiler where to find your new boost header files and shared object files.
# For C and C++ header files search path
export C_INCLUDE_PATH=$your_new_boost_include_dir:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=$your_new_boost_include_dir:$CPLUS_INCLUDE_PATH
# link path
export LIBRARY_PATH=$your_new_boost_lib_dir:$LIBRARY_PATH
Usually you'll also need to do the following so that the compiled executables can be linked to the right version of shared object files at run time:
# run-time
export LD_LIBRARY_PATH=$your_new_boost_lib_dir:$LD_LIBRARY_PATH

Why are 3rd party libraries not found on the OCaml search path?

My configuration is as follows:
OCaml is installed by Homebrew, according to its default recipe. It lives in /usr/local/Cellar/objective-caml/3.12.0/[bin,lib,share], the contents of which are symlinked out to /usr/local/[bin,lib,share].
A 3rd party library (LLVM) installed symlinks into /usr/local/lib/ocaml/*. Critically, /usr/local/lib/ocaml is itself not a symlink to the Homebrew Cellar, but a folder containing links to the individual files under the OCaml Cellar path, so these 3rd party library files are in the /usr/local/lib/ocaml/ path but not the original path of
The standard OCaml compilers/interpreter/build tools consistently fail to find these 3rd party libraries unless they are explicitly pointed there (e.g. with ocamlbuild -cflags -I,/usr/local/lib/ocaml).
ld.conf lists:
/usr/local/lib/ocaml/stublibs
/usr/local/lib/ocaml
/usr/local/lib/ocaml/site-lib/pcre
which would seem to suggest that the compiler search path be set correctly, but I am not familiar with the inner workings of the toolchain.
Is this a known problem?
Is there a way to print the OCaml search paths actually used by the standard tools?
Assuming this is a consequence of the Homebrew configure and installation process (i.e. assuming that the problem is OCaml, as configured, assuming its actual lib path is /usr/local/Cellar/objective-caml/3.12.0/lib/ocaml rather than /usr/local/lib/ocaml), is it possible to force explicitly add additional search paths outside the --prefix during configuration?
Is it possible to extend the search paths for the entire environment after installation (by editing config files, rather than having to resort to potential reinstallation)?
Indeed as ygrek pointed out, the answer is ocamlfind. OCamlfind maintains a list of findlib-enabled¹ OCaml packages installed on your system, and it's easy to link them. Use
ocamlfind list
To get the list of packages, which can be piped to grep etc.
ocamlfind query mypackage
To get the installation path for the package (for more see ocamlfind query --help)
ocamlfind ocamlc -package mypackage .....
To compile something using the package as a dependency (-linkpkg is used in the final linking step to build the executable, you don't need it with -c -o foo.cmo for example).
ocamlfind can also be used through ocamlbuild. Prior to ocaml 3.12 you add to hack a bit the myocamlbuild.ml file (link), but since 3.12 it's dead easy: use package(foo) in the ocamlbuild tags if you want to use ocamlfind's package foo, and add option -use-ocamlfind to ocamlbuild's invocation.
¹: ocamlfind is the lingua franca of OCaml packages. If some of your third libraries don't register themselves through ocamlfind, you should hunt them, write a META file (it's easy), and send it to the library maintainer.
The only builtin search path for ocaml modules is the path to stdlib - see it with ocamlc -where. Paths referenced in ld.conf are used to find stublibs - C code compiled to dynamically loadable modules for bytecode ocaml programs using C bindings (without custom runtime). There is no way to "extend" search paths globally wrt ocaml installation.
The correct way is to add needed include paths when invoking ocaml tools. ocamlfind tool greatly helps to do this in system-independent way. E.g.:
ocamlfind ocamlc -linkpkg -package llvm ll.ml -o ll
High-level build systems like oasis/ocamlbuild/omake/etc hide all this stuff altogether and user only needs to provide names of dependent packages.
I think you're looking for $CAML_LD_LIBRARY_PATH to specify locations of additional libraries to link to, cfr. http://www.cs.jhu.edu/~scott/pl/caml/htmlman/manual024.html
You should be able to set the OCAMLLIB environment variable to get the result you're looking for. This is documented to help ocamlrun find the ld.conf file you noted in your question, but might also help you with ocamlc. The core distribution of OCaml doesn't have a configuration file for library paths, only the config file for locating C libraries.

How to write *.pc files for pkg-config on Windows?

I've recently downloaded the gtk+ all-in-one bundle downloaded from the GTK+ website, which works fine and allows me to build gtk+ applications on Windows using the MinGW compiler.
However, when now looking at the *.pc files for pkg-config in lib/pkgconfig, I noticed something weird. Here's how the beginning of glib-2.0 looks like:
prefix=c:/devel/target/059c48de6b739307c37648aba3005b29
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
My gtk+ folder resides on a different drive than C:\ and I don't have a C:\devel folder at all. So what does this prefix stand for? What prefix would I use if I decided to write a *.pc file for easily linking my own application?
Surprisingly enough, using pkg-config works as expected and returns the correct path the libraries and headers inside the gtk+ folder.
The version of pkg-config that comes with the all in one package basically ignores the prefix. It knows to look in ../lib/pkgconfig for the pkg-config files. You don't need to do anything special for your pkgconfig files other than either put them in that pkgconfig directory, or set some environment variables so pkg-config knows where to look for your *.pc files.

Resources