Adding a library to a makefile - c++

I just installed RtMidi for a project and compiled it. The examples in the tests folder work and so does my code if I put it in the folder and include it in the Makefile that compiles all the examples. How can I use RtMidi in a project with #include <RtMidi.h> instead of having my code in the tests folder? More specifically, what should I put in my Makefile? I've read a bit about dynamic and static libraries but I have no idea what I should be looking for. I've tried adding -llibrtmidi and /usr/local/lib/librtmidi.a without success.

In a standard Makefile, the CXXFLAGS macro defines flags for the C++ compiler. You will need to add -I<path to header directory> to this macro for the compiler to find the RtMidi header files.
Then you will need to add -L<path to lib directory> to the link step of the Makefile so that -lrtmidi will find the library file. (Note that you omit the lib prefix for the -l command)

Based on your description of your environment, you may require something like
CPPFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib
LDLIBS += -lrtmidi
in your Makefile. make uses a lot of these implicit variables.

Related

How to use a library with headers and .so files?

I'm new to C and wanted to use a library (MLT Multimedia Framework)
I've built it and it produced the following directories: include lib share
Inside lib there are .so .a .la files
Inside include there are .h files
Now, I'm instructed to do this:
#include <framework/mlt.h> which is inside include/mlt/framework/
Questions:
Why I do I need to place the header file that contains only function prototypes? Where are the real functions then? are they linked someway to the ones included in lib directory?
Where to place my own files and how to compile it?
How to learn more about the topics:
Dynamic/Static libraries
Building / making / installing
How to use any C library
If you don't have the function prototypes, how would the compiler know what functions exist in the library? Short answer is: It doesn't. Longer answer: The compiler doesn't care about library files, static (files ending in .a) or shared (files ending in .so), all it cares about is the current translation unit. It's up to the linker to handle resolving undefined references.
When you use libraries, you include the header files that contain the needed declarations (structures, classes, types, function prototypes) into the source file. The source file plus all included header files forms the translation unit that the compiler uses to generate code. If there are undefined references (for example a call to a function in the library) the compiler adds special information about that to the generated object file. The linker then looks through all object files, and if it finds an unresolved reference it tries to find it in the other object files and the provided libraries. If all definitions are resolved the linker generates the final executable, otherwise it will report the unresolved definitions as errors.
To answer your other questions:
Where to place my own files and how to compile it?
This is two questions, the answer to the first one (about placement of your files) is that it doesn't really matter. For small project with only a few source and header files, it's common to place all files in a common project directory.
The second question, about compiling, there are different ways to do it too. If there are only one or two source files you could use the compiler frontend (e.g. gcc) to compile and link and generate your executable all in one go:
$ gcc -Wall -g source1.c source2.c -o your_program_name
The above command takes two source files, compiles and links them into the program your_program_name.
If you need to use a library, there are one or two things that you need to add to the above command line:
You need to tell the linker to link with the library, this is done with e.g. the -l (lower case L) option:
$ gcc -Wall -g source1.c source2.c -o your_program_name -lthe_library
It's important to note that the_library is the base name of the library. If the library file is named libthe_library.so then only the_library part is needed, the linker will add the other parts automatically.
If the library is not in a standard location, then you need to tell the compiler and linker where the library file are. This is done with the -I (capital i) option to tell the preprocessor where the header files are, and the -L (capital l) where the linker files are.
Something like
$ gcc -Wall -g -Ilocation/of/headers source1.c source2.c -o your_program_name -Llocation/of/libraries -lthe_library
If you have more than a couple of source files, it's common to use so called makefiles that lists all source files, their dependencies, compiler and linker flags, and contain rules on how to build object files and link the final program. Such a makefile could look like
CFLAGS = -Wall -g
LDFLAGS = -g
SOURCES = source1.c source2.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = your_program_name
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) $^ -o $#
%.o: %.c
$(CC) $(CFLAGS) $< -c -o $#
The above makefile should do just about the same as the previous command line. The big difference is that it's much easier to add more source files, add special rules for special files, and most importantly, the make program will handle dependencies so that if one source file haven't been modified since last build then it won't be compiled. The last bit will make big projects with many source files build much quicker when only one or a few source files has been modified.
How to learn more about the topics [...]
By going to your favorite search engine, and looking for those topics there. I also recommend e.g. Wikipedia.
Of course, if you use an Integrated Development Environment (a.k.a. an IDE) then you don't have to compile from the command line, or to make your own makefiles, the IDE will handle all that for you. It will also have dialogs for the project settings where you can enter include paths and library paths, and what libraries to link with.
Why I do I need to place the header file that contains only function prototypes?
So as to satisfy your compiler for declaration of those functions or declaration of classes. As C++ is static type checking language, they must know the type of objects which they will be using.
Where to place my own files and how to compile it?
You can place you code anywhere in you filesystem; only make sure to include .h files in includes path and lib while compiling. Usually you need to modify your path.
You can check about building on this link:
https://en.wikipedia.org/wiki/GNU_build_system
Check the README file that came with the code. It should tell you how to install it into the system properly. Usually there is an install build target which installs the resulting files into the proper directories.
The usual sequence of commands to build and install most products is:
$ ./configure
$ make
$ sudo make install

c++ LDLIBSOPTIONS makefile

I want to use some other project libraries in my implementation. The project has a /common folder where the libraries are located I want to include. In my makefile under LDLIBSOPTIONS, I included the path where /common folder is located like:
LDLIBSOPTIONS=-lpci -lpthread -I../../../OtherProj/Libs/common/
Then I include one .h file like:
#include <ExampleLib.h>
However I still get
fatal error: XXX.h: No such file or directory
What am I doing wrong? Thanks.
LDLIBSOPTIONS (more conventionally LDFLAGS) is used for specifying options to the linker. You need to specify the directory, using the -I flag, in CXXFLAGS:
CXXFLAGS += -I../../../OtherProj/Libs/common/
However given you are using non-standard names for your Makefile variables, CXXFLAGS might be called something like CXXOPTIONS, but the exact name is unknown to me.
Once this is solved you're going to be getting linker errors until you start specifying the library path using -L; perhaps:
LDLIBSOPTIONS = -L../../../OtherProj/Libs/common/ -lpci -lpthread

C++: get Boost working; questions on include path and linking library

I was trying to use Boost.Tokenizer library. In my PROG.cpp, I have the following:
#include <boost/tokenizer.hpp>
And my Makefile was initially something like
CXX = g++-4.8
CXXFLAGS = ## some irrelevant flags
LDFLAGS = ## some irrelevant flags
SOURCES = PROG.cpp
OBJECTS = $(SOURCES:.cpp=.o)
TARGETS = PROG
$(TARGETS) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
## other targets
It won't compile, since boost/tokenizer.hpp cannot be found:
fatal error: boost/tokenizer.hpp: No such file or directory
Then I manually added the boost include path to CXXFLAGS:
-I/opt/local/include/
(which is the path from MacPorts.)
Then I tried to include the Tokenizer library, but in /opt/local/lib/ I have libboost_atomic-mt.dylib, libboost_chrono-mt.dylib, etc., but nothing like tokenizer. I was rather confused at the time. I supposed that still wouldn't work since the library was not linked against. Surprisingly, the program built, linked, and ran perfectly.
So I'm really confused now. Here are some questions:
(1) I did not link against boost explicitly, so boost is treated like standard library by the linker?
(2) If boost is treated like standard, why the headers are not standard?
(3) Why there are libboost_atomic-mt.dylib, libboost_chrono-mt.dylib, etc. but not tokenizer? Which dynamic library does tokenizer belong to?
I'm not very familiar with g++ linking mechanism; speaking of boost, this is my very first program with boost. So I'd really appreciate detailed explanation. Thanks in advance!
For reference, this is what I extracted by gcc -print-search-dirs:
install: /usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/
programs: =/usr/gcc-4.8.0/libexec/gcc/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/libexec/gcc/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/libexec/gcc/x86_64-apple-darwin12.3.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../../x86_64-apple-darwin12.3.0/bin/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../../x86_64-apple-darwin12.3.0/bin/
libraries: =/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../../x86_64-apple-darwin12.3.0/lib/x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../../x86_64-apple-darwin12.3.0/lib/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../x86_64-apple-darwin12.3.0/4.8.0/:/usr/gcc-4.8.0/lib/gcc/x86_64-apple-darwin12.3.0/4.8.0/../../../:/lib/x86_64-apple-darwin12.3.0/4.8.0/:/lib/:/usr/lib/x86_64-apple-darwin12.3.0/4.8.0/:/usr/lib/
Most of the boost libraries, are just header files, if you look in the .hpp files you will not see just the declaration of the classes, like you would expect in a header file, but actually the entire implementation. This is why for 90% of the boost libraries, you don't need to worry about linking, only inclusion.
However for a few libraries, serialiser, a few others, there is just too much polluting code for the header inclusion method to be reasonable. I'm sure there is a better, more rigid definition about when the implementation is included in the header and when it isn't.
http://www.boost.org/boost-build2/doc/html/bbv2/faq/header-only-libraries.html
Here is another question about it:
Why are not all boost libraries header-only?
p.s.
Generally it is better to keep the boost library separate and in your makefile do something like:
For compilation:
CXXFLAGS += -I/path/to/boost/include
For Linking:
LDPATH += -L/path/to/boost/lib
This makes it easier to upgrade your boost version as you just have to change the path in one place.

Including Boost libraries into standard MinGW path

how can I include Boost libraries (together with its includes files) in the standard search path of MinGW so that I can just do something like this;
#include <filesystem.hpp>
using boost::filesystem;
and avoiding adding -I, -l, and -L in Makefile, just like C++ standard library?
(I'm using compiled boost 1.51.0 on Windows 7)
The way I do it (for /usr/local) I add to my globally defined CXXFLAGS. I always use MinGW in conjunction with MSys. I changed the fstab (C:\MinGW\msys\1.0\etc\fstab) to map C:\Users to /home. (That should be the default anyway.) Then I define a .profile file in my user directory that contains my "default" CFLAGS, CXXFLAGS and LDFLAGS. So in my case:
export CFLAGS=-g -Wall -I/usr/local/include
export CXXFLAGS=-g -Wall -I/usr/local/include
export LDFLAGS=/usr/local/lib
In the makefile, I then only extend the variables as needed:
LDFLAGS += -lawsomelib
This works like a charm and has the advantage that I can locally redefine CXXFLAGS in special cases. Basically you should assume in a makefile that the variables CC, CXX, CXXFLAGS, CFLAGS and LDFLAGS are already defined and contain useful stuff. This is the portable and sort of standard way to do it.
(NOTE: /usr/local is not used as standard include location in vanilla MinGW + MSys.)
By default GCC looks for C_INCLUDE_PATH and CPP_INCLUDE_PATH environment variables.
Instead of doing -I, you can add the following to your .bashrc:
export CPP_INCLUDE_PATH=/path/to/your/boost/header

Where in Qt Creator do I pass arguments to a compiler?

Where in Qt Creator do I pass arguments to a compiler?
It isn't really that obvious.
Depending on your build system it's either in your qmake project file(.pro, standard for new projects) or in one of the CMake files (CMakeLists.txt, used by KDE and several other projects).
Using .pro:
QMAKE_CXXFLAGS += -O2
Using CMake:
set( CMAKE_CXX_FLAGS "-g -Wall")
To add compiler flags, open your .pro file and add a line like this:
QMAKE_CXXFLAGS += -std=c++0x
For standard flags like debug vs. release etc. you should try to use the predefined qmake options (see QMake documentation) for the sake of platform and compiler-independency, as QMake will map them to the compiler-specific flags.
If your intention is to precompile some source code you can do like this:
/A/ In your .pro file you can add a line like this:
DEFINES += HOPLA
/B/ In you .cpp or .h file you can use it like this
#ifdef HOPLA
// Do something
#else
// Do something different
#endif
for C projects, add the following line in .pro file
QMAKE_CFLAGS += -std=c99
in the .pro file you can add variables which modify the make behavior for example, if you try to execute the following command:
g++ -Wall -I/usr/include/cppconn -o exe main.cpp -L/usr/lib -lmysqlcppconn
you must add the following lines in the .pro file
INCLUDEPATH += /usr/include/cppconn
LIBS += -L/usr/lib -lmysqlcppconn
Check the image below.
For more information on the available variables that QT IDE uses, you can visit the following link where they explain in more detail each one. Qt Documentation: Variables
As the elected answer points, for CMake based projects, you can edit the CMakeLists.txt and set the flags for the compiler, and for this case, I have a pictorial demonstration on how to add flags on QtCreator/CMake.
I wanted to add the '-pedantic' flag, which warns about extensions, without throwing errors while executing the program, and here's pictorial example of how to enable compiler flags on CMake while using QtCreator:
For more context:
On the example below, I'm setting the size of a Static Array at Runtime, something that is only possible with Variable-length Array feature, which is available at C99, but defined as optional feature starting from C11. Without -pedantic flag being available for the compiler, the warning would't be displayed after compiling the code.