I have a C++ application that uses WxWidgets. It compiles perfectly with g++ on my computer.
However I need to run the application on a Raspberry Pi 3. Compiling directly on Raspi takes almost an hour.
So I want to do a cross compilation: compile it on my computer and copy the executable to raspberry.
I tried to follow a tutorial, however the generated file is an "x86-64" file:
http://yasriady.blogspot.com/2015/10/how-to-build-wxwidgets-for-raspberry-pi.html
My computer:
Ubuntu 20.04.2 LTS;
g++ 9.3.0;
wxWidgets v3.1.5.0;
build flags for my computer: CC_FLAGS=-std=c++17 -w -c -rdynamic -W wx-config --cxxflags --libs --gl-libs geos-config --cflags -lgeos -lglut -lGLU -lGL -lm -lGLEW .
Should I re-install wxWidgets for arm? I'm new to cross-compilation
Thank you so much
I already have wxWidgets installed and compiling for x86. Afterwards, I installed wxWidgets for arm-linux following the tutorial.
When I run "make for the examples from the samples folder, the generated file is for x86.
Maybe "make" is compiling using the x86 compiler, not the newly installed arm compiler.
You should be able to cross-compile for RPi without any problems, double check that you've specified the correct --host option and didn't get any errors from configure (if you did, look at config.log to see why).
I work for buildroot. My purpose work GUI on my buildroot with Gtk3.0 and Gstreamer1.0. I use Olinuxino A13 so I wrote GUI code(Gtk3.0 hello world example) on this with codeblocks. I use Debian wheezy. I want transfer this code from Debian wheezy to buildroot.
I tried this:
I transferred /path_to_proectfile/bin/Debug/my_program.my_program created by codeblocks. I wrote ./my_program on terminal and code work. I transferred this file to my buildroot but ./my_program does not work. It returns No such file or directory error.
I thought the problem might be compiling and tried compiled on terminal. I use gcc -o my_program main.c 'pkg-config --cflags --libs gtk+-3.0' again work on Debian wheezy terminal. After I transferred to buildroot but result does not change. I tried different compile kind like cc,arm-linux-gnueabi-gcc etc. but every time No such file or directory error.
Finally when I don't use gtk library(Just use printf Hello World), I saw Hello world. When I add gtk library returns No such file or directory error. Have you any suggestion?
You need to cross compile your program with the corresponding buildroot toolchain. It looks like you have transferred a binary which was built against a different libc (this gives a "No such file or directory" error).
The buildroot cross compiler with the correct libc can be used by setting CC to "path_to_buildroot_output/host/bin/arm-linux-*-gcc" (the exact name depends on which toolchain options you have chosen).
Original Question
I am having trouble installing gtk to start building GUIs in C++ on Code::Blocks. Could anyone nudge me in the right direction? I'm running Windows 10 (64-bit) on a Lenovo.
I attempted an installation guide (https://www.youtube.com/watch?v=jvQXvTtSIQo), stack overflow (How do you install GTK+ 3.0 on Windows?), the official GTK installation guide (https://www.gtk.org/download/windows.php), a written guide (http://www.tarnyko.net/repo/gtk3_build_system/tutorial/gtk3_tutorial.htm), and just noticed a very similar stack overflow (Install GTK for c on Windows 10?)
Before this, my PATH environment variable only recorded C:\Users\Owner\AppData\Local\Microsoft\WindowsApps;C:\Users\Owner\AppData\Roaming\npm;C:\Users\Owner\AppData\Local\atom\bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;
I downloaded MinGW from mingw.org. This was to the youtube link's comment that the official is more stable than the one that can be installed with Code::Blocks. I added C:\MinGW\bin to PATH.
Trying the official GTK installation site, I downloaded MSYS2 and used pacman -Syu to install core system packages and pacman -Su to then update. That's the end of that, so I think gtk is officially installed, I just need to get it to talk to Code::Blocks. I added C:\msys64\mingw64\bin to PATH but that didn't seem to work.
I tried to install the all-in-one bundle for GTK 3.6.4 at http://www.tarnyko.net/dl/gtk.htm , and extracted it to C:\gtk. I now have C:\gtk\bin in PATH. GTK should be in my path in one form or the other. I can run gtk3-demo and gtk-demo-application from CMD but not MSYS2. I'm a bit confused about that. It probably has something to do with MSYS2's specific path variable, I think? But it should search the system's PATH afterward? And I don't know how to change that specific path? Probably questions for another day.
So the similar stack overflow, youtube, and written tutorial all say to use pkg-config --cflags --libs gtk+-3.0 to check for a reasonable output to see if I have gtk correctly installed. I installed
pkg-config-lite to avoid the glib circular dependency issue that How to install pkg config in windows? describes and frankly I do not understand. I added it to C:\MinGW\bin to by in my path. Now I am able to run it, but get:
Package gtk+-3.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gtk+-3.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gtk+-3.0' found
I tried 3.6.4 instead of 3.0. No dice. I tried just 3. Nope. I can only find gtk3 files, and not the actual version I installed anywhere. pkg-config --cflags --libs says that I need to name a library, so I tried just gtk hopiing to get libraries containing that. Nope. The rest of the tutorials are aimed at getting Code::Blocks compiler (I think) to include gtk. I hope this is the only obstacle, and I will be able to get the rest. But, if anyone can help me through the rest, it would be appreciated.
At this point I'm out of ideas. Can someone help me?
Gratefully,
John
More Questions After Liberforce's Answer
Thank you for writing up https://www.gtk.org/download/windows.php !! I bet it helps a lot of frustrated newbies like myself. I will kindly offer more proper feedback after I get everything to work. I am stuck on compiling a C/C++ program, if you can help more. Before I get to that, I want to be very clear about the precise steps I took. The step names correspond to your written instructions.
Step 1: Install MSYS2
Alright, resetting everything...
Removed C:/gtk directory from PATH and from computer, aka all the tarnyko files.
Removed C:/MinGW directory from PATH and from computer, effectively uninstalling. I read your conversation with Simon (Unable to compile code with GTK and https://chat.stackoverflow.com/rooms/156828/discussion-between-liberforce-and-simon) about the confusion between MinGW's terminal which includes msys1.0 and MSYS2 terminal which includes MinGW. I figured this would be safer.
Thus, I only have C:\msys64 in PATH (and what I had before, irrelevant to GTK).
Uninstalled MSYS2 (via Add/Remove Programs) and reinstalled using the x86_64 from www.msys2.org. On pacman -Syu, I received error, "msys2-runtime and catgets are in conflict" and "msys2-runtime and libcatgets are in conflict." Entered y to remove both.
I keep uninstalling and reinstallling but I hit the following problem... (5/5) upgrading pacman was at 100% and the warning pops up:
warning: terminate MSYS2 without returning to shell and check for updates again
warning: for example close your terminal window instead of calling exit
The program halts here. I assume this means to close the window. I did, and clicked OK for the dialogue "Processes are running in session: Close anyway?." Window now printed "Hangup signal received" and it is no longer responding. I use task-manager to kill it.
Openning MSYS2 by the desktop application after the first pacman -Syu gave me the dialogue to choose which shell: MSYS2, Mingw-w64 32 bit, Mingw-w64 64 bit. I instead went into the filesystem and openned C:\msys64\msys2_shell.cmd for all future instances.
Ran pacman -Syu to finish installing packages. I restart MSYS2 again, and ran pacman -Su to reveal
:: Starting core system upgrade...
there is nothing to do
:: Starting full system upgrade...
there is nothing to do
pacman -Syuu showed:
:: Synchronizing package databases...
mingw32 is up to date
mingw64 is up to date
msys is up to date
The pacman -Su, pacman -Sy, and pacman -Suu likewise reveal everything okay. Closed and reopenned C:\msys64\msys2_shell.cmd
pkg-cofig just gives "bash: pkg-config: command not found." So I ran pacman -S pkg-config and got that working. update-core, though, which is mentioned in https://github.com/msys2/msys2/wiki/MSYS2-installation cannot be found, and pacman -S update-core will not work. pacman -Ss core turns up:
msys/coreutils 8.26-2 (base) [installed]
The basic file, shell and text manipulation utilities of the GNU operating
system
And other files that seem unrelated. Results of pacman -Ss core likewise seem irrelevant.
pacman --version shows:
.--. Pacman v5.0.1 - libalpm v10.0.1
/ _.-' .-. .-. .-. Copyright (C) 2006-2016 Pacman Development Team
\ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet
'--'
This program may be freely redistributed under
the terms of the GNU General Public License.
Ran "pacman --needed -S bash pacman pacman-mirrors msys2-runtime" to reveal:
warning: bash-4.4.019-2 is up to date -- skipping
warning: pacman-5.0.1-5 is up to date -- skipping
warning: pacman-mirrors-20160112-1 is up to date -- skipping
warning: msys2-runtime-2.10.0-2 is up to date -- skipping
there is nothing to do
I exited out of all msys shells, and ran C:\msys64\autorebase.bat, although not on a 32 bit system. I believe there is a typo when it says to reopen msys2_shell.bat, which I do not have. I openned msys2_shell.cmd. I use pacman -Suu once more to reveal that everything is okay.
Step 2 -> Step 5 (optional): Install build tools
Openned C:\msys64\msys2_shell.cmd and ran "pacman -S mingw-w64-x86_64-gtk3" (GTK+3 package) and "pacman -S mingw-w64-x86_64-toolchain base-devel" (package to develop GTK+3 applications in other languages) (defaulted to all installations when prompted).
Failed to Compile a GTK+3 Application
Restarted computer. Openned C:\msys64\msys2_shell.cmd. Following https://developer.gnome.org/gtk3/stable/gtk-getting-started.html.
Put the simple window tutorial file in C:\Users\Owner\Desktop\test_code\example-0.c . When running gcc pkg-config --cflags gtk+-3.0 -o example-0 example-0.c pkg-config --libs gtk+-3.0 , got the error in my original question. Used "pacman -Ss gtk3" to see two packages I think I need. Ran "pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gtkmm3" .
To answer your questions to Simon about this same error at Unable to compile code with GTK , pkg-config --list-all | grep gtk returns nothing, even after closing and reopenning C:\msys64\msys2_shell.cmd. "which gcc" returns:
which: no gcc
in(/usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:
/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:
/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl)
I see gtk-3.0 under C:\msys64\mingw64\include. I have no idea how to add this to the path. "echo $PKG_CONFIG_PATH" returns:
/usr/lib/pkgconfig:/usr/share/pkgconfig:/lib/pkgconfig
Correctly Compiled a File in Console with GTK+3
Checked that GTK was in Console
I needed to open up MSYS2 in a Mingw-w64 64 bit shell. This can be preformed via the Desktop app for MSYS2 which prompts you which one of three shells you want to open: MSYS2, Mingw32, and Mingw64. Specifically, me installing gtk with the command mingw-w64-x86_64-toolchain means it can only be accessed this way.
Commands in this shell show that I do, in fact, have gtk:
$ pkg-config --modversion gtk+-3.0 --> 3.22.29
$ which gcc --> /mingw64/bin/gcc
Compiled Sample Code from Mingw64 Console
I referenced https://github.com/msys2/msys2/wiki/MSYS2-introduction to learn the file system / drive mounting syntax. I will place the sample code gotten from https://developer.gnome.org/gtk3/stable/gtk-getting-started.html in `/c/Users/Owner/Desktop/test_code/example-0.c'. I just used my favorite IDE, Atom, but any text editor would do.
Openned MSYS2's Mingw64 shell, cd /c/Users/Owner/Desktop/test_code/ , compiled with gcc \pkg-config --cflags gtk+-3.0` -o example-0 example-0.c `pkg-config --libs gtk+-3.0`` , and execute with ./example-0
Unsuccessful to Link GTK+3 and the Code::Blocks Compiler
I Understand some Linker Settings
I went into Code::Blocks. Went to Settings > Compiler... Made sure to use the dropdown box under Selected compiler to select GNU GCC Compiler, and clicked Reset Defaults because of complications when I first installed Code::Blocks. The check boxes under Compiler Flags should all blank after the reset, and so I checked "Have g++ follow the C++14 ISO C++ language standard [-std=c++14]" under General and "Enable all common compiler warnings (overrides many other settings) [-Wall]" under Warnings.
Next to where it says Compiler Flags, I went to Linker settings and added text to Other linker options. I got this text by running pkg-config --cflags gtk+-3.0:
-mms-bitfields -pthread -mms-bitfields -IC:/msys64/mingw64/include/gtk-3.0 -IC:/msys64/mingw64/include/cairo -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/pango-1.0 -IC:/msys64/mingw64/include/fribidi -IC:/msys64/mingw64/include/atk-1.0 -IC:/msys64/mingw64/include/cairo -IC:/msys64/mingw64/include/pixman-1 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/freetype2 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/harfbuzz -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include/gdk-pixbuf-2.0 -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/glib-2.0 -IC:/msys64/mingw64/lib/glib-2.0/include -IC:/msys64/mingw64/include -LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lz -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -lfribidi -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl
Explanation: When compiling from console, I used a command that included the text /pkg-config --cflags gtk+-3.0`` . The backticks mean to run pkg-config --cflags gtk+-3.0 BEFORE the higher-level compilation command, and insert whatever text comes out into the higher-level compilation command. Code::Blocks needs that text under the Linker settings.
I do not Understand the Search Directories
In Settings > Compiler... , beside where it says Compiler Settings, I clicked Search directories. I know you need to do some work here. After this, you go back to Linker Settings to finish, and your Code::Blocks will be ready to go!
If anyone can help me here, or if I figure it out, I would love to finish, in case this helps posterity. I have GTK compiling, and that is good enough for now.
Ok, let's start from the beginning.
Don't use tarnyko packages, they're outdated and not maintained anymore
Official way to get GTK+ 3 on Windows is through MSYS2
Don't blindly follow every guide you find on the internet, mixing them all together and expect things to work. Things change, and something that was advertised at some point can be outdated and plain wrong at the time you read it. If you cook a dish with 3 different recipes at the same time, don't expect it to taste good.
So:
Remove all remnants of the tarnyko bundle
Remove pkg-config-lite. pkg-config is already installed through MSYS2 if you follow official installations
Try to get things working with the MSYS2 guide (pkg-config detection, and compiling a simple GTK+ program) without the Code::Blocks integration first
Once this works, making it work on Code::Block should be a matter of setting some environment variables and pointing to the right pkg-config.
I used gtk+ bundle_2.24.10 32 bit on Windows 7.
I downloaded it from tarnkos, there's no need to do change a single setting in code blocks 17.12.
I've been given a project to run on MATLAB R2011a. As there are several .c files in there - I need to set up GCC as the MEX compiler for that project. However, I cannot seem to find any explanation as to how to set it up. I've tried a script program called gnumex - but it failed (probably set up for an older version of MATLAB).
Any idea how to set it up?
Why not adjust the mexopts.bat file in your directory? That way you can use the "mex" command transparently to compile anything, as usual in MATLAB, the same as if it was configured by MATLAB using mex -setup. I'm surprised nobody did this before.
The file below is for x64 version of Matlab and Mingw. I'm using the TDM Mingw64 distribution, which I installed in p:\mingw64-tdm. I have Matlab installed in p:\matlab\R2012a -- edit those accordingly.
This is the mexopts.bat file I'm using, copy paste this in %USERPROFILE%\AppData\Roaming\MathWorks\MATLAB\R2012a\mexopts.bat:
#echo off
set MINGWPATH=p:\mingw64-tdm
set PATH=%MINGWPATH%\bin;%PATH%
set COMPILER=gcc
set COMPFLAGS=-c -m64 -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE -Wall -std=c99
set OPTIMFLAGS=-O3 -DNDEBUG
set DEBUGFLAGS=-g
set NAME_OBJECT=-o
set LINKER=gcc
set LINKFLAGS=-shared -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
Then you can just try doing this in Matlab:
mex -v p:\matlab\R2012a\extern\examples\mex\yprime.c
which yprime
Should yield b:\code\m\yprime.mexw64 (or whatever the current folder is). Then if you do:
yprime(1,1:4)
You should see:
ans =
2.0000 8.9685 4.0000 -1.0947
Which means you're in business. Good luck!
EDIT Oct 2014: I now use an improved mexopts.bat file than the above with a different MinGW64 (yields slightly faster binary code than TDM's). See my homepage for details and downloads.
In Matlab 2011b, just compile and link directly in mingw64 or cygwin environment.
MINGWPATH=c:/MinGW64
CYGPATH=c:/cygwin
MATLABROOT=c:/Progra~1/MATLAB/R2011b
CC=$(MINGWPATH)/bin/x86_64-w64-mingw32-gcc
CFLAG= -Wall -m64 -O3 -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= -L$(MATLABROOT)/bin/win64 -L$(MATLABROOT)/extern/lib/win64/microsoft -lmex -lmx -lmwlapack -lmwblas -leng
EXE=../bin/engwindemo.exe
MEXTGT=
SRC=engwindemo.c
MEXSRC=
all:$(EXE)
$(EXE): $(SRC)
$(CC) $(CFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o $(EXE)
#rm -f *.o*
$(MEXTGT): $(MEXSRC)
$(CC) $(MEXFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex
#rm -f *.o*
Put this makefile on the source code directory and make. No dll files conversion needed.
As of MATLAB R2015b, MinGW is officially supported!
It's now at the top of the list of supported compilers.
See here for the official instructions for downloading MinGW (they recommend TDB-GCC).
There are several limitations and caveats listed (e.g. don't link with libraries compiled with other compilers, you have to catch your exceptions inside the MEX file, etc.).
Below is my old way of making an XML file to do the same thing.
The years have gone by and MATLAB (as of R2014a) has moved to a new XML-based system for configuring MEX files. MATLAB still temporariily supports legacy .bat files, for now, but it will bother you about it. Another change is that are distinct C and C++ configurations (more later).
What has stayed the same is that you just need to download and extract a MinGW distribution and point MATLAB to it. There is still no need for MSYS, cygwin or gnumex. The only tricky part is pointing MATLAB to it, but here is a solution.
Short Version
Download and extract a MinGW distribution. Pick one, such as MinGW-w64 (64-bit) or TDM-GCC (32-bit and 64-bit options).
Customize the XML config file, using this one as a template (details in long version below).
Set MINGWROOT environment variable.
Run mex -setup:[xmlfile] [C|C++].
Long Version
For MinGW-w64, I do the following to set it up:
Grab the latest revision for w64 from Sourceforge (or use the installer to choose the toolchain you want, picking a pthread or Win32 threads version depending on your needs).
Extract it so that you have a path to the compiler like C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe. There is no need for MSYS, cygwin, or any other environment if you plan on compiling in MATLAB with the mex command. Check your PATH environment variable to make sure you don't have multiple compilers (g++) on your path, preferably none. Verify with a fresh command prompt.
Set it up with a custom XML configuration file. On my GitHub repo, I have posted C++ configurations for MinGW-w64 in both file types: mex_C++_mingw-w64.xml and legacy mingw_mexopts.bat. Start with that as a template and (optionally) edit the XML file with a descriptive name and version of the MinGW distribution you downloaded and extracted.
Set (or create) the MINGWROOT environment variable. This is what allows the mex command to locate the compiler. You can do this in MATLAB (and every time MATLAB starts with a startup.m script in userpath) with setenv, or just once with the Windows properties dialog or the native Windows 7 setx.exe command.
Run mex -setup:C:\actual\configFilePath.xml C++. For example, using the .xml file to set up C++ MEX file compilation:
setenv('MINGWROOT','H:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1')
mex -setup:H:\building\GitHub\MATLAB\MinGW\mex_C++_mingw-w64.xml C++
The output should look like this:
MEX configured to use 'MinGW-w64 GCC 4.9.2 posixthreads seh' for C++ language compilation.
If needed, set up the C compiler in a similar manner with a new XML config file specifying the C language, the C compiler frontend (e.g. "x86_64-w64-mingw32-gcc.exe" which won't automatically link the C++ standard library), adjust the link libraries as needed, compiler flags (e.g. change -std=c++11 to -std=c99), etc.
Note about static vs. dynamic linking of runtime libraries
Libraries such as a MEX file created with MinGW-w64 as above may depend on a few DLLs (at runtime): LIBGCC_S_SEH-1.DLL (for the seh exception distributions) and LIBSTDC++-6.DLL, and possibly libwinpthread-1.dll if you chose a pthreads distribution instead of Win32 threads. If you don't want to copy these files around, you can statically link the runtime libraries into your MEX file by adding the following switches:
-static-libgcc -static-libstdc++
There's a comment in the XML template about this. See here for info about libpthread-1.dll.
With TDM-GCC, the opposite is true: the runtimes (including pthread) are statically linked automatically. To link dynamically, which will require the DLLs but reduce your MEX file size, you need:
-shared-libgcc -shared-libstdc++
EDIT: There seems to be a much better way with MinGW; see my other answer.
You can compile a .mex file using gcc if you have Matlab installed, from the command line. Some might say it's a little tedious the first time.
First things first - what Matlab do you use? if it's 64-bits, MinGW won't help you, because it's 32-bit. I will therefore show how to use MinGW-w64 instead. Understanding how to do this with 32-bit MinGW should be straightforward.
Add C:\MinGW-64\bin\ to your path. You won't regret this :)
Compile your .c files using gcc:
x86_64-w64-mingw32-c++ -m64 -shared -I"C:\Program Files\MATLAB\R2010b\extern\include" -o bla.mexw64 -DMATLAB_MEX_FILE -Wl,--export-all-symbols *.cpp
This will result in a bunch of linker errors, such as
undefined reference to `mexErrMsgTxt'
To solve this problem, you'll have to create an import library which connects with libmex.dll, libmx.dll, libmat.dll and libeng.dll (you might have others, but these are the main ones)
List the functions you're missing, and, well, guess what dll they're coming from. Hint: mexErrMsgTxt is from libmex.dll, because it starts with "mex"...
For every dll you need to export, create a .def file containing
EXPORTS
... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
Execute the following command, to create import libraries:
x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
(Same for the rest of the .def files)
Now you're good to go!
x86_64-w64-mingw32-c++ -m64 -shared -I"C:\..." -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp libmex.a libmx.a libmat.a libeng.a
Things which can be done better -
instead of --export-all-symbol, only export mexFunction (requires creating another .def file, or adding "__declspec(dllexport)" before void mexFunction(...)).
MinGW is capable of direct-linking a DLL; that is, it will create a kind of an import library on the fly when linking.
This means compilation can be performed in one step:
x86_64-w64-mingw32-c++ -m64 -shared -I"%MATLAB%/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp -L"%MATLAB%/bin/win64" -lmex -lmx -leng -lmat
Matlab links to external code (C++, Fortran, Java etc) using MEX files. (http://gnumex.sourceforge.net/)
Setting up Compiler:
Install TDM-GCC (C++ Compiler "C:\MinGW32\bin;") from http://tdm-gcc.tdragon.net/download
Install Cygwin (toolkit provides Unix tools on the Windows platform) from (http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII4.0/cygwin.htm). Download and Install cygwingDevel.exe
Obtain the gnumex archive via (https://sourceforge.net/projects/gnumex) and extract the gnumex to ($MATLABHOME\gnumex). Where $MATLABHOME would be for example (C:\Program Files\MATLAB\R2010a)
Add this directory ($MATLABHOME\gnumex) to the Matlab path (File->Set Path in Matlab). Note: Run Matlab with Administrator priviledges.
In Matlab, type gnumex at the prompt. Fill in appropriate paths like;
MinGW_Root = C:\MinGW32, Cygwin_Root=C:\cygwin
Do 'File->Save Config', then click 'Make Options file'. Exit from gnumex configure window.
Testing:
Copy mexopts.bat (%AppData%\MathWorks\MATLAB\R2010a\mexopts.bat) to the working directory (%UserProfile%\Documents\MATLAB) for this test.
In matlab, execute the following at prompt;
mex -f mexopts.bat "C:\Program Files\MATLAB\R2010a\extern\examples\mex\yprime.c"
You get (%UserProfile%\Documents\MATLAB\yprime.mexw32) when you type;
which yprime
Run it by typing at Matlab prompt >> yprime(1,1:4) and see if you get 2.0000 8.9685 4.0000 -1.0947.
Now just copy mexopts.bat to $MATLABHOME\bin and it should work from anywhere.
Matlab on Linux Platform:
At Linux prompt, install the following;
sudo apt-get install gcc g++ gfortran
In Matlab, execute the following at prompt;
mex -setup
The options files available for mex are: **1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh : Select option 1. To test the working, execute the following at Matlab prompt;
mex "/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c"
yprime(1,1:4)
In case you get the warning;
Warning: You are using gcc version "4.6.3-1ubuntu5)". The version
currently supported with MEX is "4.4.6".
For a list of currently supported compilers see:
http://www.mathworks.com/support/compilers/current_release/
At Linux prompt:
sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
Change 'gcc' to 'gcc-4.4' ,'g++' to 'g++-4.4' , 'gfortran' to 'gfortran-4.4' at all instances of CC = 'gcc' , CXX = 'g++' and FC = 'gfortran'.
Save the file and exit.
This is a detailed walkthorugh of this answer. Therefore, all the credit should go to that answer.
1 Install MinGW-w64:
1.1 Download this MinGW64-w64 build and its update:
(http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/mingw-w64-bin_x86_64-mingw_20111101_sezero.zip/download)
(http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/sezero_20111101-w64-update-rev.5747.zip/download)
(http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/README-mingw-w64-20111101_sezero.txt/download)
1.2 Install (unzip) the downloaded archives:
1.2.1 Unzip the build file and move the resulting mingw64\ folder in c:\
1.2.2 Unzip and copy (overwrite) the update file on c:\mingw64
1.3 Add C:\mingw64\bin to the Path variable:
set PATH=C:\mingw64\bin;%PATH%
2 On a commandline (outside Matlab environment), compile your *.c files: For example, CCODEFILE.c (Assuming Matlab 2012b installed in C:\Program Files\MATLAB\R2012b\ folder):
"c:\mingw64\bin\x86_64-w64-mingw32-g++.exe" -m64 -shared -I"C:/Program Files/MATLAB/R2012b/extern/include" -DMATLAB_MEX_FILE -o CCODEFILE.mexw64 -Wl,--export-all-symbols CCODEFILE.c -L"C:/Program Files/MATLAB/R2012b/bin/win64" -lmex -lmx -leng -lmat
3 Then, any Matlab code should work fine when it calls the CCODEFILE function.
If you couldn't install Mingw-w64 using the Add-Ons toolbar of Matlab2016b on Windows, you can use this workaround. Keep this in mind that you need to change the paths according to your installation paths.
The Mingw-w64 official website redirects you to Win-builds project which is a package manager for a bundle of open source development tools. So, first you need to install the Win-builds.
While installing Win-builds, make sure you are entering a path that does not contain any spaces e.g. C:\Win-builds.
After installing Win-builds, just hit the Process button to install all packages where Mingw-w64 is among them.
Now that you installed Mingw-w64, you need to define the MW_MINGW64_LOC environment variable which Matlab uses it to detect Mingw-w64.
To define the environment variable do the following steps:
Control panel\ System\ Advanced system settings\ Advanced\ Environment Variable\ User variables for $YOUR_USER_NAME\ New
Put Variable name = MW_MINGW64_LOC and Variable value = C:\Win-builds. Notice that the Win-builds puts all executables in C:\Win-builds\bin and by defining this variable, Matlab will automatically scans the bin folder of the path looking for gcc.exe.
Now that you installed the Mingw-w64 and define the MW_MINGW64_LOC environment variable, it is time to build and test the yprime example. So Launch Matlab and type the following command (Do not forget to modify the path accordingly):
mex -v 'C:\Program Files\MATLAB\R2016b\extern\examples\mex\yprime.c'
A successful installation will show the following message:
MEX completed successfully.
Finally, you can test your installation by typing yprime(1,1:4). The answer would be:
ans = 2.0000 8.9685 4.0000 -1.0947
Why so many steps? If you have Matlab 2016 or higher, just do:
Download mingw and install to a folder without spaces (ie. not into "Program Files")
Add the MW_MINGW64_LOC environment variable pointing to the install folder (the exact same thing you typed into the installer)
Restart your PC
Open MATLAB and type mex -setup into the console. It should say "configured to use MinGW"
Run/compile your MATLAB program
I've tested these on a new Windows 10 PC and it works!
This one works on Matlab 2012b under Windows 8:
https://github.com/DynareTeam/dynare/blob/master/windows/mexopts-win64.bat
Modify cgwin directory or replace it with mingw directory if used. You can also echange the compiler-exe if you switch to a 64 bit version.
In Windows 64 bit with R2011a it worked with http://tdm-gcc.tdragon.net/ and http://gnumex.sourceforge.net/ but I have to change maxopt.bat line entry GM_ADD_LIBS as follows:
rem Add path to where dlls are:
set DLL_PATH="C:\Program Files\MATLAB\R2011a\bin\win64"
rem Add every dll needed:
set GM_ADD_LIBS=%DLL_PATH%\libmx.dll %DLL_PATH%\libmex.dll %DLL_PATH%\libmat.dll
It took me a long time to get to this point, good luck.
I originally thought this sounded like a form of torture, but based on the above answer by #user10171136 I actually found it pretty straightforward to cross-compile for Windows mex from Fedora Linux. Fedora has mingw and mingw64 packages, so:
sudo yum install mingw64-gcc mingw64-gcc-c++
Copy over from a Windows Matlab install both the extern/include and bin/win64 directories (actually you probably only need a subset of the headers and a small subset of the dlls; libmat.dll libmex.dll libmx.dll might be all you need. I put these two directories into a new R2010a-w64 directory under my existing Linux MATLAB directory; change the below commands appropriate for where you stashed the Windows headers and libs.
There was one problem I ran into, which is that char16_t was needed in matrix.h and wasn't defined. I guess matrix.h forgot to include uchar.h? I worked around with an -include directive; see below.
x86_64-w64-mingw32-gcc -m64 -shared -include uchar.h -I/opt/MATLAB/R2010a-w64/extern/include -DMATLAB_MEX_FILE -L/opt/MATLAB/R2010a-w64/bin/win64 -o bla.mexw64 bla.c -lmx -lmex
(You may need additional libraries for linking, e.g. -lmat -leng -lm, etc.)
This successfully generates a mex file that is executable under Windows Matlab for my setup. So far I've only tested this with pretty simple C programs.
Interested to hear if this sounds reasonable; I don't have much experience with cross-compiling.
On linux, if you type mex -setup, you can choose the compiler.
On windows, you should try to install lcc, you can do so for instance by installing Microsoft Visual Studio Express, which is free.
I've had Eclipse for Java on my computer for a few years, and decided to install the CDT and learn C. I installed both MinGW and Cygwin and the CDT detects and tries to use them when I make a new project.
I choose File > New C++ Project and choose Hello World C++ Project and the CygwinGCC toolchain. I name the project "asdf" and hit "Build Debug" in the toolbar. The compiler completes without error. I hit Run and nothing happens.
Browsing to the project directory manually and running asdf.exe gives me an error saying:
"The program can't start because cygwin1.dll is missing from your computer. Try reinstalling the program to fix this problem."
The same thing happens using MinGW, only a different dll is missing.
What do I need to do to have a usable .exe?
(I'm running Windows 7 x64 and the newest version of Eclipse and the CDT.)
EDIT:
The compiler output is as follows:
**** Build of configuration Debug for project asdf ****
make all
Building file: ../src/asdf.cpp
Invoking: Cygwin C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/asdf.d" -MT"src/asdf.d" -o"src/asdf.o" "../src/asdf.cpp"
cygwin warning:
MS-DOS style path detected: C:\Users\Shawn\Dropbox\eclipse\asdf\Debug
Preferred POSIX equivalent is: /cygdrive/c/Users/Shawn/Dropbox/eclipse/asdf/Debug
CYGWIN environment variable option "nodosfilewarning" turns off this warning.
Consult the user's guide for more details about POSIX paths:
http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
Finished building: ../src/asdf.cpp
Building target: asdf.exe
Invoking: Cygwin C++ Linker
g++ -o"asdf.exe" ./src/asdf.o
Finished building target: asdf.exe
This error message means that Windows isn't able to find "cygwin1.dll". The Programs that the Cygwin gcc create depend on this DLL. The file is part of cygwin , so most likely it's located in C:\cygwin\bin. To fix the problem all you have to do is add C:\cygwin\bin (or the location where cygwin1.dll can be found) to your system path. Alternatively you can copy cygwin1.dll into your Windows directory.
There is a nice tool called DependencyWalker that you can download from http://www.dependencywalker.com . You can use it to check dependencies of executables, so if you inspect your generated program it tells you which dependencies are missing and which are resolved.
You can compile with either Cygwin's g++ or MinGW (via stand-alone or using Cygwin package). However, in order to run it, you need to add the Cygwin1.dll (and others) PATH to the system Windows PATH, before any cygwin style paths.
Thus add: ;C:\cygwin64\bin to the end of your Windows system PATH variable.
Also, to compile for use in CMD or PowerShell, you may need to use:
x86_64-w64-mingw32-g++.exe -static -std=c++11 prog_name.cc -o prog_name.exe
(This invokes the cross-compiler, if installed.)
To add to this and save someone another google, just do this in cmd:
set PATH=%PATH%;C:\cygwin64\bin