How can I include a needed C library using GCC? - c

I am trying to compile the simple C example from this tutorial on Ubuntu using GCC. What do I have to use as arguments for GCC to include the needed libraries for #include <libappindicator/app-indicator.h>?

-I<search path to include files>
-L<search path to the lib file>
-l<libname>

Use the -l command line option. You can specify the library search path with the -L option. E.g:
gcc -o myprogram -lfoo -L/home/me/foo/lib myprogram.c
This will link myprogram with the static library libfoo.a in the folder /home/me/foo/lib.

If you used apt-get, Synaptic Package Manager, etc. to get the appindicator library (vs. building it from source), did you only install the libappindicator1 package or did you also install libappindicator-dev to get the libappindicator header files? Linux packages very often have split the runtime libraries from the compile-time headers. That way people who only need the libraries to satisfy a dynamic link don't have to install unneeded headers. But since you're doing development you need those headers and therefore need the libappindicator-dev package as well.

What I do is:
pkg-config --list-all | grep indicator

Use:
gcc example.c -o example `pkg-config --cflags --libs appindicator-0.1`
pkg-config will fetch the required include and library flags for libappindicator and its dependencies. This assumes libappindictaor-dev package is already installed.

You are trying to make a GTK app, and the previous solutions are as applicable anywhere like using the -l option and -I option,
However, for GTK applications, you may also use pkg-config which makes it easier as your paths can be predefined.
An interesting example can be found in
http://developer.gnome.org/gtk/2.24/gtk-compiling.html

Related

pkg-config: print Requires.private without being recursive

I have a problem which I think I can solve if I manage to get from pkg-config the list in Requires.private without being recursive. First I'll post the problem, and then my try to workaround it.
Problem:
I had a static-only library (let's call it libfoo.a) with no pkg-config files, which I just included as a submodule of my programs. I had to take into account in the program makefile all the dependencies that my library might have, because as a static library, it didn't carry the information of which shared library it depended on. That meant that I had to dinamically link with a lot of libraries in my programs' makefiles, but that worked.
Example:
$(CC) $(OBJS) -o $# -L path/foo/ -l foo `pkg-config --libs opencv gsl ncurses`
It worked, because it could only find a static version of libfoo, and after that it had a list of what libfoo needed (instead of what the program actually needed dinamically).
Now I have improved that library so that it is installed in /usr/local/, provide pkg-config files, and both .a and .so files.
When I link dinamically to my library, everything is fine.
When I try to link statically, if the program doesn't use opencv at all, it is fine (I don't know if it's opencv that is broken when trying to link statically, or that I broke it installing some updates from the testing repo; if I had a clean installation I would know, but I don't). The problem comes when I try to link statically, and some opencv is used. There are some libraries not found, so what I thought as a solution is to replicate what happened before I installed my library.
But now I don't want to hardcode my library's dependencies in my program's makefile, so I use pkg-config.
My try:
Assuming that my program only depends directly on libfoo, and libfoo depends on opencv, gsl and ncurses directly (which my program ignores), this is what I would do:
$(CC) $(OBJS) -o $# -Wl,-Bstatic `pkg-config --libs foo` -Wl,-Bdynamic `pkg-config --static --libs foo`
the first pkg-config is to expose only libfoo to be linked statically, and the second one is to expose libfoo's dependencies to be linked dinamically. But the problem is that I'm exposing, not only libfoo's direct dependencies, but also all the recursive dependencies, which I don't want to.
Is there any way to expose only the direct dependencies? Or is there any other workaround to this situation?
In this case, it is needed to the problem with a broken openCV, and someone could say: hey, just solve that problem with openCV, and forget about that.
But this is also useful for someone who wants to link statically to a library which performance is critical, but still link dinamically to other heavier libraries which aren't as critical.
System:
Debian 10
GCC 8
OpenCV might have some packages or dependencies installed from testing.
I just bumped into this, and I think I'm going to have to write a bit of Python to just repeatedly call pkg-config.

Questions about how libraries work in C

