This question has probally been answered countless numbers of times - there have been simular questions which I've read about but I just still don't understand it.
I have the sources to the libaiml project - a C++ interrepter for aiml a specification for a chatterbox program.
Within the source of the example program, it contains an #include call to a header file :
#include "../src/aiml.h"
the header file is there, I compiled and linked the program and it states that the header file can't be found.
Various of answers state that the header file needs to be compiled into a static library (a .a file) but how would the program reference the .h file when it's not compiled into the library binary?
Also I tried to compile the srcs into a library with G++ and ar , but it contains alot of errors.
Am I doing anything wrong?
Am I doing anything wrong?
Yes: you completely mis-stated what actually happens to you. You said "it states that the header file can't be found", and "I compiled and linked the program".
But what's really happening is that you've compiled and failed to link the program, and the errors have nothing to do with the header file; rather you are getting missing symbols at link time.
To fix your problem, you must link the libaiml library to your executable (this library should have been built when you built in the ../src/ directory. Something like this should work:
g++ -I../src -o program program.cc -L../src -laiml
Related
I have a library that consists of some .c modules and some .cpp modules. I assume that's fine when the library is linked into a C++ main program. But when I attempt to link that library into a C program, I get linker errors for 'standard C++ library' modules.
gcc -o PSEQ.app -Xlinker --allow-shlib-undefined pseq.app.o -L../librep -lrep
..librep/ssuinventbean.cpp:62: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
The program in question is not written in C++ - and it does not reference the ssuinventbean.cpp module. I asked a similar question about unreferenced shared library modules complaining about stuff called from there, and was told that the --allow-shlib-undefined linker flag could be used to get around that. I tried using that flag in the gcc command above, but obviously it doesn't work as advertised when the library in question is a statically linked library.
Normally, that wouldn't be a problem. I can make sure that all the modules in my application libraries have all of their references satisfied. But in this case, the reference is to the standard C++ library, which I assume would've been included if the main module of the program in question were in C++. So, catch-22? Can I not have C++ code in a library if that library will be linked against a non-C++ app - even if the .cpp module in question is never referenced? Do I have to segregate all C++ library code into its own .a files to be included only when building apps that call that code?
I found out what was causing this. It turned out that somebody had put a variable definition into a .h file that was pulled into this .cpp file. I guess it's undefined what the compiler will do with a global variable in a .h file (it could end up getting defined in multiple .c or .cpp files that pull it in).
Anyway the .cpp file in question apparently pulled in that .h file as extern "C" code, which caused something else to pull in the .cpp module (presumably to pick up the global variable). After I commented out the global variable in the .h file, the app was able to build with gcc instead of g++ on the linker line in my makefile. Problem solved.
It turns out that the link maps generated in linux by these flags are very useful. Told me that the global variable was what caused the otherwise unreferenced .cpp module to be included...
MAPFLAGS = -Xlinker --cref -Xlinker -Map=MAP
This is my first stab at C++, also I know that the question is broad but I have a specific example that I'm working with so hopefully that will narrow everything down a bit.
I'm basically attempting to compile a C++ game manually in Linux (Ubuntu 14.04). The source code I am attempting to compile is located in this directory: https://github.com/akadmc/SmashBattle/tree/master/battle.
I'm CD'ing into the battle directory and, perhaps naively running
gcc *.cpp
I started seeing multiple issues as such:
compilation terminated.HealthPowerUp.cpp:1:21:
fatal error: SDL/SDL.h: No such file or directory #include "SDL/SDL.h"
and
compilation terminated.LaserBeamPowerUp.cpp:1:21:
fatal error: SDL/SDL.h: No such file or directory #include <SDL/SDL.h>
After researching header file includes I concluded that includes without <>'s are basically just relative paths to include a header file, and that when they are wrapped in <>'s they can either lookup the file through a listing of directories specified in an enviornment variable, or a command line option.
So my first question is, is there any reason the developer used
#include "SDL/SDL.h
AND
#include <SDL/SDL.h>
in different files? There was no SDL directory in the source code...
After realizing that SDL was missing from the source code / environment in one way or another I did tinkering. I was pretty confused (and still am) because I downloaded the SDL source files, didn't see any header files, ended up building a version of SDL by using cmake, and then build. I realized afterwards that I just made a local executable and didn't yield any header files. Then I realized that I just needed the development library, downloaded that, and put higher in the directory tree and then included it at compile with
c++ *.cpp -I $HOME/Desktop/smashProject/source/
Afterwards, the previous header file errors went away - but I started getting errors like the following:
Text.cpp:(.text+0x17): undefined reference to `SDL_RWFromFile'
Text.cpp:(.text+0x24): undefined reference to `SDL_LoadBMP_RW'
Text.cpp:(.text+0x34): undefined reference to `SDL_DisplayFormat'
And so on. Am I generally headed in the right path or do I have some misunderstanding about compiling, including development libraries, etc? Also I've read the the order of the compilation matters, and I'm not using any order + the developer didn't put a makefile in the source code or anything. I'm generally just confused as to how I should be doing this. Any help would be greatly appreciated.
Yes, you are on the right track. However, now you need to have a linkage to the SDL libraries. The -I just includes an extra library path but you have to actually link your assembly to the SDL files.
See this stack overflow question for more information.
How to compile an example SDL program written in C?
I'm using code blocks IDE and GNU GCC compiler. when i create a simple program like e.g. add.cpp (for adding two number) it usually creates two file add.exe (executing file) add.o(object file) according to some of them add.o is linked to add.exe while executing.
my question is i deleted the add.o still the add.exe is executing and still producing the required results. how this is possible if the object file is missing ?? and please also explain me what object file really does ??
The object file is linked at compilation time... The object file is then redundant post all the compilation. The o files are maintained between builds so you don't need to rebuild unchanged parts of your application.
From source to executable (in a really oversimplified sort of way):
1) The pre-processor gathers the #include'd files for each .cpp in turn, runs macros, etc, and produces a "translation unit" for each file. These contain all the includes, and the macros have been evaluated: it's otherwise recognisable as source code.
2) The compiler runs over each translation unit, and turns the source into machine-instructions in "object files". These object files contain references (called "symbols") to the functions and variables it has defined, and those that are mentioned but never defined.
3) The linker grabs all the object files, and matches up the symbols across different object files. It then produces an executable.
You can freely run your executable without either the source or object files: these were read in order to produce the next step. Object files are left behind because usually you don't need to rebuild everything each time you press compile: if you only changed one source file, you only need build one new object file, and one new executable.
Files .o are not linked to exe at runtime, they are linked to it at compile time (specifically, during the linking step). Once you have an executable, you can safely remove all object files that were linked into it. It is also OK to remove all static libraries that were statically linked into the exe, because their content becomes part of the executable.
the object file contain the result of the compilation. the exe file contain the result of the link. You can delete the o file if you want exe still working
There are 2 types of linking: static and dynamic. When you compile something the compiler produces object files which are linked statically into your executable. Only if you use an external library and only if you link dynamically against it will you need to have access to it.
The .o file is used for compiling, the .exe. Where the .o is an compiled object code to be later used to compile other programs.
Where as the .exe is the compiled file, and does not require .o.
Given compiling:
g++ -c Hello.cpp -o Hello.o
g++ Hello.o main.cpp -o mainprogram.exe
The first line, creates a .o file but does not do external linking. The second line uses this .o and .cpp file and links your program together.
The only files you require for a program to function that are not in .exe are .so files or .a which are shared and static libraries respectively.
For object file this may help http://en.wikipedia.org/wiki/Object_file
I have a bit of an issue in static linking. I have a static library (libkells.lib) which is made up of a header file containing function declarations and a .cpp file containing the function implementations. I successfully compiled the two into an .o file and then built the static library out of them.
Then I have a file mcmd.cpp which calls the functions in the .lib file. I have included the header file involved in the static library into this mcmd.cpp file. This file (mcmd.cpp) successfully compiles into an .o file but when I try to build it into an executable file, my compiler returns a message like this:
libkells.lib(libkells.o): In function ZNKSt13move_iteratorIPSsE4baseEv
. Undefined reference to __cxa_end_catch, Undefined reference to
__cxa_begin_catch
and so many other errors. When I look keenly at these error messages, these errors seem to originate from some header file called include/c++/bits/stl_iterator.h. I'm using mingw 4.7.1 on Windows. What is it that I'm not doing right?
You are not linking against libstdc++ or not using g++, in short the 'gcc' driver, being the C driver, not the C++ driver, doesn't link the C++ runtime at the end. If you want, you can explicitly add -lstdc++ to the command line, or, definitely the first choice in general, just use 'g++'
quick question.
I am trying to get C++ nailed down, and today I spent hours with a double definition linker error("this has already been defined!") and I finally realised it's because I had the layout as such:
main.cpp
#include Dog.cpp
Dog.cpp
#include Dog.h
Dog.h
// (Dog class and prototype of test function)
And now that I've cleared that up by including the Dog.h instead of the Dog.cpp in the main.cpp.
By including the .h file, does the .cpp file with the identical prefix get compiled with the program?
I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp. I spent ages Googling but no answers really helped me understand what was going on.
Edit: I forgot to add that I prototyped in the .h, and defined the function for the class in the .cpp and that's what gave me the "already defined" error.
By including the .h file, does the .cpp file with the identical prefix get compiled with the program? I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp.
No.
Your program is built in phases.
For the compilation phase, only declarations are needed in each translation unit (roughly equivalent to a single .cpp file with #includes resolved). The reason that declarations even exist in the first place is as a kind of "promise" that the full function definition will be found later.
g++ -c Dog.cpp # produces `Dog.o`
g++ -c main.cpp # produces `main.o`
For the linking phase, symbols are resolved between translation units. You must be linking together the result of compiling Dog.cpp and of compiling main.cpp (perhaps your IDE is doing this for you?), and this link process finds all the correct function definitions between them to produce the final executable.
g++ Dog.o main.o -o program # produces executable `program`
(Either that, or you actually haven't got to the link phase yet, and merely have an object file (Dog.o); you can't execute it, partially because it doesn't have all the function definitions in.)
The two phases can be done at the same time, with the "shorthand":
g++ Dog.cpp main.cpp -o program # compiles, links and produces executable
No, the .cpp file does NOT automatically get compiled. You can either do that manually, create a makefile, or use an IDE that has both of them in the same project.
You don't specify how you are compiling it. If you are using an IDE and have a new .h and .cpp to the project automatically then it will all be compiled and linked automatically.
There are 2 stages to making an executable to run: compiling and linking. Compiling is where the code gets interpretted and translated into lower level code. Linking is where all of the functions that you used get resolved. This is where you got the duplicate function error.
Inclusion does not automatically cause compilation, no.
In fact, the actual compiler never sees the #include statement at all. It's removed by an earlier step (called the preprocessor).
I'm not sure how it could build if you never compiled the Dog.cpp file. Did you reference any objects with code defined in that file?