How to configure mex for MATLAB 2011 with MinGW - c

I'm running 64 bit windows and 64 bit matlab. Following the instructions of an answer to a question on stackoverflow, I tried to configure a make file to compile my C function for use in matlab.
Here is the Makefile file:
MINGWPATH=/cygdrive/c/cygwin
CYGPATH=/cygdrive/c/cygwin
MATLABROOT=/cygdrive/c/Progra~1/MATLAB/R2011a
CC=i686-pc-mingw32-gcc
CFLAG= -Wall -m32 -O3 -Iinclude -I$(MATLABROOT)/extern/include $(SRC) $(LIBS) -o $(EXE)
MEXFLAG=-m64 -shared -DMATLAB_MEX_FILE -I$(MATLABROOT)/extern/include -Wl,--export-all-symbols $(LIBS) $(MEXSRC) -o $(MEXTGT).mexw64
LIBS= -Llib -L$(MATLABROOT)/bin/win64 -L$(MATLABROOT)/extern/lib/win64/microsoft -lmex -lmx -lmwlapack -lmwblas -leng
EXE= gopenfunction.exe
MEXTGT= gopenfunction.m
SRC= gopenfunction.c
MEXSRC = gopenfunction.c
all:$(EXE)
$(EXE): $(SRC)
$(CC) $(CFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o $(EXE)
Output
$ make
i686-w64-mingw32-gcc -Wall -m32 -O3 -Iinclude -I/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include gopenfunction.c -Llib -L/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64 -L/cygdrive/c/Progra~1/MATLAB/R2011a/extern/lib/win64/microsoft -lmex -lmx -lmwlapack -lmwblas -leng -o gopenfunction.exe -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o gopenfunction.exe
/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64/libmex.dll: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:18: recipe for target 'gopenfunction.exe' failed
make: *** [gopenfunction.exe] Error 1
I also tried:
i686-w64-mingw32-gcc -m32 -shared -Iinclude -I"/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.c -L"/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64" -lmex -lmx -leng -lmat
I am using GCC because I cannot find VS2008 or 2010, only VS Community 2015 which doesn't work when I try to setup with mex via mex -setup
Note that I changed from -m64 to -m32 because otherwise I received the error below. I'm not entirely sure what it does.
$ i686-w64-mingw32-gcc -m64 -shared -Iinclude -I"/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.c -L"/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64" -lmex -lmx -leng -lmat
gopenfunction.c:1:0: sorry, unimplemented: 64-bit mode not compiled in
#include "gclibo.h"
Visual Studio Follow-Up
After installing Microsoft Visual C++ the compiler option popped up but requires the SDK. Attempting to install the sdk results in an error 'visual studio 2010 must be installed.' I also installed .NET 4 and SDK for Windows 7 as per the supported compilers for MATLAB 2011 page.
>> mex -setup
Welcome to mex -setup. This utility will help you set up
a default compiler. For a list of supported compilers, see
http://www.mathworks.com/support/compilers/R2011a/win64.html
Please choose your compiler for building MEX-files:
Would you like mex to locate installed compilers [y]/n? y
Select a compiler:
[1] Microsoft Visual C++ 2010 Express in C:\Program Files (x86)\Microsoft Visual Studio 10.0\
[0] None
Compiler: 1
Please verify your choices:
Compiler: Microsoft Visual C++ 2010 Express
Location: C:\Program Files (x86)\Microsoft Visual Studio 10.0\
Are these correct [y]/n? y
*****************************************************************************
Error: Microsoft Visual C++ 2010 Express requires the Microsoft Windows
Software Development Kit (SDK), but the SDK cannot be found.
For more information about the required SDK, see:
http://www.mathworks.com/support/compilers/R2011a/win64.html
*****************************************************************************
??? Error using ==> mex at 208
Unable to complete successfully.
Cygwin Follow-Up
I changed the compiler but now there is an undefined reference to 'WinMain.'
$ make
x86_64-w64-mingw32-gcc -Wall -m64 -O3 -Iinclude -I/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include gopenfunction.c -Llib -L/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64 -L/cygdrive/c/Progra~1/MATLAB/R2011a/extern/lib/win64/microsoft -lmex -lmx -lmwlapack -lmwblas -leng -o gopenfunction.exe -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o gopenfunction.exe
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
/usr/src/debug/mingw64-x86_64-runtime-4.0.2-1/crt/crt0_c.c:18: undefined reference to `WinMain'
collect2: error: ld returned 1 exit status
Makefile:18: recipe for target 'gopenfunction.exe' failed
make: *** [gopenfunction.exe] Error 1
edit - using the second method, I was able to compile using the new x86_64 compiler.
x86_64-w64-mingw32-gcc -m64 -shared -Iinclude -I"/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.c -L"/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64" -lmex -lmx -leng -lmat
edit2 - after investigating, the absence of -shared option is what causes the 'WinMain' error. I would really appreciate an explanation. I don't know anything about dlls, import libraries, shared libraries, etc, except that they are used at runtime. On the whole my problem has been solved and I thank everyone for their help.
$ x86_64-w64-mingw32-gcc -m64 -shared -Iinclude -I"/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include" -o bla.mexw64 *.c -L"/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64" -lmex -lmx -leng -lmat
$ x86_64-w64-mingw32-gcc -m64 -Iinclude -I"/cygdrive/c/Progra~1/MATLAB/R2011a/extern/include" -o bla.mexw64 *.c -L"/cygdrive/c/Progra~1/MATLAB/R2011a/bin/win64" -lmex -lmx -leng -lmat
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
/usr/src/debug/mingw64-x86_64-runtime-4.0.2-1/crt/crt0_c.c:18: undefined reference to `WinMain'
collect2: error: ld returned 1 exit status
edit3 - looking at the original makefile in the question linked at the start, all of the above is already there under the $(MEXTGT) target. I just didn't understand how that would be called or used so I foolishly deleted it.

Despite having "w64" in the file name, i686-w64-mingw32-gcc.exe generates 32-bit binaries.
To generate 64-bit binaries, use x86_64-w64-mingw32-gcc.exe. In the cygwin package installer, look for mingw64-x86_64-.
"mingw64" GCC toolchains in the list below. The first targets 32-bit systems and the second 64-bit. They are named this way because they are from the "GCC for Win64" project (cygwin is not the only source for these toolchains). Also get the C toolchains (not shown below).
Also, based on my experience with the standalone mingw64, you probably need to add the following compiler flags to what you have:
-m64 -mwin32 -mdll ...
And you do need -shared as a linker flag.

Related

Proper way of using link time opimization with source and assembly files?

I'm currently playing around with LTO for an embedded system (to see if it could reduce the size) and was having some issues getting everything to link properly using ld directly and was wondering what I was doing wrong. This is mostly playing with a toy program before I use this in a larger project.
The setup is basically I have 3 files:
test.c - data transform function
test_main.c - calls a function defined in start.S
start.S - calls a function in test.c and also contains _start
I compile the files using:
arm-none-eabi-as -mthumb -Wall start.S -o start.o
arm-none-eabi-gcc -Wall -Werror -march=armv7 -mtune=cortex-r7 -mthumb -fPIC -nostdlib -flto -static test.c -c test.o
arm-none-eabi-gcc -Wall -Werror -march=armv7 -mtune=cortex-r7 -mthumb -fPIC -nostdlib -flto -static test_main.c -c test_main.o
If I then try to link the program with ld I get:
arm-none-eabi-ld --static -fPIC --shared --fatal-warning test.o start.o test_main.o -test
arm-none-eabi-ld: test.o: plugin needed to handle lto object
arm-none-eabi-ld: test.o: plugin needed to handle lto object
arm-none-eabi-ld: test_main.o: plugin needed to handle lto object
arm-none-eabi-ld: test_main.o: plugin needed to handle lto object
If I use gcc though, it works:
arm-none-eabi-gcc -Wall -Werror -march=armv7 -mtune=cortex-r7 -mthumb -fPIC -nostdlib -flto -static test.o start.o test_main.o -o test.gcc
I have tried specifying the linker plugin directly but then I get a different error:
arm-none-eabi-ld --static -fPIC --shared --fatal-warning --plugin <path_to_correct>/liblto_plugin.so test.o start.o test_main.o -test
arm-none-eabi-ld: <path_to_correct>.../lto-plugin.c:741: all_symbols_read_handler: Assertion 'lto_wrapper_argv' failed.
Aborted (core dumped)
What flags, parameters, etc. am I missing in my ld call?

installed check for c but "check.h" not found

Im using windows 10 with wsl ubuntu 18.04 Im trying to run the code from here :
https://www.ccs.neu.edu/home/skotthe/classes/cs5600/fall/2015/labs/intro-check-lab-code.tgz
I installed gcc, makefile, and check in the ubuntu terminal. But when I di $ make it says:
gcc money.o check_money.o -lcheck -lm -lpthread -lrt -lgcov -coverage -o check_money_tests
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libcheck.a(check_log.o): In function `subunit_lfun':
(.text+0x5f4): undefined reference to `subunit_test_start'
(.text+0x6bf): undefined reference to `subunit_test_fail'
(.text+0x6d4): undefined reference to `subunit_test_pass'
(.text+0x6ef): undefined reference to `subunit_test_error'
collect2: error: ld returned 1 exit status
Makefile:23: recipe for target 'check_money_tests' failed
make: *** [check_money_tests] Error 1
so I open the check_money.c it says that check.h cannot be found. What did I miss here?
Simple version: you should also link with -lsubunit flag, i.e.:
TST_LIBS = -lcheck -lm -lpthread -lrt -lsubunit
Better yet, all the flags should be taken from check's package configuration, as the requirements depend on how the check library was built (and that's what pkg-config has been invented for). So instead of hardcoding your options, you could improve your Makefile like this:
CFLAGS = -c -Wall $(shell pkg-config --cflags check)
TST_LIBS = $(shell pkg-config --libs check)
Result:
$ make
gcc -c -Wall -pthread -fprofile-arcs -ftest-coverage src/*.c
gcc -c -Wall -pthread -fprofile-arcs -ftest-coverage tests/*.c
gcc money.o check_money.o -lcheck_pic -pthread -lrt -lm -lsubunit -lgcov -coverage -o check_money_tests
...

Building a C application against an external library on linux

I'm working on a Linux project in C consisting of two different open source applications. "Project A" (libduo) creates an archive used for linking a couple test programs and creates the library like this:
/usr/bin/ar rv libduo.a duo.o http_parser.o https.o match.o parson.o urlenc.o
/usr/bin/ar: creating libduo.a
a - duo.o
a - http_parser.o
a - https.o
a - match.o
a - parson.o
a - urlenc.o
ranlib libduo.a
One of the libduo test programs is built like this:
gcc -g -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -I. -I. -DDUODIR=\"/usr/local/duo/libduo/etc\" -DHAVE_CONFIG_H -c test-duologin.c
gcc -o test-duologin test-duologin.o -L. -lduo -lssl -lcrypto
"Project B" is an OpenLDAP module which I've built with -lduo and a few options to tell it where to find things:
(cd .libs && rm -f pw-apr1.la && ln -s ../pw-apr1.la pw-apr1.la)
../../../libtool --mode=compile gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c
gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c -fPIC -DPIC -o .libs/pw-duo.o
gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c -o pw-duo.o >/dev/null 2>&1
../../../libtool --mode=link gcc -g -O2 -Wall -version-info 0:0:0 \
-rpath /usr/local/libexec/openldap -module -o pw-duo.la pw-duo.lo libduo.a -lduo
*** Warning: Linking the shared library pw-duo.la against the
*** static library libduo.a is not portable!
cc -shared .libs/pw-duo.o libduo.a -lduo -Wl,-soname -Wl,pw-duo.so.0 -o .libs/pw-duo.so.0.0.0
/usr/bin/ld: libduo.a(duo.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
libduo.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:51: recipe for target 'pw-duo.la' failed
make: *** [pw-duo.la] Error 1
The Makefile I'm using is the same one distributed with the OpenLDAP project. I've just added a section in the Makefile to build my module, using the same options for the other modules already there but adding -lduo to my section along with the paths to the libduo includes and libduo.a.
As make suggests above, I've recompiled by adding -fPIC after the -Wall option but it the same error was repeated. As a last resort, I tried adding -static to the module build but make was having none of that either:
*** Warning: Linking the shared library pw-duo.la against the
*** static library libduo.a is not portable!
This is the first time I've tried to build a C application against a lib not in the standard Linux locations so not exactly sure what's going on. I suspect libduo is built intended to be statically linked into everything, but the OpenLDAP modules are designed to use shared libraries. Can anyone elucidate?
Update: with help of comments below and this link I created a shared library from the .o files and distributed/built against that.

Problems building DBD Sybase on Debian

I am trying to build DBD::Sybase on Debian machine, but I am running into a problem. The problem is, BFD (GNU Binutils) 2.21.1 internal error when linking the program. Please help me resolve this.
I successfully installed freetds
Downloaded "DBD-Sybase-1.16"
Executed "perl Makefile.PL INSTALL_BASE=/usr/lib/perl5/" which was successfull
When I execute "sudo make", I get the following error. I tried googling but could not find help.
Here is the tail of the build.
Skip blib/lib/DBD/Sybase.pm (unchanged)
Skip blib/lib/DBD/dbd-sybase.pod (unchanged)
Running Mkbootstrap for DBD::Sybase ()
chmod 644 Sybase.bs
/network/glnxa64/gcc-4.7.2/bin/gcc -c -I/usr/local/freetds/include -DSYB_LP64 -DNO_BLK=1 -I/company/hub/share/apps/BuildTools/Linux/glibc-2.13/x86_64/perl/perl-5.20.2-mw-021/lib/site_perl/5.20.2/x86_64-linux-thread-multi/auto/DBI -D_REENTRANT -D_GNU_SOURCE -O2 -pipe -pthread -fPIC -fwrapv -fno-strict-aliasing -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"1.16\" -DXS_VERSION=\"1.16\" -fPIC "-I/company/hub/share/apps/BuildTools/Linux/glibc-2.13/x86_64/perl/perl-5.20.2-mw-021/lib/5.20.2/x86_64-linux-thread-multi/CORE" Sybase.c
/network/glnxa64/gcc-4.7.2/bin/gcc -c -I/usr/local/freetds/include -DSYB_LP64 -DNO_BLK=1 -I/company/hub/share/apps/BuildTools/Linux/glibc-2.13/x86_64/perl/perl-5.20.2-mw-021/lib/site_perl/5.20.2/x86_64-linux-thread-multi/auto/DBI -D_REENTRANT -D_GNU_SOURCE -O2 -pipe -pthread -fPIC -fwrapv -fno-strict-aliasing -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"1.16\" -DXS_VERSION=\"1.16\" -fPIC "-I/company/hub/share/apps/BuildTools/Linux/glibc-2.13/x86_64/perl/perl-5.20.2-mw-021/lib/5.20.2/x86_64-linux-thread-multi/CORE" dbdimp.c
rm -f blib/arch/auto/DBD/Sybase/Sybase.so
LD_RUN_PATH="/usr/local/freetds/lib" /network/glnxa64/gcc-4.7.2/bin/gcc -shared -L/usr/local/freetds/lib -pthread -L/usr/local/lib -fstack-protector Sybase.o dbdimp.o -o blib/arch/auto/DBD/Sybase/Sybase.so \
-L/usr/local/freetds/lib -lct -ldl -lm \
/network/glnxa64/gcc-4.7.2/bin/ld: BFD (GNU Binutils) 2.21.1 internal error, aborting at /local/greg/3p/sources/gcc-4.7/../binutils/bfd/reloc.c line 443 in bfd_get_reloc_size
/network/glnxa64/gcc-4.7.2/bin/ld: Please report this bug.
collect2: error: ld returned 1 exit status
Makefile:485: recipe for target 'blib/arch/auto/DBD/Sybase/Sybase.so' failed
make: *** [blib/arch/auto/DBD/Sybase/Sybase.so] Error 1
As #jww pointed out, the issue was the older version of binutils and gcc. I just edited the generated Makefile in Sybase base directory to point to newer versions of gcc and binutils. FYI, I the versions that worked are "gcc version 6.3.0 " and "GNU ld (GNU Binutils) 2.28.1"

using C and cuda create shared library got error at link stage

I was really struggled with this error when I try to build a shared library. My code utilize the Lapacke library and also CUDA. when I compile them, there are no errors(I compile them as)
gcc -m64 -Wall -fPIC -c xxx.c -o xxx.o $(INC)
where INC includes all directories
INC=-I. -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ I$/home/sniu/lapack-3.5.0/lapacke/include/ -I${CUDA_INSTALL_PATH}/include/ -I/home/sniu/CBLAS/include/
for cuda part, I wrote it as:
nvcc -m64 -arch=sm_20 -Xcompiler -fPIC $(INC) -c xxx.cu -o xxx.o
but I got the error message at the link stage:
gcc -m64 -D_REENTRANT -Wall -fPIC -g -shared -o libjniWrapper.so jniWrapper.o cholesky_inv.o wls_acc.o utils.o -L/home/sniu/lapack-3.5.0 -L/opt/cuda-toolkit/5.5.22/lib64 -lm -llapacke -llapack -lblas -lgfortran -lrt -lcudart -lcublas -ldl
/usr/bin/ld: /home/sniu/lapack-3.5.0/liblapacke.a(lapacke_dpotrf.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/home/sniu/lapack-3.5.0/liblapacke.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
I am very sure libraries are there, I really confused why I got this error.
Any suggestions are appreciated, Thank you so much!

Resources