C++ Namespace and Linking not working - c++

Update: Fixed. Very simple solution. I just have to add in my Add_Executable method. Here:
add_executable (POC eb_pms.cpp url_binder.cpp)
So this problem looks pretty small, yet, I am unable to find any solution of this. Or, I should say, none of articles explains it in a simple manner so I can understand. I have come from a strongly typed background like C#/Java. I am trying to build a Rest API in C++11 using Simple Web Server and RapidJSON. Since we are building this project to be a part of a bigger solution, I cannot use commandline to link the program. I have to use the CMakeLists to compile and run the program. It means, the linking has to be done through the CMakeLists.txt file. The whole source code can be found here at GitHub. My environment is Macbook Pro + VS Code. So I have two CPPs here: eb_pms.cpp, url_binder.cpp. The urlbinder has a namespace 'EBPMS' and eb_pms has none. Following is the code of ep_pms:
(header file)
#include "server_http.hpp"
#include "client_http.hpp" //client for testing the API code
#include <boost/property_tree/ptree.hpp> /*for the shared pointer*/
#include "url_binder.h"
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
using HttpClient = SimpleWeb::Client<SimpleWeb::HTTP>;
using Binder = EBPMS::URLBinder;
void bindUrls(HttpServer *server);
cpp file:
# include "eb_pms.h"
using namespace boost::property_tree;
using namespace std;
using namespace EBPMS;
int main(){
HttpServer server;
server.config.port = 8081;
bindUrls(&server);
thread server_thread([&server]() {
server.start();
});
server_thread.join();
}
void bindUrls(HttpServer *server){
//URLBinder c;
Binder binder;
binder.bindURL_string();
}
the url binder h:
#include <boost/property_tree/ptree.hpp> /*for the shared pointer*/
#include "server_http.hpp"
#include "client_http.hpp"
#include <iostream>
namespace EBPMS{
class URLBinder{
public: URLBinder();
void bindURL_string();
};
}
the url binder cpp;
#include "url_binder.h"
using namespace boost::property_tree;
using namespace std;
namespace EBPMS{
URLBinder::URLBinder() {}
void URLBinder::bindURL_string(){ //HttpServer *server
std::cout << "Trying to log if it comes" << std::endl;
}
}
So all I need is basically, to find a way to link this file with NameSpace with my original cpp so I can use the method from url binder inside my main cpp class. I am trying to call function in eb_pms.cpp class. When I run make command, I get this error:
Scanning dependencies of target POC
[ 2%] Building CXX object CMakeFiles/POC.dir/eb_pms.cpp.o
[ 5%] Linking CXX executable POC
Undefined symbols for architecture x86_64:
"EBPMS::URLBinder::bindURL_string()", referenced from: _main in eb_pms.cpp.o
bindUrls(SimpleWeb::Server<boost::asio::basic_stream_socket<boost::asio::ip::tcp>> >*) in eb_pms.cpp.o
"EBPMS::URLBinder::URLBinder()", referenced from: _main in eb_pms.cpp.o
bindUrls(SimpleWeb::Server<boost::asio::basic_stream_socket<boost::asio::ip::tcp>> >*) in eb_pms.cpp.o
ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [POC] Error 1
make[1]: ***
[CMakeFiles/POC.dir/all] Error 2
make: *** [all] Error 2
It has been hours since I am trying to research. But I am unable find that missing piece. Any help will be greatly appreciated.

I'm just guessing here since you don't show your CMakeLists.txt file...
I would say that you don't list your url_binder.cpp file as a source in the CMake add_executable command.
All source-files you want to be part of your program must be listed.

Related

Compiling multiple files in Visual Studio Code resulting in error

