When would you use find_path? - c++

I am reverse engineering someone's code and I came across a line like so in the CMake file
FIND_PATH(OPENSSL_INCLUDE_DIR openssl/ssl.h
/usr/local/opt/openssl/include
/usr/opt/openssl/include
/usr/local/include/openssl
/usr/include/openssl
/usr/local/include
/usr/include
)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
FIND_LIBRARY(LIB_CRYPTO crypto PATHS
/usr/local/opt/openssl/lib
/usr/opt/openssl/lib
/usr/local/lib
/usr/local/openssl/lib
/usr/lib
/usr/lib/openssl
)
I come from a make background, so I would use something like LDFLAGS=$(shell pkg-config --cflags --libs openssl but I would never know what header file is being included.
It seems impractical/unfeasible to know every header file included in, for example, a large dlib project which links opencv and cuda libraries, so my question is this:
When/Why would you actually reference the header file by name?

CMake needs to support platforms where pkg-config is not available.
You are correct that the find mechanism is somewhat primitive. That is why CMake also offers more sophisticated options like config-file packages or even pkg-config support. The problem with all these approaches is that they require some king of external support. Package config scripts must be provided by the dependency you are trying to find and pkg-config must be available and configured properly on the platform you are trying to build on.
The various find_* commands have no such prerequisites. They simply try to find a file or directory the filesystem. That's what makes them the most powerful commands in a way, because you can always accept a hint provided by the user where to find the files (which the people in your example code did not do btw, so shame on them) and then the find can work its magic. But it's also the most inconvenient, as it's easy to mess up and tedious to use in practice.
So keep in mind that CMake's primary goal is to be portable. Don't shy away from whatever mechanisms your platform offers to make configuring the build more convenient, but also don't lock out people that are less fortunate and have to work on platforms where those mechanisms are not available.

Related

What is the difference between a lib and an module with autoconf

I have to check that certain libraries (libm, libdl) are present in order to compile my library.
In my configure.ac template file, there is PKG_CHECK_MODULES macros and PKG_CHECK_LIB macros.
I don't understand which one to use and how?
The PKG_CHECK_MODULES seems the most global one because it checks if a whole library is present and PKG_CHECK_LIB checks only if one function is accessible… But when I do PKG_CHECK_MODULES([LIBM],[libm],[],[exit -1]), it exists and I don't understand why.
I think I'm misunderstanding some concepts. Maybe someone could lead me to good references.
PKG_CHECK_MODULES is for integrating with packages that have pkg-config metadata. This metadata is typically stored in a file called foo.pc (for package foo) in someplace like /usr/share/pkgconfig. This file will say where foo and its associated files (header files, libraries, executables, data, etc.) have actually been installed.
However, most packages don't use the pkg-config system, including the standard C library which is where libm and libdl are. So you'll need to test for them using AC_CHECK_LIB.
You seem to be confused, so I'll go on a bit of a tangent here:
Once upon a time, there was X11; there were many incompatible installations of X11. To write code that would compile against each variant, people would write crazy autoconf macros to try to figure out automatically what libraries to list before, what libraries to list after, and what extra flags were needed in between. (see AC_PATH_X, AC_PATH_XTRA).
Some people tried more sensible approaches, and wrote shell scripts to install along the libraries; so you would just call them and they would give you all the magic flags needed for that specific libraries. (see sdl-config, wx-config, freetype-config, motif-config, etc)
Then the folks from freedesktop.org decided it was a chore for everyone to maintain those scripts that did essentially the same thing, so they wrote a tool (pkg-config) that would work like all those *-config scripts, and would not require a shell to run (yay for Windows users). All the library authors need to do is to write the metadata in the *.pc files, and install them along the libraries.
Regarding autoconf, it has low-level ways to poke around the system to find out about the libraries: AC_CHECK_HEADERS, to see if the headers are present and usable, and AC_CHECK_LIB, to see if it's possible to link against them.
The pkg-config tool comes with convenience macros for autoconf, mainly PKG_CHECK_MODULES, which instead of poking around, it simply looks for the metadata the library might have installed.
Regarding libm, libdl, as ldav1s said, they are part of the system; some systems need explicit link against libm (which provides math functions) and/or libdl (which provides functions for dynamically loading shared objects). Often other tools, like gcc or libtool, take care of linking against them. Unfortunately they don't come with meta-data for pkg-config, so if you have to find them manually, you'll have to poke around with the old AC_CHECK_HEADERS and AC_CHECK_LIB macros to find them.

How do you link to a library from the software manager on Linux?

So I recently got fed up with Windows and installed Linux Mint. I am trying to get a project to build I have in Code::Blocks. I have installed Code::Blocks but I need glew(as well as a few other libraries). I found it in the software manager and installed it. I've managed to locate and include the header files. But I feel like the next step should be relatively straightforward and all over the internet but (perhaps due to lack of proper terminology) I have been as of yet unable to locate an answer.
Do I need to locate the files on my system and link to each library manually? This is what I did on windows but I just downloaded the binaries and knew where they were. I found one library from the software manager and linked to it manually but it just feels like I'm doing it the wrong way. Since it's "installed" on the system is there some quick way to link?
You should use two flags for linker '-l' and '-L'. You can set these flags somewhere in project properties.
The first one '-l' tells linker to link with particular library. For example glew, probably in /usr/lib is a file named libglew.so, when you link your program with '-lglew' flag, it will link it with glew library. Linker looks for libraries in few standard places: /usr/lib, /usr/local/lib and few extra. If you have your libs in nonstandard place, use '-L' flag to point these dirs.
Many linux distributions provide two kinds of packages with libraries, regular ones just with runtime, and devel ones (usually prefixed or suffixed with dev or devel) with header files and development version of libraries.
use build systems, Luke!
the typical way to develop/build software in *nix world is 3 steps:
configure stage -- before building smth you have to realize in what environment you are going to build your software... is everything that required is installed... it wouldn't be good if at compile stage (after few hours of compilation) you (or user who build your soft) got an error: unable to #include the 'xxx.h'. the most popular build systems are: cmake, my favorite after autotools. yout may try also scons or maybe crazy (b)jam...
compile stage -- usually just make all
install stage -- deploy just built software into the system. or other way: build packages for target distro (.deb/.rpm/&etc)
at configuration stage using test scripts (don't worry there are plenty of them for various use cases) you can find all required headers/libraries/programs/compiler options/whatever you need to compile your package... and yes: do not use hardcoded paths in your Makefiles (or whatever you use to make your binaries)
Answer to this question really depends on what you want to achieve. If you want just to build you app by yourself then you can just write path to libraries in your makefile, or your code editor settings. You may not even have to do that as if libraries installed by your linux distribution package manager, headers usually go to /usr/include and libraries to /usr/lib or /urs/lib64 etc. That locations are standard and you do not need to specify them explicitly. Anyway you need to specify libraries you want to link to.
If you want to create application that can be build by others, or by you on many different configurations/environments using something like cmake would be very helpful.

PKG_CHECK_MODULES for somelib++

I am trying to make my autotools project in C++ link against library, that originates as C library (libsomelib.so), but also has bindings to c++ (libsomelib++.so). I ma trying to use PKG_CHECK_MODULES to check if this package is installed, and use autotools to link against it. However both libs come in one package (c++ version requires configure flag), and have only one .pc file, in which independently of configuration settings there is only line
Libs: -L${libdir} -lsomelib
without any mentioning of ++ version. There is also no separate ++.pc file that i noticed at other programs. Therefore automatic linking against ++ version is impossible. I thought about manually adding -lsomelib++ to linking flags, but that's rather ugly (and it will not work if somebody compiled it without --with-cxx flag). I could also test for it's existence by AC_SEARCH_LIBS, but since it's C++ library it's not so straightforward.
Is missing ++.pc file mistake of package distributor or is it some deeper idea, and i don't know how to use it?
If somebody is really qurious i will say that package in question is ossp-uuid.
Yes, the missing ++.pc usually hints towards an omission on behalf of the packager.
BTW: If simple (DCE) UUIDs are sufficient, you could consider e2fsprogs/util-linux's libuuid (in case you run this OS).

Where do I put third-party libraries to set up a C++ Linux development environment?

I'm not new in C++ although I'm new in Linux. I'm using CMake to precompile a cross-platform game engine with some third-party components, but I have a lot of doubts about using libraries. My question is how to work with third-party libraries and where to put them. Apt installs libs in their official place (/usr/local, /usr/lib/ ..) but I develop in Windows using local libs that are in a folder in my project dir.
Also, I need a good tutorial to know the rules of how libraries work. For example: when trying to compile my project, luabind is asking for liblua.s0.1, but AFAIK there is no way to generate this library with the source provided by Lua (at least doing make, make install).
I know, this question is fuzzy but I haven't enough experience to be more concise.
Update: After reading some answers, a more concise question is the following. If I install all third-party libraries, how can I distribute my program? How do I manage dependencies without using a large readme?
Where to put libraries
The best solution is to use your Linux distribution's packaging system (apt-get, yum, or similar) to install libraries from distro-provided packages wherever possible.
If the distro's packaged libraries aren't of a recent enough version, or if you need some nonstandard build options, or if you need a library that your distro doesn't provide, then you can build and install it yourself. You have two main options for where to put the library:
/usr/local (libraries under /usr/local/lib, headers under /usr/local/include). This installs the libraries systemwide and is probably the simplest solution, since you should then be able to build against them without taking any extra steps. Do NOT install libraries directly under /usr, since that will interfere with your distro's packaging system.
Under your project directory, as you did under Windows. This has the advantages of not requiring root access and not making systemwide changes, but you'll have to update your project's include paths and library paths, and you'll have to put any shared library files someplace where the dynamic linker can find them (using LD_LIBRARY_PATH or ld.so.conf - see the link for more details).
How libraries work
See David A. Wheeler's excellent Programming Library HOWTO. I'd recommend reading that then posting any specific questions as new topics.
How to distribute your program
Traditionally, Unix / Linux programs do not include copies of their dependencies. It's instead up to the end user or developer to install those dependencies themselves. This can require a "large README," as you said, but it has a few advantages:
Development libraries can be installed, managed, and updated via the distro's package manager, instead of each source copy having its own set of libraries to track.
There's only one copy of any given library on a system, so there's only one place that needs updating if, for example, a security flaw is found. (For example, consider the chaos that resulted when zlib, a very widely used compression library, was found to have a security flaw, so every application that included an affected version needed to be updated.)
If your program is popular enough (and is open source or at least freely available), then package maintainers for various Linux distributions may want to package it and include it in their distro. Package maintainers really don't like bundled libraries. See, for example, Fedora's page on the topic.
If you're distributing your program to end users, you may want to consider offering a package (.dpkg or .rpm) that they could simply download and install without having to use source. Ideally, from the end user's perspective, the package would be added to distros' repositories (if it's open source or at least freely available) so that users can download it using their package managers (apt-get or yum). This can all get complicated, because of the large number of Linux distros out there, but a Debian/Ubuntu compatible .dpkg and a Red Hat/CentOS/Fedora-compatible .rpm should cover a good percentage of end users. Building packages isn't too hard, and there are good howtos online.
for the first part of your question regarding Windows: there's no real standard place for libraries/headers on Windows, so the easy solution is: create your own. Simply provide a single lib/ and include/ on your system and have all your projects use it (by setting the path in a cmake file that you include everywhere). Put all third party libs in there, for example:
your projects:
d:/projects/projectA
d:/projects/projectB
third party stuff:
d:/api/lib/lua.lib
d:/api/include/lua/....
(you can even use symlinks aka 'directory junctions' if you have different version)
and the corresponding cmake file:
include_directories( d:/api/include )
link_directories( d:/api/lib )
Okay, so this is one of the basic questions and while I myself might not come across very clear on this, here goes:
While building a project, your compiler will need to find the header files of the libraries. The headers must be in the include path.
after compilation is done, the linker will look for the library binaries (files.so or something like that). These must be in the Library path.
That's the basics.
If you have some specific libaries, you can add them to your own project-specific lib/ and include/ directories and add them to the include path and the library path respectively.
Adding these dirs to these paths can be done in many ways, depending upon how you are building the project. I'm sure there is something called LD_PATH involved in all this... But I don't really know the specifics involved with CMake.
A little googling can help you do the above with CMake.
Hope that helps,
jrh
If you are installing the libraries with a package manager, they will probably all end up in the right place. If not you can get the compiler to search for the by providing the an additional search path using the -L <path> flag. You should be able to pass this extra flag to CMake.
Incidentally the -I <path> can be used to add an extra directory to search for include files.

How to use Festival Text To Speech C/C++ API

I want to use Festival TTS with my C++ programme.
So i have downloaded all files form http://www.cstr.ed.ac.uk/downloads/festival/2.0.95/
then i start reading manual(http://www.cstr.ed.ac.uk/projects/festival/manual/festival_28.html) for C++ API but in manual they says that:
In order to use Festival you must include festival/src/include/festival.h' which in turn will include the necessary other include files infestival/src/include' and speech_tools/include' you should ensure these are included in the include path for you your program. Also you will need to link your program withfestival/src/lib/libFestival.a', speech_tools/lib/libestools.a',speech_tools/lib/libestbase.a' and `speech_tools/lib/libeststring.a' as well as any other optional libraries such as net audio. "
I am using UBUNTU 10.04(festival package is by default installed and i can use it form terminal by festival command) and GCC 4.4.3
but the problem is that i am new to GCC and i am not understanding which files i have to include in order to run my C++ code and i also don't know how to link libraries with my c++ code.
So please tell me exactly which files i have to include and how to link with libraries if anyone already use festival tts with c++ then please post your code
Thanks
1) #include <festival.h> at the beginning of your program (because you have it installed). It could also be festival/festival.h or something like that (it depends on how does the package install) - and I can't say exactly, because I've never used it. Still I assume the first variant would work by default.
2) Link all the libraries you need (those three which you'll definitely need are listed in your bold text) using appropriate GCC switch. If you're not familiar with GCC syntax, you'd better read some manuals / google it, because there's a lot of important information.
P.S Instead of adding the static libraries via console switch, you could definitely write an appropriate makefile for your project. But the situation here is the same as with GCC switches - there is are many different manuals about using makefiles and I definitely won't copy/paste them in this answer.
4 years old. Perhaps it has been solved. Anyway.
I strongly recommend you use CMAKE for that. You need to use:
set(EST_DIR "${CMAKE_CURRENT_LIST_DIR}/")
find_package(EST REQUIRED)
set(Festival_DIR "${CMAKE_CURRENT_LIST_DIR}/")
find_package(Festival REQUIRED)
INCLUDE_DIRECTORIES(include ${CMAKE_SOURCE_DIR}
${EST_INCLUDE_DIR}
${Festival_INCLUDE_DIR})
file(GLOB_RECURSE headers "include/*.h*")
file(GLOB_RECURSE sources "src/*.c*")
add_executable(festivalProject ${sources} ${headers} )
target_link_libraries(Project ${EST_LIBRARIES} ${Festival_LIBRARIES})
For that you will need 2 files at the same location of your CMakeLists.txt file:
ESTConfig.cmake - Source Here
FestivalConfig.cmake - Source Here
NOtice that you will need both, EST and Festival to make it compile (Festival depends on EST). Of course you can also dive in your hard drive and #include/link directly against every file you need.
While the festival command line program might be installed, the headers for developing programs based on festival are in a different package -- ensure that you've got the festival-dev package installed too.