Codelite linker undefined reference error - c++

I'm new to codelite and c++. I'm using Linux and the g++ compiler. I've set up a simple project with two source files just to play around with linker errors. The files look like so:
Main.cpp:
#include <iostream>
void Log(const char*);
static int Multiply (int a, int b)
{
Log("Multiply");
return a * b;
}
int main()
{
std::cout << Multiply(5, 8) << std::endl;
std::cin.get();
}
Log.cpp:
#include <iostream>
void Log(const char* message)
{
std::cout << message << std::endl;
}
As you can see, Log.cpp simply specifies a function called in main. Both files are in the same directory, "src". So far all my settings are pretty much default, still I get an "undefined reference to `Log(..." error when I try to build this project.
Also, if I comment out the declaration of the Log function at the top of main.cpp, I would expect a compilation error since an undeclared function being called. Yet if I try to compile main.cpp I get no errors.
This is what my workspace looks like
Project settings
Compiler settings
Linker settings
Am I correct to expect the behaviors described above? Is there some setting I have to manually configure?

Related

Pybind11 - Where to put PYBIND11_MODULE

Im currently playing around with pybind11 a bit. Im trying to create a C++ class which then gets passed to a python interpreter embedded in my C++ source.
I created some dummy class just to test the basic functionality I kept everything in a single source file. This approach compiled and ran without any problems.
Now I separated my dummy Class Test into a Test.h and Test.cpp
Test.h
#pragma once
#include<iostream>
#include"pybind11\pybind11.h"
namespace py = pybind11;
class Test
{
public:
Test(const std::string &s);
~Test();
void printStr();
private:
std::string _s;
};
Test.cpp
#include "Test.h"
PYBIND11_MODULE(TestModule, m)
{
py::class_<Test>(m, "Test")
.def(py::init<const std::string &>())
.def("printStr", &Test::printStr);
}
Test::Test(const std::string &s) : _s(s)
{
}
Test::~Test()
{
}
void Test::printStr()
{
std::cout << "---> " << _s << std::endl;
}
main.cpp
#include"Test.h"
int main(int argc, char **argv)
{
PyImport_AppendInittab("TestModule", PyInit_TestModule);
Py_Initialize();
PyRun_SimpleString("import TestModule");
PyRun_SimpleString("t = TestModule.Test(\"str\")");
PyRun_SimpleString("t.printStr()");
Py_Finalize();
getchar();
return 1;
}
After putting the Class Test into a new file the Compiler cannot find the PyInit_TestModule (main.cpp line: 6) anymore since this is generated by the PYBIND11_MODULE Macro which lives in the Test.cpp file(MSVS2017 Error: C2065).
I tried putting the PYBIND11_MODULE Macro into the Test.h. This however resulted in a linker error which said that "_PyInit_TestModule" is already defined in main.obj (MSVS2017 Error: LNK2005)
Putting the PYBIND11_MODULE Macro in the main.cpp file works.
However I feel like this will become quite unreadable as soon as you put a lot of custom Module definitions into main.cpp or even worse you have multiple Python-Interpreter being started from different source files where you then
need to put the same definition in all those files which will be a mess and most likely turn into a linker error.
Has one of you faced the same Problem and how did you solve it?
I created a file of his own for the bindings, and compiled/linked it together with the original c++ file. This way:
1) Test.h + Test.cpp contain only c++ code of your class
2) Test-bindings.cpp contains the PYBIND11_MODULE and #include <Test.h>
3) Building (with cmake). You will get a PyTest.so file out of it, that you can load in python.
# c++ libray
add_library(TestLib SHARED /path/to/Test.h /path/to/Test.cpp)
# bindings
add_subdirectory(pybind11) # you must have downloaded this repo
include_directories(/path-only/to/Test.h)
pybind11_add_module(PyTest SHARED /path/to/Test-bindings.cpp /path/to/Test.cpp)
4) (I suggest you to) write the main in python, using the python-binding you just created
5) In your main.py
import PyTest
# do something

How c++ includes all functions in specific file without any inclusion of that file?

I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.

Including STL in static libraries

I have created a static library with the files alien.h and alien.cpp below. That library is linked by the file user.cpp. If one removes the line with the comment, then the code compiles, links, and runs as expected. As it is, the library and the program compile, the program however does not link. MSVC2015RC generates over 100 errors about std::numeric_limits being already defined.
Is there some setting that I should be aware of or is this a MSVC2015 bug?
File alien.h
#include <vector> // This line causes troubles.
struct alien
{
const int * const value;
};
extern alien meh;
File alien.cpp
alien meh { 7 };
File user.cpp
#include "alien.h"
#include <iostream>
#pragma comment(lib, "alien.lib")
int main()
{
wcout << meh.value;
return 0;
}
Error LNK2005 "public: static int const std::numeric_limits::max_exponent" (?max_exponent#?$numeric_limits#M#std##2HB) already defined in alien.obj
It is a bug! The same library/program compiles under MSVC2013 without language extensions enabled. In MSVC2015, language extensions must be enabled.

C++ Linker Error (Unresolved External) when linking to /clr DLL

I have a DLL with the /clr option ON. I have the following declaration in my DLL:
int __declspec(dllexport) __cdecl test();
Also, I have a console with /clr option ON. And have the following declaration on my main.cpp file:
int __declspec(dllimport) __cdecl test();
I added the Reference to the DLL project on the property settings of my console application. But I still get unresolved externals from the compiler about the test function.
I managed to compile by manually adding a reference to the lib file generated by the compiler. But then I can't hit breakpoints inside the DLL functions (it says the source code is different from the original version or the symbols have not been loaded...)
Can someone help me?
If your DLL doesn't use any managed functionality, simply remove the /clr option from that project and recompile. If you still get the errors, it's probably related to the references in the console application.
If the DLL use managed functionality, what you need is instead like so:
DLL:
#include "stdafx.h"
namespace Test1
{
public ref class Test2
{
public:
static int test()
{
return 1;
}
};
}
Console app:
#include <iostream>
int main(int argc, char* argv[])
{
int i = Test1::Test2::test();
std::cout << i << std::endl;
return 0;
}

undefined reference to the shared library function

I have implemented a shared library in Linux and try to test it, but I get an error "undefined reference to `CEDD(char*)'".
I use Eclipse with following parameters:
Path to include files (here is
everything ok)
Path to the library
and its name. Path is correct and the
name is WISE_C (full name:
libWISE_C.so)
My Code:
Test programm I use for tests:
#include <iostream>
#include <Descriptor.h>
int main() {
char* path = "/export/home/pdmazubi3/workspace/proj1/src/pic.jpg";
double * cedd = CEDD(path); ///// <-ERROR!
std::cout << "!!!Hello World!!!" << cedd[1];
return 0;
}
Header Descriptor.h:
double* CEDD(char* path);
A part of Descriptor.c with desirable function:
#include "Descriptor.h"
#include "highgui.h"
#include "cv.h"
double* CEDD(char* path)
{
IplImage* srcImg;
IplImage* ImageGrid;
...
}
What I am doing wrog? I have raed a lot of articles in the Internet but I didn't found a solution.
undefined reference to `CEDD(char*)' is a compiler or linker error?
It's a linker error (although I don't think it usually includes the 'char*' bit), so it seems that it either cannot find your library or the library does not contain the function. The latter might also mean that it does contain the actual function, but with a different name; make sure both projects a compiled as C and not C++.
Edit: I missed that you program is C++ (which also explains the more detailed linker message). In this case you should add extern "C" (conditionally, so it is only used when using C++) to the declaration of CEDD if the library is in C.
Are you sure that you linked the object code generated for descriptor.c when building?