g++: Compiling without -l flags - c++

Simple question- are these any way to not have to call libraries during the compiling? I mean, I would like to simply call g++ main.cpp without calling g++ main.cpp -lGL -lGLU -lGLEW -lSTL -lMyMother and so on... I know, makefiles or simple shell scripting, but I would like to make it elegant way - call these libraries inside cpp code - something like 'using GL;'.

Since you're using GCC, you could create/modify a specs file to add the flags you want.
If you don't like typing flags, you really should be using a makefile, though.

Technically you can dynamically load libraries by dlopen() and call functions from it (I am assuming you are on *nix). Though that would be not the same thing and I doubt will make your life easier. Other than that there is no portable way of specifying which library to use in source file.

On Linux you may use pkg-config and shell expansion. Use pkg-config --list-all to discover what packages are known to it (you might add a .pc file to add a new package). For instance, a GTK application mygtkapp.c could be compiled with
gcc -Wall -g $(pkg-config --cflags gtk+-x11-3.0) -c mygtkapp.c
then later linked with
gcc -g mygtkapp.o $(pkg-config --libs gtk+-x11-3.0) -o mygtkapp
Notice that order of arguments to gcc always matter. Of course use g++ to compile C++ applications with GCC.
Consider also using a Makefile like this one. Then just type make to build your software (and e.g. make clean to clean the build tree).
You might use weird tricks in your Makefile to e.g. parse with awk some comments in your C++ code to feed make but I think it is a bad idea.
Technically, you still pass -I and -D flags (at compile time) and -L and -l flags (at link time) to gcc or g++ but the pkg-config utility (or make ....) is generating these flags.
If you edit your source code with emacs you could add a comment at end of your C file to set some compilation command for emacs, see this.
PS. I don't recommend configuring your GCC spec files for such purposes.

Related

How do I permanantly add a path to the g++ compiler?

I'm currently using a non standard c++ library in my programs, but linking the library everytime I run the code is getting annoying. Right now I'm using
c++ file.cpp -o file -L/path/to/lib -lLibName
I tried the following:
CPLUS_INCLUDE_PATH=/path/to/lib
export CPLUS_INCLUDE_PATH
but it neither solved the issue nor gave me an error. What am I doing wrong?
A better option would be use a makefile and run make.
You can edit the makefile to add the necessary compiler and linker options.
GNU Make uses many implicit variables. For your use case, the contents of the Makefile can be as simple as:
CXXFLAGS = -Wall
LDFLAGS = -L/path/to/lib -lLibName

c++ shared library in custom directory is not found

I want to use a shared library (resides in a custom directory) into an executable.
I've created this makefile
all: SayHello
SayHello: compiledObjects/SayHello.o myLib/libNames.so
g++ compiledObjects/SayHello.o -o SayHello -Icommons -LmyLib -lNames
compiledObjects/SayHello.o: SayHello.cpp
g++ -c SayHello.cpp -o compiledObjects/SayHello.o
myLib/libNames.so: commons/Names.cpp commons/Names.h
g++ -shared -fPIC commons/Names.cpp -o myLib/libNames.so
That create correctly the executable and shared library infact I can Execute the program using this command
LD_LIBRARY_PATH=/custom/path/to/lib/myLib/libNames.so
./SayHello
How can I execute ./SayHello without specify LD_LIBRARY_PATH?
I'm not using any IDE and I'm on linux.
Use the -rpath option to link your executable. See the ld(1) manual page for more information.
P.S. Your makefile appears to have a bug. If you successfully make your program, and immediately run make again, looks like your makefile will attempt to recompile the program again, even though nothing has changed.
After all, the whole purpose of a makefile is to avoid doing unneeded compilations.
The SayHello.o build target should be compiledObjects/SayHello.o.
You need to tell g++ to pass the -rpath option to the linker using -Wl,-rpath. Also, you need to specify a path to the -rpath option.
Putting it all together your last build step should look like this:
SayHello: compiledObjects/SayHello.o myLib/libNames.so
g++ compiledObjects/SayHello.o -o SayHello -Icommons -LmyLib -lNames -Wl,-rpath=/custom/path/to/lib/myLib/
Relative RPATH:
If you want to specify an RPATH relative to your binary you should use
$ORIGIN as a placeholder: -rpath='$ORIGIN/rel/path'.

