Problems trying to compile a program with external header - c++

I'm learning c++ and I'm trying to use a library that I've downloaded from internet in my program ( from here https://mattmccutchen.net/bigint/).
Because I want everything to be quite tidy, I put all the .hh files in a subfolder named "BI".
However when I try to compile my .cpp file with g++ (It's MinGW on Windows XP SP3), the compiler outputs the following error:
J:\comp proj\FS>J:\Programmi\MinGW\bin\g++.exe "J:\comp proj\FS\test.cpp" -o "J:\comp proj\FS\test.exe" -I "J:\comp proj\FS\BI"
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text+0x2c): undefined reference to BigInteger::BigInteger(int)'
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text+0x11b): undefined reference tooperator<<(std::ostream&, BigInteger const&)'
E:\DOCUME~1\MrJackV\IMPOST~1\Temp\ccidH1Z6.o:test.cpp:(.text$ZNK10BigIntegermlERKS[BigInteger::operator*(BigInteger const&) const]+0x29): undefined reference
to `BigInteger::multiply(BigInteger const&, BigInteger const&)'
collect2: ld returned 1 exit status
I've tried using the -I, -l and -L switches to fix the problem but with no success.
Moreover I've tried in the cpp to put #include "BI/BigIntegerLibrary.hh" but that didn't work.
Is there something I'm doing wrong?
Thanks in advance.

You need to use both -L and -l switches. -L to point to the directory containing the library binary, -l to name that binary
e.g. -L/home/ed/libs -lmath

There's two keywords to keep in mind. Undeclared means the compiler has never heard of it. Undefined means the compiler has heard of it, but doesn't know exactly how to use it. For those errors you need to tell it to link with the BigInteger library that should have come with the headers (A *.lib file) I'm hot sure exactly how gcc includes link libraries (Ed Heal says -L and -l, I'd do that).

Your problem is that you didn't link with the library code.
Read the "README", then follow its advice to adapt the enclosed Makefile.

Ok, so after some messing around I figured out that I needed to do a couple of things
add the -L switch with the dir of the header files
add to the g++ command line all the .cc files (e.g. g++ test.cpp BigInteger.cc etc.)
put everything in a batch file for semplicity
wow, now it seems quite easy!

Related

How to correctly Install ImGui?

I am very new to c++ but i know a couple other languages (ie. python, java, a little C). The problem is when i compile my code and try to open a new ImGui window it gives a "undefined reference" error. I think it is a problem with how i the setup the files. both my main.cpp file and the imgui library are in the same directory and when i try to import the file by using "#include "imgui/imgui.h" " it still gives my the undefined reference error. I have tried to pull all the .h and .cpp files out of the imgui folder and into the same directory as my "Main.cpp" file but it still gives me a undefined reference error. I have read the install instructions where you put the .cpp files into the working directory and it still didn't work and gave me the same error. Any help would be appreciated.
--------------------------------------------MyCode--------------------------------------------
#include <iostream>
using namespace std;
#include "imgui/imgui.h"
int main(){
ImGui::Begin("Window");
ImGui::End();
}
---------------------------------------------Output---------------------------------------------
/tmp/ccMXHI3r.o: In function `main':
Main.cpp:(.text+0x16): undefined reference to `ImGui::Begin(char const*, bool*, int)'
collect2: error: ld returned 1 exit status
-------------------------------my working directory-----------------------
imgui // imgui library folder that i downloaded from github
Main.cpp // my cpp file where my code is
The problem seem to be a missing linking step, you need to tell your compilation/linking process to link to imgui library.
When you include a header in C/C++ you are just letting the compiler to know the signatures of functions and other declarations.
Then you need to let your linker know where to look for the code, and that will be telling it to link to the library.
For example with gcc you can make a compilation + linking with the following call:
gcc foo.c -o foo -ldynLib
that example will compile the source code 'foo.c', will generate an object for that and it will link it with the dynamic library 'dynlib' into the final binary 'foo' (the executable).
in your case it could be something like this:
gcc Main.cpp -o program -limgui
Of course flags and steps will depend on your compiler / linker, also you should check the actual name of the library (imgui is just a guess, as I don't know that library)

What dependencies does gmp's libgmp.so have? I keep getting undefined references

I am trying to get gmp working so I can use large integers. I've compiled it ok but when I try to compile my code with it I keep getting errors such as:
.../libgmp.so: undefined reference to `__gmpn_sublsh2_n'
My compile line is,
g++ -g -std=c++11 -I ../gmp-6.1.2 test.cpp -L../gmp-6.1.2/.libs -lgmp -lgmpxx
libgmpxx.so is definitely in the specified lib directory.
I can't find any references to similar problems or any reference in the docs to dependencies for libgmp.so (shouldn't it be linking with libgmpxx.so?).
I'm sure I've missed something obvious and will feel the fool when someone points it out, but at the moment I'm losing it.
Thank you guys, I seem to have found the problem. You got me thinking about the location of libgmpxx.so. I copied it into /usr/local where I found libgmp.so and adjusted my library paths (-L) and hey presto! Clearly the undefined references are defined in libgmp.so upon which libgmpxx.so depends and could not find in the directory where it lived (.libs) or in the search path.
Thanks again.

