c++ Compile error - Undefined symbols for architecture x86_64 [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Undefined symbols for architecture i386:
using namespace std;
#include <iostream>
#include <fstream>
#include <string>
#include "CorpusExp.h"
int main(int argc, char* argv[]){
ifstream infile("../DATA.txt");
string train_dir; // The training data directory
infile>>train_dir;
train_dir=train_dir.substr(6,train_dir.length());
if (argc>1){
if (strcmp(argv[1],"-s")){ // enter into CorpusExploration mode
CorpusExp ce(train_dir,"all"); //<<=======LINE X!!!!!!!!
//ce.calculate();
if (argc>=3 && strcmp(argv[2],"-u")){ // check user stats
cout<<"shit";
}
else if (argc>=3 && strcmp(argv[2],"-m")){ // check movie stats
}else{ // check the all (default) stats
}
}else if(strcmp(argv[1],"-m")) {// enter into Recommendation mode
}
}
return 0;
}
If I include the LINE X, the main.cpp won't compile, the error message is:
Undefined symbols for architecture x86_64:
"CorpusExp::CorpusExp(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [recommend] Error 1
And here is my CorpusExp.cpp and CorpusExp.h:
/* CorpusExporater header file
Used for statistical purpose
*/
using namespace std;
#include <iostream>
#include <fstream>
#include <string>
#include <dirent.h> // the Linux library to read the directories
class CorpusExp{
public:
CorpusExp(const string&,const string&); // (dir_name, mode)
void calculate();
void display(ostream &out, const int&); // print out the id's stat information
private:
string _dir_name;
int _movie_count;
int _user_count;
int _movie_rated_count[5]; // times of movie rated as 1,2,3,4,5
float _movie_avg; // total moview average rates
string _mode; // the mode of current task
int _id; // the id of current task
};
/*CorpusExporater cpp file
Used for statistical purpose
*/
#include "CorpusExp.h"
CorpusExp::CorpusExp(const string &dir_name, const string &mode):
_dir_name(dir_name),
_mode(mode),
_movie_count(0),
_user_count(0)
{
}
void CorpusExp::calculate(){
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir(strdup(_dir_name.c_str()));
if (dpdf!=NULL){
while(epdf = readdir(dpdf)){
cout<<epdf->d_name<<endl;
}
}
}
void CorpusExp::display(ostream &out, const int &id){
}
I am barely new to c++, so I get very confused, don't know which part caused this problem. If I remove the LINE X, everything will just be fine, but if I declare the CorpusExp class in the main function, then it did not compile......
here is the compile file:
# Makefile for Movie Recommendation--- HW5 of Search Engine 11-641
# Yitong Zhou
# Nov 19, 2012
#source code directory:
src=src
#obj code directory:
obj=obj
recommend: $(obj)/main.o $(obj)/CorpusExp.o
g++ -o $# $<
$(obj)/main.o: src/main.cpp src/CorpusExp.cpp
g++ -c $< -o $#
$(obj)/CorpusExp.o: $(src)/CorpusExp.cpp $(src)/CorpusExp.h
g++ -c $< -o $#
clean:
rm -rf obj/*.o recommend

Try a simple command line compile without the makefile to make sure the makefile itself isn't the problem.
cd src; g++ main.cpp CorpusExp.cpp -o recommend

Related

Is there something missing from this extremely basic but uncooperative code?

I recently started learning C++, and I'm currently trying to test out the header file functionality. I wrote three simple files:
headertest.h:
#pragma once
class Cube
{
public:
double getVolume();
double getSurfaceArea();
void setLength(double length);
private:
double length_;
};
headertest.cpp:
#include "headertest.h"
double Cube::getVolume()
{
return length_ * length_ * length_;
}
double Cube::getSurfaceArea()
{
return 6 * length_ * length_;
}
void Cube::setLength(double length)
{
length_ = length;
}
and main.cpp:
#include "headertest.h"
#include <iostream>
int main()
{
Cube c;
c.setLength(3.48);
double volume = c.getVolume();
std::cout << volume;
}
However, when I try to build the files, I get the following error:
> Executing task: /usr/bin/clang++ -std=c++17 -stdlib=libc++ -g /Users/jonathan/Desktop/myc++/cubetest/headertest.cpp -o /Users/jonathan/Desktop/myc++/cubetest/headertest <
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The terminal process terminated with exit code: 1
Terminal will be reused by tasks, press any key to close it.
Is there something wrong about how I wrote the main.cpp file, or am I leaving out something important? I've spent all day trying to figure out this issue, and I have no idea how to get unstuck. Thank you!!

Clang unable to link files in VS Code

I recently started learning C++, and I'm currently trying to test out the header file functionality. I wrote three simple files:
headertest.h:
#pragma once
class Cube
{
public:
double getVolume();
double getSurfaceArea();
void setLength(double length);
private:
double length_;
};
headertest.cpp:
#include "headertest.h"
double Cube::getVolume()
{
return length_ * length_ * length_;
}
double Cube::getSurfaceArea()
{
return 6 * length_ * length_;
}
void Cube::setLength(double length)
{
length_ = length;
}
and main.cpp:
#include "headertest.h"
#include <iostream>
int main()
{
Cube c;
c.setLength(3.48);
double volume = c.getVolume();
std::cout << volume;
}
However, when I try to build the files with Clang, I get the following error:
> Executing task: /usr/bin/clang++ -std=c++17 -stdlib=libc++ -g /Users/jonathan/Desktop/myc++/cubetest/headertest.cpp -o /Users/jonathan/Desktop/myc++/cubetest/headertest <
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The terminal process terminated with exit code: 1
Terminal will be reused by tasks, press any key to close it.
Does anyone have any idea of why this is happening? I've tried running g++ main.cpp headertest.cpp -o main before building, but the error isn't getting solved. Thank you!

How to compile OpenCV with Boost::Python?

I'm trying to compile OpenCV in C++ with boost::python but I keep getting a linker error that I can't quite resolve.
Here is the code below.
cascade_handler.cpp
#include <iostream>
#include <boost/python.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ocl/ocl.hpp>
#include "cascade_handler.h"
using namespace std;
using namespace boost::python;
void CascadeHandler::cascade_classifier_cpu(const string *cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors){
/*cv::Mat image;
cv::CascadeClassifier cascade_classifier;
cascade_classifier.load(*cascade_file);
cascade_classifier.detectMultiScale(image, objects, scale_factor, min_neighbors, 0 | CASCADE_SCALE_IMAGE, Size(20, 20));
*/
}
void CascadeHandler::cascade_classifier_gpu(const string *cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors){
/*Mat image;
cv::CascadeClassifier cascade_classifier;
*/
}
void CascadeHandler::handle(const string cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors)
{
CascadeHandler cascade_handler;
cv::CascadeClassifier cascade_classifier;
//ocl::Context context;
/*
if (!cascade_classifier.load(cascade_file)){
cout << "[!] Error: You must load a Cascade file\n";
}
if (objects.empty()){
}
if (scale_factor == 0){
cout << "[!] Error: Unacceptable Scale Factor\n";
}
if (min_neighbors == 0){
cout << "[!] Error: Unacceptable Minimum Neighbors\n";
}
if (context.ndevices()){
cascade_handler.cascade_classifier_gpu(&cascade_file, objects, scale_factor, min_neighbors);
}
else if (!context.ndevices()){
cascade_handler.cascade_classifier_cpu(&cascade_file, objects, scale_factor, min_neighbors);
}
*/
}
void cascade_handler_wrapper(const string cascade_file, std::vector<cv::Rect>& objects,
double scale_factor, int min_neighbors){
CascadeHandler cascade_handler;
cascade_handler.handle(cascade_file, objects, scale_factor, min_neighbors);
}
BOOST_PYTHON_MODULE(cascade_handler){
def("handle", cascade_handler_wrapper);
}
The Header file
#ifndef _CASCADE_HANDLER
#define _CASCADE_HANDLER
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ocl/ocl.hpp>
using namespace std;
class CascadeHandler
{
public:
void cascade_classifier_cpu(const string *cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors);
void cascade_classifier_gpu(const string *cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors);
void handle(const string cascade_file, std::vector<cv::Rect>& objects, double scale_factor, int min_neighbors);
};
#endif
The Makefile
CPP = g++
CPPFLAGS = -g -Wall -std=c++11
INCLUDES = -I /usr/local/include
LDFLAGS = -L /usr/local/lib
ARCH := $$(getconf LONG_BIT)
CUDA_PATH = /opt/cuda
CUDA_LDFLAGS = -L$(CUDA_PATH)/lib$(ARCH)
CUDA_INCLUDES = -I$(CUDA_PATH)/include
OPENCV_LDFLAGS = $(CUDA_LDFLAGS)
OPENCV_LIBS = $$(pkg-config --libs opencv)
OPENCV_INCLUDES = $$(pkg-config --cflags opencv) $(CUDA_INCLUDES)
PYTHON_VER = 2
ifeq ($(PYTHON_VER), 2)
BOOST_LIBS = -lboost_python
else
BOOST_LIBS = -lboost_python$(PYTHON_VER)
endif
PYTHON_LIBS = $$(pkg-config --libs python$(PYTHON_VER))
PYTHON_INCLUDES = $$(pkg-config --cflags python$(PYTHON_VER))
TARGET = cascade_handler
all: $(TARGET).so
$(TARGET).so: $(TARGET).o
$(CPP) -shared -Wl,--export-dynamic $(LDFLAGS) \
$(OPENCV_LIBS) $(BOOST_LIBS) $(PYTHON_LIBS) \
$(TARGET).o -o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
$(CPP) $(CPPFLAGS) $(INCLUDES) $(OPENCV_INCLUDES) $(PYTHON_INCLUDES) \
-fPIC -c $(TARGET).cpp
clean:
rm -f *.o *.so
And the Output
g++ -shared -Wl,--export-dynamic -L /usr/local/lib \
$(pkg-config --libs opencv) -lboost_python $(pkg-config --libs python2) \
cascade_handler.o -o cascade_handler.so
ld: unknown option: --export-dynamic
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [cascade_handler.so] Error 1
The linker error is the thing I can't quite fix. I wanted to have everything compile on a Makefile because I couldn't find a way to compile OpenCV with the setup.py you normally use when using boost::python. I've also read that some people have been using numpy to wrap their code in and then compile that way, but I was wondering if this method may also work? I also have most of the code commented out because I just wanted to test if it would compile by just have the class cv::CascadeClassifier cascade_classifier;