I am a newbie student learning C and wish to use the gLib library functions for a project: http://www.linuxfromscratch.org/blfs/view/svn/general/glib2.html
(I am using Ubuntu)
I have a couple questions about how libraries work in C and what happens when you install one or want to use one:
When I install this (run ./configure && make && make install inside the folder), what exactly is it doing? From what I learned there are shared libraries in C and static libraries in C. Is it true that it is installing library and include files to /usr/lib/ or somewhere?
When using gcc with external libraries, you have to specify -L and -I flags to specify where to look for library and header files. When I install glib, will I need to specify these flags?
If I want to package my executable for another machine, what would happen if the other machine doesn't have glib? I think if I had static libraries I would be able to include it in the binary, but how would it work for glib?
I am familiar with developing with GTK+ and GLIB. As i'm aware library files reside in /usr/lib and include files are found in /usr/include. Some libraries might be in places such as /usr/local/lib. I will attempt to answer your questions as best as I could.
When installing a library through the source package yes it installs files to the various folders /usr/share /usr/lib /usr/include and etc. It's highly recommended you use your distribution's package manager to install library packages and development headers. Installing from source is always bound to fail as necessary dependencies might be required.
This is where tools such as autogen and makefiles come handy. You don't necessarily need to concern yourself with specifying all that. tools such as pkg-config handle all that work. Most libraries will install a package configuration file into /usr/lib/pkgconfig & /usr/share/pkgconfig directories. This helps anyone developing an application easily link their code to the libraries.
Using package config to get the config:
$ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0
Linking using GCC & package config:
$gcc example.c `pkg-config --cflags --libs gtk+2.0 glib-2.0` -o example
The above command would link my program with gtk & glib.
Using Makefile to not ever have to enter those long lines again:
Makefile:
OBJS = main.o callbacks.o
CFLAGS = `pkg-config --cflags --libs gtk+-2.0`
program: $(OBJS)
gcc -o program $(OBJS)
main.o: main.c
gcc -c main.c $(FLAGS)
callbacks.o: callbacks.c callbacks.h
gcc -c callbacks.c $(FLAGS)
.PHONY : clean
clean:
rm *.o
rm program
.PHONY : install
install:
cp program /usr/bin
.PHONY : uninstall
uninstall:
rm /usr/bin/program
The above makefile is for a simple GTK+2.0 application as you can tell by what package config is including in CFLAGS to make the program executable all you have to enter in your source directory would be make. pkg-config will only work if you have installed the development packages for the library you are trying to work with. For ubuntu to install GTK+-3.0 and GLIB development files you would enter:
$ apt-get install libgtk-3-dev
I think this is a good concern for portability. No single static library is going to be cross platform. It would have to be compiled for those platforms manually. I reckon to get rid of all the headache you would use Anjuta IDE developed by the GNOME software foundation. It makes developing GLIB & GTK+ apps a breeze supporting both C & C++. It will create the Makefile, configure and other files to make developing code on cross platforms easy and make deployment easy. I could link you some resources, but my reputation on stack overflow is less then 10. So I will just mention the name of some resources below.
Further Reading
Makefile Tutorial
Anjuta IDE (C/C++)): ://anjuta.org/
GTK+-3.0 Hello World with Compiling and linking using pkg-config:
When I install this (run ./configure && make && make install inside
the folder), what exactly is it doing? From what I learned there are
shared libraries in C and static libraries in C. Is it true that it is
installing library and include files to /usr/lib/ or somewhere?
Well it is running first ./configure and then if that succeeds it runs make and if that succeeds it runs make install. configure is a script that takes care of a lot of compatibility issues between systems. They are usually shell scripts as this is the common denominator across systems so the configure script will work across various systems. One of the thing configure does is create a Makefile. The second command make will use the newly created Makefile to build the library or executable. Since you did not specify a target (like you will in the make install) make will build the default target, which is typically the all target. This is just by convention. Makefiles are basically a list of things to build (targets) along with what they depend on (dependencies) and how to build to target (rules). Finally, make install will actually install the necessary components. For libraries this is the library and necessary header files for executables it is just the program. man pages might also be installed. Where you install the libraries depends on where you specify to install them. Typically configure will take the --prefix argument that lets you control where they are installed. If you do not use --prefix you will most likely install in the default location for your system.
When using gcc with external libraries, you have to specify -L and -I
flags to specify where to look for library and header files. When I
install glib, will I need to specify these flags?
Your question is a little unclear, so let me first make sure I understand. Are you asking if after you install glib will you need to use -L and -I to tell gcc where to look for them? If so it depends on where you install them. Typically when you make and install a library you will install the library and header files in the default location or not. If you did then assuming your gcc is configured correctly then no you will not. If you did not then you will most likely have to use -L and -I
If I want to package my executable for another machine, what would
happen if the other machine doesn't have glib? I think if I had static
libraries I would be able to include it in the binary, but how would
it work for glib?
If it doesn't have glib and you used the shared libraries your application will not work. You will need to either have the same version glib libraries on the other machine or build the libraries statically. How to build them statistically depends on the library. This SO question might help.
Regarding configure, make and make install. configure is a shell script that is used to discover (and configure) your development environment. make and make install are convenient way of building your software. Where make would normally involve compiling and linking, where as make install would normally involve copying executables and libraries to standard path and setting up things (also include files if any usually in /usr/include), so that you don't have to explicitly give path before running the executable. What make does can be done by hand, but it's very cumbersome.
For glibc - yes you have to specify those flags. Normally all libraries will come in two flavors on most of the platforms. The binary form are used for dynamic linking when programs are actually loaded. Also - most distributions will have -dev or -devel versions of those libraries. Those are required for building software that makes use of those libraries (configure above can help find out whether devel libraries are installed). Typically when you see a library installed but not it's devel - you are likely to see configure errors. In short you require devel versions if you want to link with those libraries. This step is not needed if you are building libraries also from source using make and make install.
If you want to package your executable for another machine and you are not sure whether another glib is there or you want to be sure that the glib to be installed should be one specific version that you want, you should statically link while building (compiling/linking) the library. this gcc man page has got several details about link options. I believe there should be a way to statically link glib(or glib2). Though normally that may not be required if you have enough applications that are using it already.

