g++ include files in other directories - c++

I have a main.cpp file in a directory called test that has an
#include "INIReader.h"
The structure of the files is like below
---/test/main.cpp
---/inih/ini.h
ini.c
---/inih/cpp/INIReader.h
INIReader.cpp
INIReader.cpp has these includes
#include "../ini.h"
#include "INIReader.h"
I am trying to compile main.cpp in one line with
g++ -o test -Wall -I../inih/cpp main.cpp
but it is not working. Errors like
> Undefined symbols for architecture x86_64:
>... REFERENCES TO stuff in INIReader ...
>ld: symbol(s) not found
> for architecture x86_64 clang: error: linker command failed with exit
> code 1 (use -v to see invocation)
show up.
Right now I am compiling by running the commands and it will work.
> g++ -c -Wall ../inih/cpp/INIReader.cpp
> g++ -c -Wall ../inih/ini.c
> g++ -c -Wall -I../inih/cpp main.cpp
> g++ -o configtest main.o INIReader.o ini.o
I thought that the g++ compiler will look for each #include in each of the default include directories and the passed -I directory and do not know why the above one liner does not work. Will g++ "follow" includes in all files like the ./ini.h? I have not been able to find a good resource for learning this.
How can I combine these command into one line like the previous command? Thanks.
Edit:
I have looked at the "duplicate" question but not understand how it relates to my problem. I am trying to find a good resource for learning how to "include" correctly with g++ and know why my current one liner does not work.
It is not a problem in the code, as compiling and then linking one by one is successful!
Duplicate question was similar, but did not cover including files in other directories.

The error you are getting is coming from the linker step, not the compiler step. It doesn't have anything to do with your includes. You need to tell the linker all the files required to make the target binary. As has been said in this answer, which may be the question this was previously closed as a duplicate of, you just need to list all of the cpp files after main in the command line. So for yours, the command line should be something like:
g++ -o configtest -Wall -I../inih/cpp main.cpp ../inih/cpp/INIReader.cpp ../inih/ini.c
Once you start compiling all of the files in one step, you may have to add an extra include instruction to find header files in different paths, so your command line might need to be:
g++ -o configtest -Wall -I../inih/cpp -I../inih main.cpp ../inih/cpp/INIReader.cpp ../inih/ini.c
But that depends how you're including your headers from your source files...

Related

C++ makefile does not compile

Apologies for such a beginner question, but I have been stuck on making Makefile work on my c++ files for quite a while
My makefile contains two .cpp files and one .h files and are as follows
example.o: example.cpp example.h
g++ -c example.cpp
main.o: main.cpp example.h
g++ -c main.cpp
main: main.o example.o
g++ main.o example.o -o main
and it outputs the following error when I try to make main
Undefined symbols for architecture x86_64: *(with large pieces of code)*
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
However, it works perfectly fine when I just do a compilation of the program by using
g++ main.cpp example.cpp -o main
Is there any reason why Makefile doesn't work but just compiling works? Thanks a lot for any replies!
Please show the output of make including the compiler lines that were invoked, not just some of the error output. Also it would be helpful if you provided at least SOME of the symbols that were not found so we could get an idea of what is missing.
There is no reason from the info you've provided why this should happen, so the cause must be related to some detail that you haven't provided.
One difference between the command line and the makefile is that the makefile builds object files then turns them into an executable, while the command line simply compiles the sources directly into an executable.
Maybe you have some .o files lying around from a different compilation? If you use rm -f *.o before you run make do you still see the same errors?
Also, it's a little odd that you're invoking g++ but the error output says clang which is a completely different compiler. Are you trying to build on MacOS? You should always provide your operating system info. If you're building on MacOS you should just use clang directly, unless you've explicitly install GCC and want to use that.

How to use libraries and headers in C++ with MinGW?

I want to use OpenGL GLEW library. I have the binary downloaded and its folder is in the folder with my .cpp file. My .cpp file uses #include <eglew.h>.
How should I format my command for MinGW to compile my .cpp file? Do I compile with the .lib file like g++ -L./path/to/lib/file.lib test.cpp -o test or do I do something else like link to the header files g++ -I./path/to/headers test.cpp -o test?
To better understand things maybe it's better to split compiling and linking steps.
If you get errors then you will also know in which step the problem occurs.
I'm assuming you have the following folders/files:
/path/to/eglew/include/GL/eglew.h
/path/to/eglew/lib/libglew32.a
Compiling:
g++ -Wall -c -o test.o test.cpp -I/path/to/eglew/include/GL
Linking:
g++ -o test.exe test.o -L/path/to/eglew/lib -lglew32
Though I would expect to see #include <GL/eglew.h> in which case the linker include flag should be -I/path/to/eglew/include.

C++ file compiling: -L and -I arguments don't work for boost library

There are similar questions but their answers did not work for my issue.
I have a c++ program with #include <boost/test/unit_test.hpp> on top (among other includes).
To compile correctly, if I understood, I should do the command:
g++ -g -L/path_to_boost_lib -lboost_lib myprog.cpp -o myprog.exe
If i do a locate, I get /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.
Hence I edited my call to g++ by doing:
g++ -g -L/usr/lib/x86_64-linux-gnu -lboost_unit_test_framework myprog.cpp -o myprog.exe
But I still get errors of the type undefined reference to boost::unit_test.
I also tried the option -I/usr/include/ which contains the boost folder, without success.
It's because of the order. The GCC linker goes through the artifacts left-to-right, and every unknown symbol it encounters in an object file must be resolved by an artifact occurring afterwards.
The right command is thus:
g++ -g myprog.cpp -L/usr/lib/x86_64-linux-gnu -lboost_unit_test_framework -o myprog.exe
See this answer for a more thorough explanation.
I suggest using a build tool like CMake that takes care of such low-level details for you.

Why am I getting "undefined reference to main"

I am a very new to programming and have a very basic question that may be answered in other threads however I think they are far too advanced for me to understand how. I have actually found many answers so far on this site but this is the first problem that forced me to create an account and ask.
Anyway i am running a very basic example program on linux mint 18.3. Now I have seen this exact code work on a machine with windows 8 I believe so I was wondering if that could be the problem. I have created a class and when i plug in my object then build and run I get:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o||In function _start':|
(.text+0x20)||undefined reference tomain'|
This is the entire code:
#include <iostream>
#include "Gladius.h"
using namespace std;
int main()
{
Gladius io;
return 0;
}
Thats it very basic. here is the .h
#ifndef GLADIUS_H
#define GLADIUS_H
class Gladius
{
public:
Gladius();
};
#endif // GLADIUS_H
and the .cpp for the class.
#include "Gladius.h"
#include <iostream>
using namespace std;
Gladius::Gladius()
{
cout << "The Gladius is a short sword" << endl;
}
I know this seems extremely simple but I am just learning to code and i have been looking all over for an explanation why this isn't working yet I see it work on another pc exactly as is. Anyway any explanation would be greatly appreciated.
Here is what i found in command line If this answers your questions about what was in the cmd.
g++ -Wall -fexceptions -g -std=c++11 -Wall -I -c /home/gator/Documents/Spartan1/Gladius.cpp -o obj/Debug/Gladius.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference tomain'
collect2: error: ld returned 1 exit status
Know the compiler options(gcc/g++ compiler):
-c : Compile and assemble, but do not link
-o file : Place the output into file
So when you run
g++ filename.cpp -o executable_name
, you generate an application which can be executed.
The problem is you are compiling, assembling as well as linking when you are trying to compile "Gladius.cpp" and compiler is trying to search for main() definition.
So in your case, the compilation steps would be:
First compile "Gladius.cpp" and generate object file "Gladius.o":
g++ -Wall -fexceptions -g -std=c++11 -c Gladius.cpp
Next compile "main.cpp" and generate object file "main.o":
g++ -Wall -fexceptions -g -std=c++11 -c main.cpp
Generate executable by linking "main.o" and "Gladius.o"
g++ -Wall -fexceptions -g -std=c++11 -o main main.o Gladius.o
Now you can run "main":
./main
Your compiler's command line contains -I -c sequence.
This -I option "swallows" your -c option. -I requires an additional argument, which is an include directory name. You failed to supply that argument, which is why -I assumes that -c that follows it is the directory name. So that -I consumes that -c.
The compiler never sees that -c. Without -c it assumes that you want to compile and link your program. Since Gladius.cpp does not have main in it, you get the error at linking stage.
Here 's a simple demo of the same problem: http://coliru.stacked-crooked.com/a/8a37cd3e90a443e2
You need to figure out why you have an orphaned -I in your command line.
If you are compiling this code using a command line like:
g++ -Wall -Wextra -Werror -O gladius.cpp -o output.exe
then make sure that you include all the .cpp files (not .h files) that contain code that your program needs.
g++ -Wall -Wextra -Werror -O gladius.cpp main.cpp -o output.exe
I explain this to beginners all the time as each .cpp being a bag of Lego's in a kit. You need all the bags that came with the box in order to build the kit. If you omitted main.cpp (or the file that contains main) then you will get the linker error that you are currently getting.
What command are you using to compile, link, and then execute? It should look something like
$ g++ main.cpp gladius.cpp -odemo
$ ./demo
check your command line for linking step.. You may forgot file with main as input, or you had forgot output file name after -o (and masked main.o in result)
I had this very kind of problem myself, and though it may not be the conventional, "proper" solution, I simply renamed the ".c" file to ".cpp", and it all worked.
After all, I was compiling both c and c++ together with a c++ compiler (recommended by the library), and the c code already had the proper c++ #extern flags (see here for more on that).
Also related:
C++ Error: undefined reference to `main'
Including C Code in C++
Why do you need an explicit `-lm` compiler option
Compilation on Linux - In function '_start': (.text+0x20): undefined reference to 'main'

Geany, g++ and SDL errors in compilation

So, I was following a simple C++ with SDL tutorial for linux but i encounter some errors on my way.
First of all I'm using Geany and i downloaded the corresponding SDL2 libs, here is the thing:
in my project folder there is a main.cxx file, which i open with geany as i mentioned before:
I included this libraries:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
First i encountered a pelculiar error, compilation performs sucessfully but when it comes to build i got this error:
main.cxx: undefined reference to `SDL_Init'
After searching a bit i found out that i had to add the tag -lSDL to my geany build options so they would end up being somethinf like this:
Compile:
g++ -Wall -c -lSDL "%f"
Build:
g++ -Wall -o -lSDL "%e" "%f"
But there is a problem, now when I execute the build command i get a:
G ++: error: main: There is no such file or directory
Why am i getting this error, am I including a wrong library or g++ has problems with .cxx files?
I already tried converting between .cxx and .cpp.
Thanks in advance.
g++ -Wall -c -lSDL2 "%f"
There is absolutely no need to specify libraries during compilation phase. Remove -lSDL.
g++ -Wall -o -lSDL2 "%e" "%f"
It invokes compiler, implies linking (no -c or other operation-specific flags), and sets output file name to -lSDL2. That is, linker will output resulting binary in a file named -lSDL2 in current working directory. Then, when it comes what files to link, it goes main, which supposed to be -o main, but since you've broken flags order it is now just ordinary file name that linker will try to link into resulting binary. It so happens that this file doesn't exist.
Long story short, make correct linking line - g++ -o "%e" %f -lSDL2 (libraries comes last, library order is also important).