Compiling libzip on Mac: Undefined symbols for architecture x86_64

I've been learning C++ and have decided to try to create a simple file reader using libzip on archive files (e.g. Word).
I’ve recently installed libzip on my Macbook using brew but I seem to keep on getting the following issue whenever I try to compile a program that uses libzip:
Undefined symbols for architecture x86_64:
"_zip_fopen", referenced from:
_main in main-918bfa.o
"_zip_open", referenced from:
_main in main-918bfa.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: *** [a.exe] Error 1
The command I use to compile:
g++ -g main.cpp -std=c++11 -I/usr/local/Cellar/libzip/0.11.2/include -I/usr/local/Cellar/libzip/0.11.2/lib/libzip/include -L/usr/local/Cellar/libzip/0.11.2/lib -o ../a.exe
main.cpp:
#include <iostream>
#include <fstream>
#include <zip.h>
#include <zlib.h>
using namespace std;
int numArgs = 2;
int main(int argc, char** argv){
// Parse command line arguments
if(argc != numArgs){
std::cout << "Incorrect number of arguments provided.\n";
std::cout << "Command line syntax: fileReader.exe inputFile" << endl;
exit(0);
}
// Try out libzip functionality
std::string inputDocument(argv[1]);
int err = 0;
zip* z = zip_open(inputDocument.c_str(), 0, &err);
if(z == NULL) {
printf("Could not read docx file. Error code: %d", err);
exit(-1);
}
zip_file* contentTypes = zip_fopen(z, "[Content_Types].xml", ZIP_FL_UNCHANGED);
exit(0);
}
Doesn't look like your including the libzip library in the compilation command. Try adding -lzip to your g++ command

