MEX compilation error - c++

I'trying to compile the c code with mex for MATLAB 2013a 64 under win7 64
http://www.cs.cornell.edu/People/tj/svm%5Flight/svm_perf.html
According to info from this site the SVMPerf MATLAB interface was done by O Luaces
but only for Linux and MACos and it don't compile under windows
http://www.aic.uniovi.es/~oluaces/Oscars_Home_Page/Personal.html
for this i installed gnumex to have access to gcc for MATLAB and this is ok.
then I compiled with mex and created object files for all involved c programs according
to make file from SVMPerf.
I also compiled mex_interface.cpp file which was used for MATLAB interface under LINUX.
However when I try to link all files I'm getting following error related to my_malloc
svm_learn_main.obj:svm_learn_main.c:(.text+0x470): first defined here
svm_struct_main.obj:svm_struct_main.c:(.text.startup+0x0): multiple definition of
`main'
svm_learn_main.obj:svm_learn_main.c:(.text.startup+0x0): first defined here
Cannot export mexFunction: symbol not defined
mex_interface.obj:mex_interface.cpp:(.text+0x94): undefined reference to
`my_malloc(unsigned long long)'
mex_interface.obj:mex_interface.cpp:(.text+0x218): undefined reference to
`my_malloc(unsigned long long)'
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.0/../../../../x86_64-w64-mingw32
/bin/ld.exe: mex_interface.obj: bad reloc address 0x0 in section `.pdata'
collect2.exe: error: ld returned 1 exit status
link command: gcc -shared C:\Users\KRZYSZ~1\AppData\Roaming\MATHWO~1\MATLAB\R2013a
\gnumex\mex.def -o svm_perf_classify.mexw64 -LC:\Users\KRZYSZ~1\AppData\Roaming
\MATHWO~1\MATLAB\R2013a\gnumex -s mex_interface.obj my_malloc.obj svm_learn_main.obj
svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj -llibmx -llibmex
-llibmat
I believe it points to this code. my_malloc compiles OK. Any idea ??
void create_argc_argv(const mxArray *options,int *argc,char **argv[]) {
// convert the matlab string of options into a CLI-like input (argc and argv)
*argc=1;
mwSize buflen = mxGetN(options)*sizeof(mxChar)+1;
char *buf = mxMalloc(buflen);
// Copy the string data into buf
mxGetString(options, buf, buflen);
// and separate in argv[]
char **ap, **argv_ptr=(char **)my_malloc(MAX_ARGVS*sizeof(char *));
argv_ptr[0]="OLR";
for (ap = (argv_ptr+1); (*ap = strsep(&buf, " \t")) != NULL;)
if (**ap != '\0') {
(*argc)++;
if (++ap >= &argv_ptr[MAX_ARGVS])
break;
}
// 'buf' shouldn't be freed, since it is converted to the different 'argv[i]'
// by setting to '\0' the tabs and white spaces between options
// (this trick was taken from the 'strsep' man page)
// so, we don't make mxFree(buf);
*argv=argv_ptr;
}
my mex command looks like this
mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_learn_main.obj svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj

It looks like the issue you have isn't MEX related, as the main function is declared more than once. Which makes it hard for the compiler to know where to start running the code. If you have public functions you want to use in svm_learn_main or svm_struct_main, you'll want to separate those from the files containing the main function.

mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_perf_classify does not have a source file extension(.c or .cpp or other), so it's considered a executable by compiler.

Related

How to run a Fortran program within GNU Octave?

I want to run a Fortran program within Octave. I would like to do this for automation purposes and use Octave for all the data processing.
Is it possible to run a Fortran program from octave using cygwin, if so, could you provide me some pointers along that direction?
Moreover, I have a gfortran compiler installed in my system, Is there a way I could make use of it to complete my task mentioned above?
Furthermore, I tried to use mex to perform the same:
mckoctfile --mex HelloWorld.f
I got the following error after trying the mex approach:
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `hi': C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_transfer_character_write'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:3: undefined reference to `_gfortran_st_write_done'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\rajan\AppData\Local\Temp/oct-qur1RF.o: in function `main':C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_args'
c:/octave/octave~1.0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tech Stuff\Fortran Programs/HelloWorld.f:6: undefined reference to `_gfortran_set_options'
collect2.exe: error: ld returned 1 exit status
warning: mkoctfile: building exited with failure sta
How do I resolve this error to move forward?
Obviously your particular use-case may be a lot more complex than this, but here's a simple example to get you started (or to help you decide whether it's worth going down that route at all...)
Let's start with a simple octfile which performs simple integer addition, no fortran involved for now.
// in: simple_addition.cpp
#include <octave/oct.h>
DEFUN_DLD (simple_addition, args, ,"Add two integers via C++")
{
octave_value retval = args(0).int_value() + args(1).int_value();
return retval;
}
Compile:
mkoctfile -c simple_addition.cpp # compiles a simple_addition.o file
mkoctfile -o simple_addition simple_addition.o # links .o file to named output file
In octave:
octave:1> simple_addition(1,2)
ans = 3
Now let's put this aside for a minute, and see how we might call a fortran-defined function from pure c++. First let's create a simple integer addition function:
! in fortran_addition.f90
function fortran_addition(a,b) result(Out)
integer, intent(in) :: a,b ! input
integer :: Out ! output
Out = a + b
end function fortran_addition
and compile it using gfortran:
gfortran -c fortran_addition.f90 # creates fortran_addition.o
You can see (e.g. using nm fortran_addition.o) that the generated object contains a reference to a symbol under the name fortran_addition_ (note the added underscore at the end).
Now let's create a normal (i.e. non-octave-related) c++ wrapper program which calls the function defined via this symbol:
// in generic_fortran_addition_wrapper.cpp
#include <iostream>
extern "C" { int fortran_addition_( int *, int * ); }
int main() {
int a = 1, b = 2, fortran_result;
fortran_result = fortran_addition_( &a, &b );
std::cout << a << " + " << b << " = " << fortran_result << std::endl;
}
compile:
g++ -c generic_fortran_addition_wrapper.cpp
g++ -o addints generic_fortran_addition_wrapper.o fortran_addition.o
./addints # outputs `1 + 2 = 3` on the terminal
Now we have all the ingredients to create an octfile that wraps a fortran function:
// in fortran_addition_wrapper.cpp
#include <octave/oct.h>
extern "C" { int fortran_addition_( int *, int *); }
DEFUN_DLD (fortran_addition_wrapper, args, ,"Add two integers via fortran")
{
int a, b, fortran_result;
a = args(0).int_value();
b = args(1).int_value();
fortran_result = fortran_addition_( &a, &b );
octave_value retval(fortran_result);
return retval;
}
compile with mkoctfile:
mkoctfile -c fortran_addition_wrapper.cpp
mkoctfile -o fortran_addition_wrapper fortran_addition_wrapper.o fortran_addition.o
and then in octave:
octave:1> fortran_addition_wrapper(1,2)
ans = 3
Having said all this, obviously if you have a fully defined fortran program, rather than just linkable functions, and you have a running compiled executable on your system, then you can skip all the above 'formalities' and just call your executable via the system() command from octave. Obviously in this scenario it's up to you to pass the data in an octave-agnostic way ... but presumably if you have a standalone fortran executable, then presumably it already has a way of reading input data from the operating system.
EDIT as per the comments below, I've been reminded that I got side-tracked and answered the question that was asked in the comments to the original question, and forgot to address the error messages in the original question. As mentioned in my comment there, mkoctave is a generic wrapper to the gnu compiler collection. Those messages do not sound specific to octave, but rather that the compiler/linker complains that you're missing the fortran runtime libraries that define these basic functions.

test.c:(.text+0x36): undefined reference to `md5_file'

I installed polarssl:
make
sudo make install
tried to compile very simple file, named test.c:
#include <stdio.h>
#include "polarssl/md5.h"
int main(int argc, char * argv[])
{
int i;
for (i=1;i<1;i++)
{
char res[16];
if (md5_file("file.txt",res) == 0)
{
int count;
for (count=0;count<16;count++)
printf("%02x",res[count]);
printf("n");
}
}
return 0;
}
Compiled it like this:
gcc -lpolarssl test.c -I /usr/local/include/polarssl/
but it shows me:
/tmp/cczptlsk.o: In function `main':
test.c:(.text+0x36): undefined reference to `md5_file'
collect2: ld returned 1 exit status
whats the problem, how to fix it? I know for 100% that polarssl files are in /usr/local/include/polarssl/
The compiler will attempt to complete linkage in the order the objects or files are presented. In this case, since you had put -lpolarssl first, there were no unresolved symbols needed from that library, so nothing got linked in.
Putting -lpolarssl last lets the compiler resolve unresolved symbols from your source file from that library.
Includes are fine.
But linking is wrong. Try to put the -lpolarssl last in the linker command.
Then add a -L if libpolarssl.a is not found by the linker to point it to the right location.

runtime initialization a const

I have a header (only) file constants.h, where I define all the constant variables, to be used later in the library. However, there is one variable, which I would like to define run-time in an implementation file. I tried to do something like this:
constant.hpp
extern const unsigned int numTests;
somewhere else in run.cpp
const unsigned int numTests = 10;
and, then yet another file tester.cpp uses
if ( n < numTests) {
// do something
}
Now, when I compile it, I get a linker error in tester.o as undefined symbol numTests. I sort of understand why this is happening: the tester.cpp includes constants.hpp and not the run.cpp and so, it can not find the constant numTests initialized in run.cpp.
Is there any better way to do it?
TIA,
Nikhil
Make sure you are compiling both run.cpp and tester.cpp when you compile your program and you won't get a linker error.
You need to link run.o when creating the executable:
g++ -o tester tester.cpp run.o ; for GNU C++
(Check your own compiler's command line switches if you're not using GNU C++)