Zlib linking problems

I'm using CodeBlocks (the latest version, I'm not sure what that is at the moment)
I'm trying to use fallahn's SFML Tiled map loader, and so far I've successfully statically linked SFML and included the map loader files in my source as well as added it to my search directories, however, I'm having trouble linking zlib (which the map loader uses)
I'm gonna go ahead and walk you through how I linked zlib because I'm not even sure which step I messed up on:
obviously, I went on over to http://zlib.net and grabbed the latest version (1.2.8)
I unzipped it to my desktop
I went into my project's build options and initially i thought "I'll just globally set up my search directories like before" (for SFML and the map loader, there was an 'include' and 'lib' folder, i put 'include' in the compiler search directory, and 'lib' in the linker search directory), except there were no folders named 'include' or 'lib' in the folder that i got from unzipping. This is where I simply included the whole folder I unzipped (I'm pretty sure that's terrible practice but I wasn't sure what else to do)
I compiled an example from the Map loader's source files, and got an error along the lines of 'undefined reference to inflate' on 4 different occasions. I already figured at this point that I made an error while linking, so that's when I took to google. Most answers were simply "add -lz" or "link libz"
Well, I don't know what "add -lz" means.. like at all, so I just linked "libz", then my compiler gave me the error "ld.exe cannot find -lz", which led me to the assumption that linking libz and adding -lz are the same thing.
Here are some things I don't understand at all, and if you can't explain what they are, please at least explain how to blindly do it:
1. Compiling a library
2. Anything to do with make files, I don't know what they are or what they do at all
3. Adding commands to the project command-line.
Build messages:
C:/Documents and Settings/Brenda/Desktop/sfml-tmxloader-master/src/MapLoaderPrivate.cpp:834: undefined reference to inflateInit2_'
C:/Documents and Settings/Brenda/Desktop/sfml-tmxloader-master/src/MapLoaderPrivate.cpp:843: undefined reference toinflate'
C:/Documents and Settings/Brenda/Desktop/sfml-tmxloader-master/src/MapLoaderPrivate.cpp:852: undefined reference to inflateEnd'
C:/Documents and Settings/Brenda/Desktop/sfml-tmxloader-master/src/MapLoaderPrivate.cpp:881: undefined reference toinflateEnd'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 10 seconds)
4 errors, 0 warnings (0 minutes, 10 seconds)
The issue is, that zlib doesn't provide binaries for MinGW directly, they only provide *.lib, *.def and *.dll files, but in order to link with MinGW/GCC, you'll need an *.a file.
Since zlib is a C library the ABI will be identical and thus you can "simply" convert it, for instance with the help of lib2a. While this should work, it might still be better to download the source code and build zlib yourself, since it ships with a CMake file, it's rather easy to build.