OpenCV - C library is not working in my Ubuntu11.10

Resently I'm installed Opencv in my machine. Its working in python well(I just checked it by some eg programs). But due to the lack of tutorials in python I decided to move to c. I just run an Hello world program from http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/
while compiling I got the following error
hello-world.c:4:16: fatal error: cv.h: No such file or directory
compilation terminated.
I'm new in opencv
Qn : Could you please report what may be the problem - and how I run my helloworld program in c?
Your compiler cannot find your cv.h include file. If you installed from your package manager, it is probably in /usr/include/opencv/. You need to add that your include search path. If you are compiling from the command line use -I to specify additional include directories. It will be something like -
gcc -I /usr/include/opencv/ -o helloworld helloworld.c
If you are using Eclipse,
Right click on the project and select properties.
Select C/C++ General -> Path and Symbols.
Select Includes tab.
In Languages list, select 'GNU C' or 'GNU C++' depending on which you are using.
Press 'Add...' button and add /usr/include/opencv/
Save and rebuild.
You need to show compiler path to cv.h file. The quick way to find it is to do (on Ubuntu):
find /usr -name "cv.h"
/usr/local/include/opencv/cv.h
Just add this to the compiler:
gcc -I/usr/local/include/opencv -o helloworld helloworld.c
Since you asking this question your compiler might also have problems linking your program to opencv libraries. Just do the same thing only for library files:
find /usr -iname "libopencv*"
/usr/local/lib/libopencv_flann.so
...
add this folder the same way and specify libraries you want to use:
gcc helloworld.c -I/usr/local/include/opencv -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -o helloworld
that should probably compile. There is a also a short cut you can take and instead of all that steps just use the following command
gcc helloworld.c `pkg-config --cflags --libs opencv` -o helloworld
that should take care of all the work of locating required files for you and let you focus on the fun coding part.
maybe you just installed the opencv package.
But, as you want to use opencv in your C program, you may also install the package named just like opencv-devel. If you haven't, install it and than use it as #iagreen said.
Best wishes to you.

How do I use a c library after I configure, make and make install?

I need to use a C library to access and older file format used by a legacy application. The library I installed was libdbf. (Did ./configure && make && make install). It was installed under /usr/local/lib:
libdbf.0.0.1.dylib
libdbf.0.dylib
libdbf.a
libdbf.dylib
libdbf.la
I'm loosely familiar with C syntax and have done some very trivial things in C and C++, but don't know how to include the library.
How can I include this library in my project? Sorry for the noobie question.
When you compile your project use -ldbf
The -l means link, and the dbf is the name of the library (you don't need to include the lib part of the name).
Edit:
I haven't used Qt, but it looks like you can add
unix:LIBS += -ldbf
To your .pro file. Sources 1, 2
By default, gcc will look in /usr/local/include for the headers and in /usr/local/lib for the library. In case it you need to make it explicit, you can also add:
-I/usr/local/include -L/usr/local/lib
If you'd like to compile your project with symbols exported by the library you have to add -I /usr/local/include, assuming that the headers were properly installed. For linking you'll need to add -L /usr/local/lib -ldbf. You can also pass the path to the library explicitly, so instead of -L /usr/local/lib -ldbf add /usr/local/libdbf.0.dylib.
See GCC's linking options.

How do I use glib in kdevelop?

I'm using Kdevelop 4.0 to make a new app, and now I'm trying to include the glib but I cannot do it.
I have installed via apt-get install in Ubuntu 10.04 and it's installed in /usr/include/glib-2.0, but when I try to include the library with
#include <glib.h>
and try to compile it, it tells me that "such file doesn't exists".
What am I doing wrong?
Thanks!
You need to pass the path to the glib libraries and headers to your compiler.
glib provides the pkg-config script to generate what you need. To compile correctly, you would need to do something like the following:
cc `pkg-config --cflags --libs glib-2.0` hello.c -o hello
This answer is basically a quick summary of what is provided in the glib documentation here:
http://developer.gnome.org/glib/2.28/glib-compiling.html
I'm not familiar with KDevelop, but if it's like Eclipse or Visual Studio, there is a menu for adding libraries and include folders to a project. Try the following:
Run pkg-conf --cflags glib-2.0
Add output to include directories for your project.
Run pkg-conf --libs glib-2.0
Add output to libraries path for your project.
A quick look on google suggests that you can find these menus at the following locations:
Include Directories
Automake manager> options> Includes> Directories
Library Directories
Automake Manager > Options >Libraries > Link Libraries

Resources