Connecting CppUTest to C Interface - c++

I'm using CppUTest to handle unit testing with my C library. However, I'm having an issue when compiling the test file.
Here's my Makefile (The CPPUTEST_HOME var is an environment variable):
CPPFLAGS += -I$(CPPUTEST_HOME)/include
CXXFLAGS += -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorNewMacros.h
CFLAGS += -include $(CPPUTEST_HOME)/include/CppUTest/MemoryLeakDetectorMallocMacros.h
LD_LIBRARIES = -L$(CPPUTEST_HOME)/lib -lCppUTest -lCppUTestExt
all:
c++ -g -Wall $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) commonTest.cpp -o commonTest $(LD_LIBRARIES)
clean:
rm -rf *.dSYM commonTest
When I run make, the following output is given:
Undefined symbols for architecture x86_64:
"_test_common_algos_commonCalloc_wrapper_c", referenced from:
TEST_common_algos_commonCalloc_Test::testBody() in commonTest-992552.o
"_test_common_algos_commonMalloc_wrapper_c", referenced from:
TEST_common_algos_commonMalloc_Test::testBody() in commonTest-992552.o
"_test_common_algos_commonRealloc_wrapper_c", referenced from:
TEST_common_algos_commonRealloc_Test::testBody() in commonTest-992552.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: *** [all] Error 1
To me, this seems like a linking problem. However, I don't think I've done anything wrong according to the manual:
commonTest.c:
#include "../common.h"
#include "CppUTest/TestHarness_c.h"
void *ptr = NULL;
int list[10] = {1, 2, 32, 33, 2, 5, 7, 3, 9, 34};
TEST_GROUP_C(common_algos)
{
};
TEST_C(common_algos, commonMalloc)
{
ptr = malloc_c(6);
CHECK_EQUAL_C_INT(algos_error, ALGOS_OK);
strncpy(ptr, "Hello", 5);
CHECK_EQUAL_C_STRING("Hello", ptr);
free_c(ptr);
}
TEST_C(common_algos, commonCalloc)
{
ptr = calloc_c(sizeof(int), 10);
CHECK_EQUAL_C_INT(algos_error, ALGOS_OK);
memcpy(ptr, list, sizeof(int)*10);
for (int i = 0; i < 10; i++)
CHECK_EQUAL_C_INT(list[i], ptr[i]);
free_c(ptr);
}
TEST_C(common_algos, commonRealloc)
{
ptr = malloc_c(10);
CHECK_EQUAL_C_INT(ALGOS_OK, algos_error);
memcpy(ptr, list, sizeof(int)*10);
ptr = realloc_c(ptr, 20);
CHECK_EQUAL_C_INT(ALGOS_OK, algos_error);
memcpy(ptr + 10, list, sizeof(int)*10);
for (int i = 9; i < 19; i++)
CHECK_EQUAL_C_INT(list[i-9], ptr[i]);
free_c(ptr);
}
commonTest.cpp:
#include "CppUTest/CommandLineTestRunner.h"
#include "CppUTest/TestHarness_c.h"
TEST_GROUP_C_WRAPPER(common_algos)
{
};
TEST_C_WRAPPER(common_algos, commonMalloc);
TEST_C_WRAPPER(common_algos, commonCalloc);
TEST_C_WRAPPER(common_algos, commonRealloc);
int main(int ac, char **av)
{
return RUN_ALL_TESTS(ac, av);
}
Lastly, my directory structure:
common
|______ common.c
|
|______ common.h
|
|______ test
|
|____commonTest.c
|
|____commonTest.cpp
For some context, I'm not a C++ programmer, and I'm not experienced with using CppUTest, so bear with me.
Thanks for any help and feel free to ask questions.

Related

Error when compiling MATIO library: "Undefined reference to 'Mat_Open'"