Trouble including third-party code in my C++ application

I'm trying to include some networking code into my C++ application. I downloaded CSimpleSocket and I copied all the .h and .cpp files into the directory where my main file is. Then I tried including one of the headers, but the linker just barfs up a bunch of errors, like:
[Linker error] undefined reference to CPassiveSocket::CPassiveSocket(CSimpleSocket::CSocketType)'
[Linker error] undefined reference to `CSimpleSocket::Initialize()'
[Linker error] undefined reference to `CPassiveSocket::Listen(unsigned char const*, short, int)'
[Linker error] undefined reference to `CPassiveSocket::Accept()'
and others. Everything is in one directory, so I don't think that's the problem. The code I'm using to include is #include "PassiveSocket.h". I'm using Dev-C++, if that makes any difference. I don't understand what I'm doing wrong, so if somebody could help me, that would be great.
Forgive me if this is a really dumb question, but I'm trying to learn C++, and it's not easy. Thanks for your help.
The reason you're getting this error is because your compiler can't find the binary that corresponds to the CSimpleSocket headers. It's as if you wrote
void someFunction(int someArg);
And then never provided the implementation for someFunction.
To use a third party library you need two things:
Header files (.h, .hpp, etc...)
Library files (.a, .lib, etc...)
Once you've got your header files and library files you need to put them in a place your compiler can find them. This place will vary depending on your OS, environment variables and compiler configuration.
Now that they're somewhere the compiler can find them you need to tell the compiler to use them. Header files are used with the #include command and library files are linked by providing arguments to the compiler.
Behind the scenes Dev-C++ uses the MinGW GNU GCC compiler, it invokes a command similar to g++ file1.cpp file2.cpp ... filen.cpp -o filename that tells the program g++ to compile a C++ executable named "filename" using files 1 to n. There are other flags that can be added to g++ such as telling it where to search and what to link.
The name of the CSimpleSocket library when compiled is "clsocket" so we need to find a way to configure Dev-C++ to add -lclsocket to the g++ command. I don't use Dev-C++ so I can't help you here but you're probably looking for "Linking Options" or something similar in your compile configuration. You also need to make sure the .lib and .h files are on the search path which should also be configurable in Dev-C++.
CSimpleSocket also provides an installer that should automatically create the .lib file and place the .lib and .h in places where they can be found, you should consider using that installer.
I think the complexity of this answer highlights the abysmal state of the C++ library integration ecosystem. Unfortunately there is no concept of a "module" in C++ at the time of writing.

Using library files in Linux

I'm trying to use some of the functions that are in the /lib/libproc-3.2.6.so library in my Ubuntu distribution.
I have downloaded and installed the header files and they are defined in my source files.
Currently, this is all I'm trying to do, just for starters...
proc_t **read_proc = readproctab(0);
But I get the following compiler error:
/tmp/cclqMImG.o: In function `Sysmon::initialise_sysmon()':
sysmon.cpp:(.text+0x494): undefined reference to `readproctab'
collect2: ld returned 1 exit status
I'm aware I'm probably doing some wrong with the command I'm using to compile it, but due to lack of experience I'm not sure what I'm doing wrong. This is the g++ command I'm using to compile my cpp file:
g++ -o sysmon.o sysmon.cpp `pkg-config --libs --cflags gtk+-2.0`
Can someone please give me some pointers as to where I'm going wrong.
You are not linking your executable against libproc (that is a linker error message).
Try adding -lproc to the linker command.
You are not actually linking against the library that you wish to use, you are merely including its header files, therefor, the compiler will complain about undefined references.
You can read up on linking against shared libraries here.
A small suggestion, start using the build tool SCons, it can take care of linking to libraries for you, just add the ones you wish to use in the SConstruct file required by SCons and then you don't have to mess about with compiler specifics. You also gain lots of other good stuff that SCons provide. It's highly recommended.
Ubuntu 17.04
You probably want to use -lprocps instead of -lproc.