MinGW Doesn't Generate an Object File When Compiling

I've just bought a new laptop for me on the travel, then on my free time, I've started to test MinGW on it by trying to compile my own OS that is written in C++, then I've created all the files needed and the kernel.cpp:
extern "C" void _main(struct multiboot_data* mbd, unsigned int magic);
void _main( struct multiboot_data* mbd, unsigned int magic )
{
char * boot_loader_name =(char*) ((long*)mbd)[16];
/* Print a letter to screen to see everything is working: */
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
}
And tried to compile it with g++
G:> g++ -o C:\kernel.o -c kernel.cpp -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs
kernel.cpp: In function `void _main(multiboot_data*, unsigned int)':
kernel.cpp:8: warning: unused variable 'boot_loader_name'
kernel.cpp: At global scope:
kernel.cpp:4: warning: unused parameter 'magic'
G:>
But it don't create any binary file at C:/>.
What can I do?
It doesn't create the file because you have -Werror enabled. The warnings you're getting about unused variables are counting as errors, so compilation gets aborted. Just comment them out for the moment:
void _main( struct multiboot_data* mbd, unsigned int /* magic */ )
{
// char * boot_loader_name =(char*) ((long*)mbd)[16];
// ...
}
And it should build fine. Also, shouldn't _main() be declared as just main() and then allowed to be "mangled" into _main() by the compiler? Edit: You probably also want to be using -c to skip the linking phase, assuming you just want the object files.
Did you try creating the .o file in a local directory first? What result did you get?
C:\ is usually blocked for writing on Vista and 7, since it's considered a very sensitive location, and you have to run as administrator to be allowed to do that (as in, explicitly launching the command prompt or g++ with admin rights). The same should apply if you're running on a "regular" (non-admin) user account, even in XP.
Perhaps that's what's happening to you?

g++ undefined reference to constructor

I'm compiling and linking a cpp file against a pre-compiled library, and I'm getting an "undefined reference" error.
Firstly, this is the command (the library in question is quicknet3, the program I'm compiling is trapper):
g++ -w -g -I. -g -O3 -pipe -Wall -I/home/install/x86_64/include/quicknet3 -L/home/install/x86_64/lib -lquicknet3 -lintvec -lfltvec -o trapper trapper.cpp CMyException.cpp
Here's the undefined reference error:
/tmp/ccFuVczF.o: In function 'main':
trapper.cpp:1731: undefined reference to 'QN_InFtrLabStream_PFile::QN_InFtrLabStream_PFile(int, char const*, _IO_FILE*, int)'
The call in trapper.cpp (line 1731) is:
IN_PFILE = new QN_InFtrLabStream_PFile(0, "", fp, 1);
where fp is a FILE *, assigned as the result of an fopen call beforehand.
The constructor being called is defined in the relevant header file (QN_Pfile.h), as follows:
class QN_InFtrLabStream_PFile : public
QN_InFtrLabStream
{
public:
QN_InFtrLabStream_PFile(int a_debug, const char* a_dbgname, FILE* a_file, int a_indexed);
(... other declarations ...)
}
The definition of the constructor is indeed given in QN_Pfile.cc:
QN_InFtrLabStream_PFile::QN_InFtrLabStream_PFile(int a_debug,const char* a_dbgname, FILE* a_file, int a_indexed) : log(a_debug, "QN_InFtrLabStream_PFile", a_dbgname),file(a_file),indexed(a_indexed),buffer(NULL),sentind(NULL)
{
(... the usual constructor stuff :P ...)
}
I compiled the quicknet3 library myself, without error, and installed it to /home/install/x86_64/lib/libquicknet3.a
So, I can't understand why the call from trapper.cpp is unable to find the reference to this constructor definition. The g++ arguments of -L/home/install/x86_64/lib -lquicknet3 should do the trick, right?
Any ideas?
Thanks,
Roy
I notice that you're mixing FILE* and _IO_FILE*. I'm not familiar with the latter, are you sure they're one and the same?
A quick workaround is to add /home/install/x86_64/lib/libquicknet3.a to g++ commandline.
I you want to investigate further, if g++ is picking another copy of libquicknet3, you can pass -v to g++ so it will output its searching paths.
FILE is a typedef of _IO_FILE. Your linker is treating it as a unique type.
You could try:
IN_PFILE = new QN_InFtrLabStream_PFile(0, "", (FILE *)fp, 1);
to see if this resolve your constructor.
(FILE is defined in stdio.h, _IO_FILE in libio.h if you're interested)