so after building and installing the MATIO library using CMake, I am now having problems compiling it. Here's my code:
#include <iostream>
#include <matio.h>
#define tS(x) std::cout<<"\t"<<(#x)<<" == "<<(x)<<"\n"
int main(int argc, char **argv)
{
const char *fileName = argc==1?"./S.mat":argv[1] ;
mat_t *mat = Mat_Open(fileName,MAT_ACC_RDONLY);
if(mat)
{
std::cout<<"A file was opened for reading\n\tmat == "<<mat<<"\n" ;
matvar_t *matVar=0 ;
std::cout<<"Writing out the data\n\n" ;
std::cout<<"x:\n" ;
matVar = Mat_VarRead(mat, (char*)"x") ;
if(matVar)
{
int xSize = matVar->nbytes/matVar->data_size ;
const double *xData = static_cast<const double*>(matVar->data) ;
for(int i=0; i<xSize; ++i)
{
std::cout<<"\tx["<<i<<"] = "<<xData[i]<<"\n" ;
}
std::cout<<"\n" ;
for(int i=0; i<matVar->rank; ++i)
{
std::cout<<"\tdim["<<i<<"] == "<<matVar->dims[i]<<"\n" ;
}
}
std::cout<<"y:\n" ;
matVar = Mat_VarRead(mat, (char*)"y") ;
int ySize = matVar->nbytes/matVar->data_size ;
const double *yData = static_cast<const double*>(matVar->data) ;
for(int i=0; i<ySize; ++i)
{
double d = yData[i] ;
std::cout<<"\ty["<<i<<"] = "<<d<<"\n" ;
}
std::cout<<"\n" ;
for(int i=0; i<matVar->rank; ++i)
{
std::cout<<"\tdim["<<i<<"] == "<<matVar->dims[i]<<"\n" ;
}
Mat_Close(mat);
}
else
{
std::cout<<"File cannot be opened\n" ;
return 1;
}
return 0;
}
However I get the following error:
C:\WINDOWS\system32\cmd.exe /C ""C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/mingw32-make.exe" -j4 SHELL=cmd.exe -e -f Makefile"
"----------Building project:[ Test - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test'
"C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe" -c "C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test/main.cpp" -std=c++14 -Wall -g -O0 -Wall -I/Users/RS3/matio/getopt -I/matio/include -L/matio/bin -lmatio -o ./Debug/main.cpp.o -I. -I. -I"C:\Users\RS3\Desktop\SCC HiWi\Code\C++\myGmm\UQ\eigen-3.3.9" -I"C:\Users\RS3\Desktop\SCC HiWi\Code\C++\myGmm\UQ\Halton" -I"C:\Users\RS3\Desktop\SCC HiWi\Code\C++\myGmm\UQ\quasimvnrnd"
"C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe" -o ./Debug/Test #"Test.txt" -L. -L"C:\Users\RS3\Desktop\SCC HiWi\Code\C++\myGmm\UQ\eigen-3.3.9" -static-libgcc -static-libstdc++
./Debug/main.cpp.o: In function `main':
C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test/main.cpp:38: undefined reference to `Mat_Open'
C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test/main.cpp:46: undefined reference to `Mat_VarRead'
C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test/main.cpp:63: undefined reference to `Mat_VarRead'
C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test/main.cpp:77: undefined reference to `Mat_Close'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[1]: *** [Test.mk:81: Debug/Test] Error 1
mingw32-make.exe[1]: Leaving directory 'C:/Users/RS3/Desktop/SCC HiWi/Code/C++/myGmm/UQ/Test'
mingw32-make.exe: *** [Makefile:5: All] Error 2
====4 errors, 0 warnings====
I looked for this error right and left and I know the linker can't find the library for some reason despite me having the following compiler options:
-g;-O0;-Wall;-I/Users/RS3/matio/getopt;-I/matio/include;-L/matio/bin;-lmatio
I'm using Codelite IDE.
I am not sure what I am missing and it's driving me crazy. Any help would be appreciated!

Undefined symbol when trying to link with shared library built from CUDA objects

I'm experimenting with building a simple application from a couple of .cu source files and a very simple C++ main that calls a function from one of the .cu files. I'm making a shared library (.so file) from the compiled .cu files. I'm finding that everything builds without trouble, but when I try to run the application, I get a linker undefined symbol error, with the mangled name of the .cu function I'm calling from main(). If I build a static library instead, my application runs just fine. Here's the makefile I've set up:
.PHONY: clean
NVCCFLAGS = -std=c++11 --compiler-options '-fPIC'
CXXFLAGS = -std=c++11
HLIB = libhello.a
SHLIB = libhello.so
CUDA_OBJECTS = bridge.o add.o
all: driver
%.o :: %.cu
nvcc -o $# $(NVCCFLAGS) -c -I. $<
%.o :: %.cpp
c++ $(CXXFLAGS) -o $# -c -I. $<
$(HLIB): $(CUDA_OBJECTS)
ar rcs $# $^
$(SHLIB): $(CUDA_OBJECTS)
nvcc $(NVCCFLAGS) --shared -o $# $^
#driver : driver.o $(HLIB)
# c++ -std=c++11 -fPIC -o $# driver.o -L. -lhello -L/usr/local/cuda-10.1/targets/x86_64-linux/lib -lcudart
driver : driver.o $(SHLIB)
c++ -std=c++11 -fPIC -o $# driver.o -L. -lhello
clean:
-rm -f driver *.o *.so *.a
Here are the various source files that the makefile takes as fodder.
add.cu:
__global__ void add(int n, int* a, int* b, int* c) {
int index = threadIdx.x;
int stride = blockDim.x;
for (int ii = index; ii < n; ii += stride) {
c[ii] = a[ii] + b[ii];
}
}
add.h:
extern __global__ void add(int n, int* a, int* b, int* c);
bridge.cu:
#include <iostream>
#include "add.h"
void bridge() {
int N = 1 << 16;
int blockSize = 256;
int numBlocks = (N + blockSize - 1)/blockSize;
int* a;
int* b;
int* c;
cudaMallocManaged(&a, N*sizeof(int));
cudaMallocManaged(&b, N*sizeof(int));
cudaMallocManaged(&c, N*sizeof(int));
for (int ii = 0; ii < N; ii++) {
a[ii] = ii;
b[ii] = 2*ii;
}
add<<<numBlocks, blockSize>>>(N, a, b, c);
cudaDeviceSynchronize();
for (int ii = 0; ii < N; ii++) {
std::cout << a[ii] << " + " << b[ii] << " = " << c[ii] << std::endl;
}
cudaFree(a);
cudaFree(b);
cudaFree(c);
}
bridge.h:
extern void bridge();
driver.cpp:
#include "bridge.h"
int main() {
bridge();
return 0;
}
I'm very new to cuda, so I expect that's where I'm doing something wrong. I've played a bit with using extern "C" declarations, but that just seems to move the "undefined symbol" error from run time to build time.
I'm familiar with various ways that one can end up with an undefined symbol, and I've mentioned various experiments I've already performed (static linking, extern "C" declarations) that make me think that this problem isn't addressed by the proposed duplicate question.
My unresolved symbol is _Z6bridgev
It looks to me as though the linker should be able resolve the symbol. If I can nm on driver.o, I see:
0000000000000000 T main
U _Z6bridgev
And if I run nm on libhello.so, I see:
0000000000006e56 T _Z6bridgev
When Robert Crovella was able to get my example to work on his machine, while I wasn't able to get his example to work on mine, I started realizing that my problem had nothing to do with cuda or nvcc. It was the fact that with a shared library, the loader has to resolve symbols at runtime, and my shared library wasn't in a "well-known location". I built a simple test case just now, purely with c++ sources, and repeated my failure. Once I copied libhello.so to /usr/local/lib, I was able to run driver successfully. So, I'm OK with closing my original question, if that's the will of the people.

multiple definition c++/c google test

So ive looked at similar issues and I followed what they said. I have made sure that my .h and .cpp file are in my main test file.
So I'm not really sure whats wrong. I fixed an earlier error like this but it was something I caught. Id appreciate some help.
Matrix-Multiply.h
Matrix-Multiply.h
#ifndef __MATRIX_MULTIPLY_H
#define __MATRIX_MULTIPLY_H
#include<stdio.h>
#include<stdlib.h>
float *expectedFinalMatrixOutput(int mA,int nA,int mB,int nB,float *matA,float *matB);
int readFiles(const char *matAFile,const char *matBFile);
#endif //__MATRIX_MULTIPLY_H
Matrix-Multiply.cpp
//.cpp file
#include<stdio.h>
#include<stdlib.h>
float *expectedFinalMatrixOutput(int mA,int nA,int mB,int nB,float *matA,float *matB)
{
int m = mA;
int n = nB;
int size = m * n;
float *finalMatrix[size];
//build both matrices
//for both the matA Column and matB Row need to be the
//same before even multiplying
//dot product matrix
//the end matrix needs the have the same number of rows as
//matA and same number of columns as matB
return *finalMatrix;
}
int readFiles(const char *matAFile,const char *matBFile)
{
int flag;
//read in file for matrixs
//set flag for whether true or false
//verify row and column being taken have actual values and
//that the sized are correct
return flag;
}
Matrix-Multiply_unittests.cpp
// tests.cpp
#include "Matrix-Multiply.h"
#include "Matrix-Multiply.cpp"
#include<gtest/gtest.h>
#include<stdio.h>
TEST(matrixSize,emptyMatrix)
{
float *matA = NULL;
float *matB = NULL;
float *matrix =
expectedFinalMatrixOutput(0,0,0,0,matA,matB);
ASSERT_EQ(*(matrix),0);
}
TEST(dotTest,oneByoneMatrix)
{
float fMatrix[1] = {1};
float sMatrix[1] = {1};
float *matrix = expectedFinalMatrixOutput(1,1,1,1,fMatrix,sMatrix);
ASSERT_EQ(matrix[0],1);
}
TEST(dotTest,twoBytwoMatrix)
{
float fMatrix[4] = {1,1,1,1};
float sMatrix[4] = {1,1,1,1};
float *matrix = expectedFinalMatrixOutput(2,2,2,2,fMatrix,sMatrix);
for(int i =0;i<4;i++)
{
EXPECT_EQ(2,matrix[i]);
}
}
TEST(ReadFilesTest,filesExist)
{
const char *matA = "../src/Matrix1_3_3.txt";
const char *matB = "../src/Matrix2_3_3.txt";
ASSERT_EQ(0,readFiles(matA,matB));
}
TEST(ReadFilesTest,filesDontExist)
{
const char *matA = "../src/notReal.txt";
const char *matB = "../src/Matrix2_3_3.txt";
ASSERT_EQ(0,readFiles(matA,matB));
}
TEST(ReadFilesTest,matrixSizeNotCompatible)
{
const char *matA = "../src/Matrix1_3_3.txt";
const char *matB = "../src/Matrix2_2_2.txt";
ASSERT_EQ(0,readFiles(matA,matB));
}
int main(int argc,char **argv)
{
testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}
Sorry if its not all on one line. I tried to get it that way. But the error i get is:
obj/Matrix-Multiply.o: In function `expectedFinalMatrixOutput(int, int, int,
int, float*, float*)':
Matrix-Multiply.cpp:(.text+0x0): multiple definition of
`expectedFinalMatrixOutput(int, int, int, int, float*, float*)'
/tmp/ccUgZRUB.o:Matrix-Multiply_unittests.cpp:(.text+0x0): first defined
here
obj/Matrix-Multiply.o: In function `readFiles(char const*, char const*)':
Matrix-Multiply.cpp:(.text+0xbe): multiple definition of `readFiles(char
const*, char const*)'
/tmp/ccUgZRUB.o:Matrix-Multiply_unittests.cpp:(.text+0xbe): first defined
here
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
Im using googletest and already make a call to make gtest
However this error occurs when i call make test.
Any help is appreciated
Makefile
CPP=g++
OBJ=obj
SRC=src
BIN=bin
CPPFLAGS=-I$(SRC)
GTEST_DIR=../googletest/googletest
gtest:
mkdir -p $(OBJ)
${CPP} -I${GTEST_DIR}/include -I${GTEST_DIR} \
-pthread -c ${GTEST_DIR}/src/gtest-all.cc -o $(OBJ)/gtest-all.o
ar -rv $(OBJ)/libgtest.a $(OBJ)/gtest-all.o
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
$(OBJ)/gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I${GTEST_DIR}/include -I$(GTEST_DIR) $(CXXFLAGS) -c
\
$(GTEST_DIR)/src/gtest_main.cc -o $#
$(OBJ)/gtest_main.a : $(OBJ)/gtest-all.o $(OBJ)/gtest_main.o
$(AR) $(ARFLAGS) $# $^
$(OBJ)/%.o: $(SRC)/%.cpp
$(CPP) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
.PHONY: test clean
test: $(OBJ)/Matrix-Multiply.o $(OBJ)/gtest_main.a
mkdir -p $(BIN)
$(CPP) -I${GTEST_DIR}/include $(SRC)/Matrix-Multiply_unittests.cpp \
$(OBJ)/gtest_main.a $(OBJ)/Matrix-Multiply.o -o $(BIN)/Matrix-
Multiply_unittests -pthread
$(BIN)/Matrix-Multiply_unittests
clean:
rm -f $(BIN)/*
rm -f $(OBJ)/*
I think by #include "Matrix-Multiply.cpp" you are including the functions once.
Also (although not shown), you are linking with Matrix-Multiply on the link line.
You should not normally include a .cpp file. They are better bound by linking the file.
g++ -o my_awesome_app main.o Matrix-Multiply.o otherfile.o

SystemC Make Errors: Type Mismatch Member Assignment

Hello I am seeing some errors in my attempts to make a basic SystemC project. It looks like a slight mismatch of types, but I am not familiar enough with the types from the SystemC library to really know what the issue is. I have more or less taken the code directly from this tutorial.
https://www.youtube.com/watch?v=DSg4PMoUCX4
Currently, my Makefile looks like this
CXX=g++
OBJ= main.o fir_filter.o test_bench.o
INC=- -I /home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include -I /home/epi/jfrye_xilinx/SystemC/lib/fir_filter/src
LFLAGS=-L/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/lib-linux64
LIBS=-lsystemc
EXEC=test_fir
all: $(OBJ)
$(CXX) $(OBJS) -o $(EXEC)
main.o: main.cpp
$(CXX) $(INC) $(LFLAGS) $(LIBS) main.cpp
fir_filter.o: fir_filter.cpp fir_filter.h
$(CXX) $(INC) $(LFLAGS) $(LIBS) fir_filter.cpp
test_bench.o: test_bench.cpp test_bench.h
$(CXX) $(INC) $(LFLAGS) $(LIBS) test_bench.cpp
I am seeing these errors when I run make
main.cpp:28:19: error: no match for call to
(sc_core::sc_in<sc_dt::sc_uint<16> >)
(sc_core::sc_signal<sc_dt::sc_int<16> >&)
fir->inp(inp_sig);
main.cpp:29:21: error: no match for call to
(sc_core::sc_out<sc_dt::sc_uint<16> >)
(sc_core::sc_signal<sc_dt::sc_int<16> >&)
fir->outp(outp_sig);
Here is main.cpp
#include <systemc.h>
#include "fir_filter.h"
#include "test_bench.h"
SC_MODULE(SYSTEM)
{
test_bench *tb;
fir_filter *fir;
sc_signal<bool> rst_sig;
sc_signal< sc_int<16> > inp_sig;
sc_signal< sc_int<16> > outp_sig;
sc_clock clk_sig;
SC_CTOR(SYSTEM)
: clk_sig("clk_sig", 10, SC_NS)
{
tb = new test_bench("tb");
tb->clk(clk_sig);
tb->rst(rst_sig);
tb->inp(inp_sig);
tb->outp(outp_sig);
fir = new fir_filter("fir");
fir->clk(clk_sig);
fir->rst(rst_sig);
fir->inp(inp_sig);
fir->outp(outp_sig);
}
~SYSTEM()
{
delete tb;
delete fir;
}
};
SYSTEM *top = NULL;
int sc_main(int argc, char *argv[])
{
top = new SYSTEM("top");
sc_start();
return 0;
}
And lastly, fir_filter.h
#include <systemc.h>
SC_MODULE( fir_filter )
{
sc_in<bool> clk;
sc_in<bool> rst;
sc_in< sc_uint<16> > inp;
sc_out< sc_uint<16> > outp;
void fir_main();
SC_CTOR( fir_filter )
{
SC_CTHREAD( fir_main, clk.pos());
reset_signal_is( rst, true);
}
};
Update:
Thanks to the answers provided, I was able to change the two modules to ensure that the types were matching, whether signed or unsigned.
However make is still giving me this error. I did not include it originally because I did not realize it would break compilation.
g++: error: -E or -x required when input is from standard input make:
*** [main.o] Error 1
In your SYSTEM module, it shouldn't be :
sc_signal< sc_int<16> > inp_sig;
sc_signal< sc_int<16> > outp_sig;
but instead :
sc_signal< sc_uint<16> > inp_sig;
sc_signal< sc_uint<16> > outp_sig;
as inp in the FIR Filter module is a sc_in< sc_uint<16> >.

How do you wrap C++ OpenCV code with Boost::Python?

I want to wrap my C++ OpenCV code with boost::python, and to learn how to do it, I tried a toy example, in which
I use the Boost.Numpy project to provide me with boost::numpy::ndarray.
The C++ function to be wrapped, square() takes a boost::numpy::ndarray and modifies it in place by squaring each element in it.
The exported Python module name is called test.
The square() C++ function is exported as the square name in the exported module.
I am not using bjam because IMO it is too complicated and just doesn't work for me no matter what. I'm using good old make.
Now, here's the code:
// test.cpp
#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <boost/scoped_array.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
namespace py = boost::python;
namespace np = boost::numpy;
void square(np::ndarray& array)
{
if (array.get_dtype() != np::dtype::get_builtin<int>())
{
PyErr_SetString(PyExc_TypeError, "Incorrect array data type.");
py::throw_error_already_set();
}
size_t rows = array.shape(0), cols = array.shape(1);
size_t stride_row = array.strides(0) / sizeof(int),
stride_col = array.strides(1) / sizeof(int);
cv::Mat mat(rows, cols, CV_32S);
int *row_iter = reinterpret_cast<int*>(array.get_data());
for (int i = 0; i < rows; i++, row_iter += stride_row)
{
int *col_iter = row_iter;
int *mat_row = (int*)mat.ptr(i);
for (int j = 0; j < cols; j++, col_iter += stride_col)
{
*(mat_row + j) = (*col_iter) * (*col_iter);
}
}
for (int i = 0; i < rows; i++, row_iter += stride_row)
{
int *col_iter = row_iter;
int *mat_row = (int*)mat.ptr(i);
for (int j = 0; j < cols; j++, col_iter += stride_col)
{
*col_iter = *(mat_row + j);
}
}
}
BOOST_PYTHON_MODULE(test)
{
using namespace boost::python;
def("square", square);
}
And here's the Makefile:
PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)
BOOST_INC = /usr/local/include
BOOST_LIB = /usr/local/lib
OPENCV_LIB = $$(pkg-config --libs opencv)
OPENCV_INC = $$(pkg-config --cflags opencv)
TARGET = test
$(TARGET).so: $(TARGET).o
g++ -shared -Wl,--export-dynamic \
$(TARGET).o -L$(BOOST_LIB) -lboost_python \
$(OPENCV_LIB) \
-L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) \
-o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
g++ -I$(PYTHON_INCLUDE) $(OPENCV_INC) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp
With this scheme, I can type make and test.so gets created. But when I try to import it,
In [1]: import test
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-73ae3ffe1045> in <module>()
----> 1 import test
ImportError: ./test.so: undefined symbol: _ZN5boost6python9converter21object_manager_traitsINS_5numpy7ndarrayEE10get_pytypeEv
In [2]:
This is a linker error which I can't seem to fix. Can anyone please help me with what's going on? Do you have (links to) code that already does integrate OpenCV, numpy and Boost.Python without things like Py++ or the likes?.
Okay I fixed this. It was a simple issue, but a sleepy brain and servings of bjam had made me ignore it. In the Makefile, I'd forgotten to put -lboost_numpy that links the Boost.Numpy libs to my lib. So, the modified Makefile looks like this:
PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)
BOOST_INC = /usr/local/include
BOOST_LIB = /usr/local/lib
OPENCV_LIB = $$(pkg-config --libs opencv)
OPENCV_INC = $$(pkg-config --cflags opencv)
TARGET = test
$(TARGET).so: $(TARGET).o
g++ -shared -Wl,--export-dynamic \
$(TARGET).o -L$(BOOST_LIB) -lboost_python -lboost_numpy \
$(OPENCV_LIB) \
-L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) \
-o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
g++ -I$(PYTHON_INCLUDE) $(OPENCV_INC) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp