Vincentthe0ne Vincentthe0ne - 2 months ago 37
C++ Question

XCode Build Failed "undefined Symbols for architecture x86_64"

I looked up several similar Questions and did not find a Solution for my Code yet. The error I get looks like this:

Undefined symbols for architecture x86_64:
"fast9_score(unsigned char const*, int, xy*, int, int)", referenced from:
detectCornersFast(unsigned char const*, int, int, int, int, int*) in main.o
"fast9_detect(unsigned char const*, int, int, int, int, int*)", referenced from:
detectCornersFast(unsigned char const*, int, int, int, int, int*) in main.o
"nonmax_suppression(xy const*, int const*, int, int*)", referenced from:
detectCornersFast(unsigned char const*, int, int, int, int, int*) in main.o
"cv::namedWindow(cv::String const&, int)", referenced from:
_main in main.o
"cv::GaussianBlur(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)", referenced from:
_main in main.o
"cv::Mat::deallocate()", referenced from:
cv::Mat::release() in main.o
"cv::Mat::copySize(cv::Mat const&)", referenced from:
cv::Mat::operator=(cv::Mat const&) in main.o
cv::Mat::Mat(cv::Mat const&) in main.o
"cv::String::deallocate()", referenced from:
cv::String::~String() in main.o
"cv::String::allocate(unsigned long)", referenced from:
cv::String::String(char const*) in main.o
cv::String::String(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in main.o
"cv::imread(cv::String const&, int)", referenced from:
_main in main.o
"cv::imshow(cv::String const&, cv::_InputArray const&)", referenced from:
_main in main.o
"cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)", referenced from:
_main in main.o
"cv::waitKey(int)", referenced from:
_main in main.o
"cv::fastFree(void*)", referenced from:
cv::Mat::~Mat() 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)


The Architecture I am using in XCode is Universal. I builded and added the search paths for openCV and the fast9 Methods are in the fast.h header. I tried to delete the derived data of the Project but nothing helped. Here my Code of the main.cpp:

#include <vector>
#include <iostream>
#include <cmath>
#include <string>
#include "opencv2/opencv.hpp"
#include "fast.h"

using namespace std;
using namespace cv;

typedef unsigned char byte;

Mat src; Mat dst; Mat tmp;
int rows; int cols;
byte* image;
xy* nonmax;

byte * matToBytes(Mat image){

int size = image.total() * image.elemSize();
byte * bytes = new byte[size];
std::memcpy(bytes, image.data, size * sizeof(byte));

return bytes;

}

xy* detectCornersFast(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners){

xy* corners;
int num_corners;
int* scores;
xy* nonmax;

corners = fast9_detect(im, xsize, ysize, stride, b, &num_corners);
scores = fast9_score(im, stride, corners, num_corners, b);
nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);

free(corners);
free(scores);

return nonmax;

}

int main(int argc, const char * argv[]) {

// insert code here...

vector<Mat> img;
vector<int> num_corners;
vector<xy*> nms;

src = imread(argv[1],1);

img.push_back(src);
double factor = sqrt(2);

for(int i = 0; i < 5; i++){

int ret_num_corners;
rows = src.rows/factor;
cols = src.cols/factor;

resize(src, tmp, Size(rows,cols),0,0, INTER_NEAREST);

GaussianBlur(tmp, dst, Size(5,5),0,0);

image = matToBytes(dst);

nonmax = detectCornersFast(image, tmp.rows, tmp.cols, tmp.rows, 20, &ret_num_corners);

img.push_back(dst);
nms.push_back(nonmax);
num_corners.push_back(ret_num_corners);

src = dst;

}

for(int i = 0; i <img.size(); i++){

string name = "Display Window " + std::to_string(i);
cout << "Number of Corners" << num_corners[i] << endl;
cout << "Nonmax Supression" << nms[i] << endl;
namedWindow(name, WINDOW_AUTOSIZE);
imshow(name, img[i]);
}

waitKey();
return 0;
}


EDIT:
For OpenCV helped to add the Linker Flags from this Tutorial: OpenCV
The Methods from fast are in a .c File which is in my Project Folder. Also the .h file is there. I just post the .h File here because .c File is far too long because its mechanically generated.

fast.h

#ifndef FAST_H
#define FAST_H

typedef struct { int x, y; } xy;
typedef unsigned char byte;

int fast9_corner_score(const byte* p, const int pixel[], int bstart);

xy* fast9_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);

int* fast9_score(const byte* i, int stride, xy* corners, int num_corners, int b);

xy* fast9_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);

xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax);

#endif

Answer

It sounds as though you've only add the header search paths for these dependencies under your projects "Build Settings" -> "Search Paths" -> "User Header Search Paths" field. This will enable xcode to know that these classes exist while you are developing, but wont enable your project to build. You should also make sure that your project knows where to find the libraries where the openCV and fast9 symbols you're using are defined (i.e. where the .so files are for these two dependencies). You can do this by adding the appropriate linker flags under "Build Settings" -> "Linking" -> "Other Linker Flags". ALSO make sure that these fields are set for the TARGET you are trying to compile, not just the PROJECT.

If you arent sure what the linker flags are, here is a brief example. I want to link the following library:

/path/to/some/project/lib/libfoo.so

I would add the following to the "Other Linker Flags" field:

-L/path/to/some/project/lib -lfoo

Basically -L precedes the directory and -l precedes the name of the library without the 'lib' and '.so'.

Note: Whenever I include external dependencies in my xcode projects I also set "Build Settings" -> "Search Paths" -> "Always Search User Paths" to "Yes" just in case any of the dependencies include headers with angle brackets like #include <header.h>.