Add include paths and shared library for g++ permanently

I try to compile .cpp file with g++ in terminal:
g++ -o main main.cpp \
-I/usr/include/glib-2.0 \
-I/usr/include/json-glib-1.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ \
-L/usr/lib/x86_64-linux-gnu -ljson-glib-1.0 -lglib-2.0
And it works.
But I want to add these .so libraries and include files for g++ permanently so that I don't need to type these every time. And I also want to make it apply for other applications.
I am using ubuntu.
Could anyone help me out? Thank you a lot in advance.
Here is a very basic example of a Makefile using pkg-config, which you should really use with glib anyway, takes a lot of the pain away:
CXXFLAGS += $(shell pkg-config --cflags glib-2.0) $(shell pkg-config --cflags json-glib-1.0)
LIBS += $(shell pkg-config --libs glib-2.0) $(shell pkg-config --libs json-glib-1.0)
all: main
main: main.o
$(CXX) $(CXXFLAGS) main.o -o main $(LIBS)
clean:
rm -f main main.o
Might be wise to find yourself a gnu make tutorial, so that you can better understand this example.
Now instead of running your manually typed shell command, you can just do 'make'.
The best, most flexible way to do this is via a build system, using Make or CMake or something similar. But there is a serious learning curve. It may be simpler for right now to just create a script file to run the same commands that you have successfully used from the command line.
I assume you are using the bash shell. You can just edit a file -- call it "compile.bash". At the first line of the file, type "#!/bin/bash". That tells the system to interpret this file as a bash script file. Then on one or more subsequent lines, type the commands you just provided in you question, exactly as you use them previously. Save the file. Then run this command from the command line: "chmod +x compile.bash" (without the quotes). Make sure that the new file is located in the directory that you compile from, and you can just type:
"compile.bash" instead of the long command line you were using before.
Example file "compile.bash"
#!/bin/bash
g++ -o main main.cpp -I/usr/include/glib-2.0 -I/usr/include/json-glib-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -L/usr/lib/x86_64-linux-gnu -ljson-glib-1.0 -lglib-2.0
There are three different things you need to investigate further:
Environment variables affecting your compiler. Since you are using GCC, I can point out this page. In particular, you should read about:
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of
directories, much like PATH. When configured as a native compiler, GCC
tries the directories thus specified when searching for special linker
files, if it can't find them using GCC_EXEC_PREFIX. Linking using GCC
also uses these directories when searching for ordinary libraries for
the -l option (but directories specified with -L come first).
The manner in which your OS searches for shared, dynamic libraries. Since you are using Linux, I would recommend this page (discussing ldconfig).
And, most importantly:
What is a software construction tool or Makefile. For that you can refer to the Scons page, the CMake page, or the GNU Make page. Briefly, each option provides you with the means for you to describe how to build your software, and then actually building it using a simple command (scons, cmake, or make, depending on what system you chose).
So, all in all I don't have an answer to your question. I can only advice you to look into these.

Is it possible to build protobuf without pthread?

There is a need to use Protocol Buffers on the real-time OS where there is no pthread. I am able to link protobuf statically this way
g++ -g -Wall example.pb.cc example.cc -o example -static -lprotobuf -lpthread
However without pthread I get link errors. Is it possible to configure protobuf to work without pthread?
Not really. See this unresolved issue.
Someone has patched an older protobuf version to not depend on pthreads, see here - which you might take a look at if you really need it, and possibly forward port.
Also note that you're supposed to use pkg_config to get the proper compiler and linker flags when using protobuf, e.g.
pkg-config --cflags protobuf # compiler flags
pkg-config --libs protobuf # linker flags

C++, the "Old Fashioned" way

I have been learning C++ in school to create small command-line programs.
However, I have only built my projects with IDEs, including VS08 and QtCreator.
I understand the process behind building a project: compile source to object code, then link them into an executable that is platform specific (.exe, .app, etc). I also know most projects also use make to streamline the process of compiling and linking multiple source and header files.
The thing is, although IDEs do all this under the hood, making life very easy, I don't really know what is really happening, and feel that I need to get accustomed to building projects the "old fashioned way": from the command line, using the tool chain explicitly.
I know what Makefiles are, but not how to write them.
I know what gcc does, but not how to use it.
I know what the linker does, but not how to use it.
What I am looking for, is either an explanation, or link to a tutorial that explains, the workflow for a C++ project, from first writing the code up to running the produced executable.
I would really like to know the what, how, and why of building C++.
(If it makes any difference, I am running Mac OS X, with gcc 4.0.1 and make 3.81)
Thanks!
Compiling
Let's say you want to write a simple 'hello world' application. You have 3 files, hello.cpp hello-writer.cpp and hello-writer.h, the contents being
// hello-writer.h
void WriteHello(void);
// hello-writer.cpp
#include "hello-writer.h"
#include <stdio>
void WriteHello(void){
std::cout<<"Hello World"<<std::endl;
}
// hello.cpp
#include "hello-writer.h"
int main(int argc, char ** argv){
WriteHello();
}
The *.cpp files are converted to object files by g++, using the commands
g++ -c hello.cpp -o hello.o
g++ -c hello-writer.cpp -o hello-writer.o
The -c flag skips the linking for the moment. To link all the modules together requires running
g++ hello.o hello-writer.o -o hello
creating the program hello. If you need to link in any external libraries you add them to this line, eg -lm for the math library. The actual library files would look something like libm.a or libm.so, you ignore the suffix and the 'lib' part of the filename when adding the linker flag.
Makefile
To automate the build process you use a makefile, which consists of a series of rules, listing a thing to create and the files needed to create it. For instance, hello.o depends on hello.cpp and hello-writer.h, its rule is
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o # This line must begin with a tab.
If you want to read the make manual, it tells you how to use variables and automatic rules to simplify things. You should be able to just write
hello.o:hello.cpp hello-writer.h
and the rule will be created automagically. The full makefile for the hello example is
all:hello
hello:hello.o hello-writer.o
g++ hello.o hello-writer.o -o hello
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o
hello-writer.o:hello-writer.cpp hello-writer.h
g++ -c hello-writer.cpp -o hello-writer.o
Remember that indented lines must start with tabs. Not that not all rules need an actual file, the all target just says create hello. It is common for this to be the first rule in the makefile, the first being automatically created when you run make.
With all this set up you should then be able to go to a command line and run
$ make
$ ./hello
Hello World
More advanced Makefile stuff
There are also some useful variables that you can define in your makefile, which include
CXX: c++ compiler
CXXFLAGS:
Additional flags to pass to the
compiler (E.g include directories
with -I)
LDFLAGS: Additional flags to
pass to the linker
LDLIBS: Libraries
to link
CC: c compiler (also used to
link)
CPPFLAGS: preprocessor flags
Define variables using =, add to variables using +=.
The default rule to convert a .cpp file to a .o file is
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $#
where $< is the first dependancy and $# is the output file. Variables are expanded by enclosing them in $(), this rule will be run with the pattern hello.o:hello.cpp
Similarly the default linker rule is
$(CC) $(LDFLAGS) $^ -o $# $(LDLIBS)
where $^ is all of the prerequisites. This rule will be run with the pattern hello:hello.o hello-writer.o. Note that this uses the c compiler, if you don't want to override this rule and are using c++ add the library -lstdc++ to LDLIBS with the line
LDLIBS+=-lstdc++
in the makefile.
Finally, if you don't list the dependancies of a .o file make can find them itself, so a minimal makefile might be
LDFLAGS=-lstdc++
all:hello
hello:hello.o hello-writer.o
Note that this ignores the dependancy of the two files on hello-writer.h, so if the header is modified the program won't be rebuilt. If you're interested, check the -MD flag in the gcc docs for how you can automatically generate this dependancy.
Final makefile
A reasonable final makefile would be
// Makefile
CC=gcc
CXX=g++
CXXFLAGS+=-Wall -Wextra -Werror
CXXFLAGS+=-Ipath/to/headers
LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect
# (watch out for c code though!)
all:hello # default target
hello:hello.o hello-world.o # linker
hello.o:hello.cpp hello-world.h # compile a module
hello-world.o:hello-world.cpp hello-world.h # compile another module
$(CXX) $(CXXFLAGS) -c $< -o $# # command to run (same as the default rule)
# expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o
A simple example is often useful to show the basic procedure, so:
Sample gcc usage to compile C++ files:
$ g++ -c file1.cpp # compile object files
[...]
$ g++ -c file2.cpp
[...]
$ g++ -o program file1.o file2.o # link program
[...]
$ ./program # run program
To use make to do this build, the following Makefile could be used:
# main target, with dependencies, followed by build command (indented with <tab>)
program: file1.o file2.o
g++ -o program file1.o file2.o
# rules for object files, with dependencies and build commands
file1.o: file1.cpp file1.h
g++ -c file1.cpp
file2.o: file2.cpp file2.h file1.h
g++ -c file2.cpp
Sample Makefile usage:
$ make # build it
[...]
$ ./program # run it
For all the details you can look at the Gnu make manual and GCC's documentation.
I know what Makefiles are, but not how to write them.
The make syntax is horrible, but the GNU make docs aren't bad. The main syntax is:
<target> : <dependency> <dependency> <dep...>
<tab> <command>
<tab> <command>
Which defines commands to build the target from the given dependencies.
Reading docs and examples is probably how most people learn makefiles, as there are many flavors of make with their own slight differences. Download some projects (pick something known to work on your system, so you can actually try it out), look at the build system, and see how they work.
You should also try building a simple make (strip out a bunch of the harder features for your first version); I think this is one case where that will give you a much better grasp on the situation.
I know what gcc does, but not how to use it.
Again, man g++, info pages, and other documentation is useful, but the main use when you call it directly (instead of through a build system) will be:
g++ file.cpp -o name # to compile and link
g++ file.cpp other.cpp -o name # to compile multiple files and link as "name"
You can also write your own shell script (below is my ~/bin/c++ simplified) to incorporate $CXXFLAGS so you won't forget:
#!/bin/sh
g++ $CXXFLAGS "$#"
You can include any other option as well. Now you can set that environment variable ($CXXFLAGS, the standard variable for C++ flags) in your .bashrc or similar, or redefine it in a particular session, for working without a makefile (which make does do just fine, too).
Also use the -v flag to see details on what g++ does, including...
I know what the linker does, but not how to use it.
The linker is what takes the object files and links them, as I'm sure you know, but g++ -v will show you the exact command it uses. Compare gcc -v file.cpp (gcc can work with C++ files) and g++ -v file.cpp to see the difference in linker commands that often causes the first to fail, for example. Make also shows the commands as it runs them by default.
You are better off not using the linker directly, because it is much simpler to use either gcc or g++ and give them specific linker options if required.
Just to throw this out there, the complete gcc documentation can be found here: http://www.delorie.com/gnu/docs/gcc/gcc_toc.html
compiler takes a cpp and turns into an object file which contains native code and some information about that native code
a linker takes the object files and lays out an excutable using the extra information in the object file.... it finds all the references to the same things and links them up, and makes and image useful for the operating system to know how to load all the code into memory.
check out object file formats to get a better understanding of what the compiler produces
http://en.wikipedia.org/wiki/Object_file (different compilers use different formats)
also check out (for gcc)
http://pages.cs.wisc.edu/~beechung/ref/gcc-intro.html on what you type at the command line
You might also look into Autoproject, which sets up automake and autoconf files, which makes it easier for people to compile your packages on different platforms: http://packages.debian.org/unstable/devel/autoproject
I like this quirky intro to building a hello world program with gcc, Linux-based but the command-line stuff should work fine on OS/X. In particular, it walks you through making some common mistakes and seeing the error messages.
Holy Compilers, Robin, the darn thing worked!
This is what has helped me to learn the autoconf, automake, ...:
http://www.bioinf.uni-freiburg.de/~mmann/HowTo/automake.html
It is a nice tutorial progresses from a simple helloworld to more advanced structures with libraries etc.