I'm relatively new to coding in C++ and have started working with main and header files and I've created a program to test it out, however, the following program results in the following compiler error:
Undefined symbols for architecture x86_64:
"Print()", referenced from:
_main in test-7d0225.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is my current code.
test.cpp
#include <iostream>
#include "test.h"
using namespace std;
int main() {
Print();
return 0;
}
test.h
#ifndef TEST_H
#define TEST_H
void Print();
#endif
test1.cpp
#include <iostream>
#include "test.h"
using namespace std;
void Print() {
cout << "Hello" << endl;
}
Nothing I've found online has helped me and my only assumptions are that my compiler isn't set up correctly. I've tried compiling both of these of files by typing in "g++ test.cpp test1.cpp", as well, but yields similar results. I would like to note that I am on Mac as well. Please feel free to leave any comments or suggestions for how I've asked this question, this is my first time on stack overflow.
Your code seems just fine, I’ll will try to compile it on vscode myself.
One problem could be your vscode launch.json. I have had the same problem as what I am describing. Vscode can be quite “Finicky” with low level languages like c and c++. In your launch file (or tasks file if it calls something in tasks) make sure you compile *.cpp files in the folder. I would look something like {folder}/**.cpp. To find the exact command look on vscode’s official site.
Given that you tried compiling your code outside of vscode and assuming that everything is in the same folder, it might be a coding problem. Again, your code looks fine. Go online and find some learning to code website with multiple file coding. Copy their code and do the same thing that you did with your code. If it doesn’t work there is definitely a problem with how to code is being compiled. Otherwise revise your code and compare to find the problem.
Also, could you provide the terminal command vscode prints (I am also on Mac). It will be in the terminal tab in the g++ section, not in bash)
P.S. I am also new to stack overflow so any suggestions you have for me will be great.

How to add library curlpp to C++ project [duplicate]

This question already has an answer here:
How do I add curlpp to my project?
(1 answer)
Closed 4 years ago.
I want to add curlpp to my C++ project. Currently, I have a main.cpp file which looks like this:
#include <iostream>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
int main() {
return 0;
}
I compile using:
"g++ -std=c++14 -I/usr/nguyenthesang/Desktop/myprogram/curlpp-0.8.1/include main.cpp" and it successfully compiles.
Then I add the implementation in the main function (the below is copied from curlpp's repo):
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
using namespace curlpp::options;
int main(int, char **)
{
try
{
// That's all that is needed to do cleanup of used resources (RAII
style).
curlpp::Cleanup myCleanup;
// Our request to be sent.
curlpp::Easy myRequest;
// Set the URL.
myRequest.setOpt<Url>("http://example.com");
// Send request and get a result.
// By default the result goes to standard output.
myRequest.perform();
}
catch(curlpp::RuntimeError & e)
{
std::cout << e.what() << std::endl;
}
catch(curlpp::LogicError & e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
When I compile by using "g++ -std=c++14 -I/usr/nguyenthesang/Desktop/myprogram/curlpp-0.8.1/include main.cpp" , there are compilation errors, which say that "ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)".
The errors may come from the fact that I have only linked the header files to the program but not the library itself. I google around to find the way to link the library (for example using -L options) but it did not work. I need help with this problem.
I also want to ask that is there a general way for adding every library into C++ project, like Cocoapods in iOS?
I appreciate your help.
On ubuntu I had success with installing these packages:
sudo apt-get install pkg-config libcurlpp-dev libcurl4-openssl-dev
(pkg-config is to be used in CMakeLists.txt to find the curlpp and set an env var that points to it)
Then in my CMakeLists.txt I added:
include(FindPkgConfig)
pkg_check_modules(CURLPP REQUIRED curlpp)
Then still in CMakeLists.txt add to target_link_libraries ${CURLPP_LDFLAGS} for example:
target_link_libraries(mylibcurlppprog ${CURLPP_LDFLAGS})

C++ - no rule to create target SaltPepper.o

I know there are several questions like this, no answer I have found so far seems to solve my problem.
I am using eclipse.
I coded something in the main function, and it worked fine.
I then an external function with the code in the main and now I get funny mistakes.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <random>
#include <ctime>
#include <cstdlib>
using namespace std;
using namespace cv;
void createSaltandPepper();
int main(int argc, char** argv) {
createSaltandPepper();
return 0;
}
No, as I am trying not to give to extensive an example again, here is the outside of the function:
void createSaltandPepper() {
//mycode
}
At least it does not seem to be a spelling mistake.
However, the error is:
make all
make: *** No rule to make target 'SaltPepper.o', needed by 'Display'.
I do wonder why it is trying to make a tagert called SaltPepper.o if my function is called createSaltandPepper.
Can somebody help me?
Edit: I did not conciously create a makefile, as I said I am working with eclipse.
And again, the code works fine as long as it is inside the main function instead of inside createSaltandPepper().
My file is called DisplayImage.cpp, the code above is in this file, including the function createSaltandPepper();
The only two function in this file are the main function and createSaltandPepper();
There are no other source files in the project.
I am sorry if I come across as rather stupid: I am a Java programmer and have not a clue about makefiles and such.
See this screenshot:
I now created a new project and added my old file into it, this time calling it Display.cpp
"build all" resulted in an error in subdir.mk which reads:
subdir.mk:18: recipe for target 'Display.o' failed
make: *** [Display.o] Error 1
The complete Error message for the build is as follows:
make all
Building file: ../Display.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0-std=c++11 -MMD -MP -MF"Display.d" -MT"Display.d" -o"Display.o" "../Display.cpp"
subdir.mk:18: recipe for target 'Display.o' failed
g++: error: argument to ‘-fmessage-length=’ should be a non-negative integer
make: *** [Display.o] Error 1
Update
I switched to Netbeans.
It now works.
First, this error has nothing to do with compilers, this error message is produced by the build system (make in your case). Basically, eclipse seems to call make, which figures out what are dependencies between files and which of them need recompiling and in turn calls the compiler to compile them. Every C++ source file is then compiled to an object file .o (typically with the same name: SaltPepper.cpp -> SaltPepper.o). Then all the object files are linked together with the libraries to form the final executable.
This particular error message tells you that your executable is specified to depend on the object file SaltPepper.o, but the build system does not know how to produce it. Most likely there is no corresponding SaltPepper.cpp file. So check if such file exists. If not, check the settings of your project (or the Makefile if you created it manually) and see if all the cpp filenames are specified correctly. You should add all the cpp files with your code to the project, and remove all the extraneous cpp files.
Update: Note that build system operates on the file level. It does not know anything about functions etc., only source files. Maybe this is the source of the confusion.

Error information in the compiling of c++ with armadillo library

A beginner to armadillo library and have two problems with it.
The first question is about the link of armadillo and c++. I installed armadillo by following the instructions in the package and the location is /usr/include/, I could successfully run the code:
#include <iostream>
#include "/usr/include/armadillo"
using namespace std;
int main()
{
arma::mat a = arma::randu<arma::mat>(3, 3);
cout << a << endl;
return 0;
}
but if I want to define a function, for example, the inverse of the matrix (there is a function I can call from the library but I just want to do a test).
#include <iostream>
#include "/usr/include/armadillo"
using namespace std;
arma::mat Inverse( arma::mat A){
return arma::inv(A);
}
int main()
{
arma::mat a = arma::randu<arma::mat>(3, 3);
arma::mat inv_a = Inverse(a);
cout << inv_a << endl;
return 0;
}
then the program failed with three error messages.
Undefined symbols for architecture x86_64:
"_wrapper_dgetrf_", referenced from:
void arma::lapack::getrf<double>(int*, int*, double*, int*, int*, int*) in main.o
"_wrapper_dgetri_", referenced from:
void arma::lapack::getri<double>(int*, double*, int*, int*, double*, int*, int*) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I checked by google and have tried some advices, like:" In miscellaneous MAC OS X linkers, I had to put "-01 -larmadillo" AND I had to deactivate the shared library settings!", to be honest, I can not find the miscellaneous option and deactivate the shared library settings as i am not familiar with Xcode. Then I followed install MacPorts and the library is installed to the folder /usr/local/include/, and I tried again, the first program is alright but the second program still has three errors, could anyone help me with this?
The second question would be the use of lapack when I am using armadillo in the same program, as I know armadillo is based on lapack, then if I declared the library armadillo, do I need to declare lapacke.h. Why do I ask this questions is that when I declared RcppArmadillo and lapacke.h, an error exists:
This file includes at least one deprecated or antiquated header. Please consider using of the 32 header found in section 17.4.1.2 of the C++ standard. Example include substituting the <X> header for the <X.h> hear for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated. [-W#warnings]
Line 11763 conflicting type for 'cgetrf'
Line 11765 conflicting type for 'zgetrg_'
...
I had the same problem, but eventually I solved it.
I didn't installed armadillo for my own purpose, but provided absolute path to include and library directories. Also, in a README there is a note that if you're on Mac then you should use Accelerate framework like this "-framework Accelerate". So after doing this all linker errors were gone.

Error with Poppler implementation with C++

I'm currently working on project which uses the poppler library. As It stands I have the following:
In the following folder (C:\Users\ ...\Anotation Extraction) I have all the files associated with a Codeblocks C++ project (including the main.cpp) as well as the current version of poppler and its associated documents in a folder called "poppler-0.22.2".
I also have a test pdf in this folder.
(System: Windows 7, 64 bit, Codeblocks using MinGW)
In my main.cpp file I have the following:
#include <iostream>
#include "poppler-0.22.2/cpp/poppler-document.h"
using namespace std;
int main()
{
const string dir = "C:\\Users\\...\\test.pdf";
poppler::document* doc;
doc = poppler::document::load_from_file(dir);
delete doc;
cout << dir << endl;
return 0;
}
However, when I try to build this code, the following errors pop up and I have absolutely no idea why.
obj\Debug\main.o||In function `main':|
C:\Users...\Anotation Extraction\main.cpp|11|undefined reference to `imp__ZN7poppler8document14load_from_fileERKSsS2_S2_'|
C:\Users...\Anotation Extraction\main.cpp|12|undefined reference to `imp__ZN7poppler8documentD1Ev'|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|
Any help you guys could provide would be much appreciated.