C++ code compiles fine with normal V8 engine, fails to build with V8 provided by Node

Makefile:
CC:=g++
OUTFILE?=addon
SOURCE?=src
CFLAGS+=-Iinclude -lv8 -m64
.PHONY: all clean
all:
$(CC) $(CFLAGS) -o $(OUTFILE) `ls $(SOURCE)/*.cc`
clean:
rm -f $(OUTFILE)
addon.h:
#ifndef __addon_h
#define __addon_h
#define BUILDING_NODE_EXTENSION
#define ADDON_VERSION "0.0.1"
#ifdef BUILDING_NODE_EXTENSION
#include <node/node.h>
#include <node/v8.h>
#else
#include <v8.h>
#endif
using namespace v8;
void init(Handle<Object> exports);
Handle<Object> setupExports(Handle<Object> exports);
#endif
addon.cc:
#include <cstdlib>
#include <cstdio>
#include <addon.h>
using namespace v8;
#ifndef BUILDING_NODE_EXTENSION
int main(int argc, char **argv) {
Isolate *isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
Handle<Context> context = Context::New(isolate);
Context::Scope context_scope(context);
Handle<Object> exports = Object::New();
init(exports);
printf("Version: %s\n", *String::Utf8Value(exports->Get(String::New("version"))));
return 0;
}
#else
int main() {
printf("This is a module compiled for Node.\nPlease use require in Node to use this file.\n");
return 0;
}
#endif
void init(Handle<Object> exports) {
setupExports(exports);
}
Handle<Object> setupExports(Handle<Object> exports) {
// Set version number.
exports->Set(String::New("version"), String::New(ADDON_VERSION));
return exports;
}
#ifdef BUILDING_NODE_EXTENSION
NODE_MODULE(addon, init)
#endif
When compiling the above code with the normal V8 engine without BUILDING_NODE_EXTENSION defined, the output is what we expect:
❱ make && ./addon
g++ -Iinclude -lv8 -m64 -o addon `ls src/*.cc`
Version: 0.0.1
When compiling with BUILDING_NODE_EXTENSION defined, using Node's <node/node.h> and <node/v8.h> for includes instead of the normal <v8.h>, I get this:
❱ make && ./addon
g++ -Iinclude -lv8 -m64 -o addon `ls src/*.cc`
Undefined symbols for architecture x86_64:
"v8::String::New(char const*, int)", referenced from:
setupExports(v8::Handle<v8::Object>) in ccRntYkS.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1
Anyone have any idea what is going wrong here?
Building with node-gyp solved the problem.
Face. Palm.
Makefile change:
CC:=g++
OUTFILE?=addon
SOURCE?=src
CFLAGS+=-Iinclude -lv8 -m64
.PHONY: all clean
all:
if [ -d build ]; then \
node-gyp build; \
else \
$(CC) $(CFLAGS) -o $(OUTFILE) `ls $(SOURCE)/*.cc`; \
fi;
clean:
rm -f $(OUTFILE)