I am trying to compile a Matlab mex program that uses openmp on a mac. I would like to distribute this to other Matlab users so that they can use it, without them needing to install other software.
From what I can tell, xcode doesn't allow this, so I've installed gcc. I am able to compile the program fine, and run it locally, but it links to dependencies that are not available by default on a mac (I think). In particular, otool points to libgomp.1.dylib and libgcc_s.1.dylib, which from what I can tell, are not a part of the standard os installation.
I am able to link against libgomp.a statically, which from some testing (renaming the .dylib file) seems to have properly removed that dependency (i.e. the code still works when I rename the dylib file, and otool does not list it as well). However, I am unsure how to remove the libgcc_s.1.dylib dependency. In windows, copying the dll locally would fix the issue, but this doesn't work on a mac. I could not find a static library for that dependency. Instead, I am trying to get some version of rpath working (with a locally copied file), but otool consistently points to /usr/local/opt/gcc/lib/gcc/6/libgcc_s.1.dylib
The relevant parts of the Matlab command were:
'LDFLAGS="$LDFLAGS -fopenmp -Wl,-rpath,$ORIGIN/"' and
'-lgcc_s.1'
I found one solution here: Openmp with mex in Matlab on mac
However, for another project, I am using gcc specific commands so I'd really like to get this working with gcc.
So, I had some luck bypassing the mex compiling infrastructure and just passing the commands directly to gcc. To start, I ran what I currently had using the '-v' option to see the commands that Matlab was sending to the compiler. The 4 edits I then made were, 1) removed the crazy object output paths that Matlab creates (uses some temporary folder) 2) removed the reference to xcode 3) added a -L directive to the mex folder (although I will probably change this to the proper gcc directory - I'm just used to copying files locally to compile due to Matlab problems) and 4) added '-static-libgcc' (which I swear I had tried before ...) oh, and 5) I also updated the min osx version
This is the final line, the first two just had the -o options removed
/usr/local/Cellar/gcc/6.3.0_1/bin/gcc-6 -Wl,-twolevel_namespace -static-libgcc -L"/Users/jim/Documents/repos/matlab_git/matlab_sl_modules/plotBig_Matlab/+big_plot/private" -undefined error -arch x86_64 -mmacosx-version-min=10.12 -bundle -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/mexFunction.map" -fopenmp reduce_to_width_mex.o c_mexapi_version.o -O -Wl,-exported_symbols_list,"/Applications/MATLAB_R2017a.app/extern/lib/maci64/c_exportsmexfileversion.map" libgomp.a -L"/Applications/MATLAB_R2017a.app/bin/maci64" -lmx -lmex -lmat -lc++ -o reduce_to_width_mex.mexmaci64
Oh and finally I should mention I just ran these commands in the terminal, rather than in the Matlab command window ...
Related
I would like to know how I can prevent gcc under Cygwin from automatically adding the .exe extension to compiled files, because I just caused myself a lot of confusion with "missing files". For context, I am working on a C project for university and I usually work in the labs which run Ubuntu (dual-boot with Windows), but to work from home I prefer using my Windows machine, ergo Cygwin. If I just remove the extension it still works just fine on either system, but it is rather frustrating to have to change the command to include the extension whenever I've just compiled it under Cygwin.
I looked up the FAQ from Cygwin to find that it is probably an issue related to an environment variable in .bashrc or .bash_profile (see here), but I am no command-line ninja and am not very familiar with editing configuration files... I found two related questions as well that show the same behaviour, but have nothing to do with trying to change it:
Compiling with gcc (cygwin on windows)
Executable file generated using gcc under cygwin
Any ideas?
It is actually for an MPI in C project so I have a Makefile that calls mpicc but that is not really relevant to the problem, since I just tried with gcc as well and both do the same thing. For the purpose of this question, the commands and outputs I get are:
$ gcc -o hello hello.c
$ ls
hello.c hello.exe
$./hello
Hello, world!
$./hello.exe
Hello, world!
Note that running with or without the extension does the same thing in the shell, but it does not with mpirun which is why I want to change this behaviour.
I eventually decided that Windows is not the programming environment for me. From now on all work that can be done in Linux will be.
7 years and no one to tell ?
My answer : Yes it's possible to produce an executable without .exe extension under Cygwin GCC. By telling the linker how to name its output.
$ echo -e "#include <stdio.h>\nint main(int nbargs, char *args[]) {
printf(\"Hello \\\n\");
}" | gcc -pipe -x c - -Wl,-oess2
This will produce an ess PE32 / PE32+ executable file, not a ess.exe.
The -pipe option instructs the GCC build chain to not write temporary files but use pipe between stages instead. The -Wl,-o option inhibits the default --force-exe-suffix.
And this way you can really nullify Cygwin GCC output with -Wl,-o/dev/null, the linker will fail when trying to close the output but you can trap the error message. If you get it, you can be assured that GCC reaches the link stage far enough to produce an output, which means that GCC can build an executable with this code.
From the ld man page :
--noinhibit-exec Retain the executable output file whenever it is still usable. Normally, the linker will not produce an output file if
it encounters errors during the link process; it exits without writing
an output file when it issues any error whatsoever.
DO NOT USE -Wl,-o/dev/stdout under Cygwin. Under Cygwin, /dev/stdout is a symlink, and if the linker fails it will DELETE /dev/stdout.
On the other end, -Wl,-o/proc/self/fd/1 will do no harm, but the linker will fail and will produce only an error message on stdout. Currently, it seems there is no direct way under Cygwin to pipe the linker output, even with named pipes.
The automatic exe extension for executables is there for a reason (Windows requires it). You should deconfuse (aka educate :-) yourself and accept the way Cygwin works. This is a feature rooted so deeply in the Cygwin/Windows guts that it is almost impossible to make it run without it.
For a "Unix feeling on Windows" with a different approach you want to check out AT&T's UWin.
I am trying to modify the source code to an open source application on windows that uses mingw.
I am having a problem linking the psapi library.
psapi.h and libpsapi.a are in the mingw directory and I have tested it using the standard
gcc -o program program.c -lpsapi
method, and it works.
However, when I try to compile the program using the
./configure
make
method, it doesn't work I have tried,
./configure LDFLAGS=-lpsapi
make
and that doesn't work
and I tried going into the makefile.am and putting -lpsapi in AM_LDFLAGS but that doesn't work
The error it gives is just a standard "undefined reference to [function]", implying that the library with the functions is not linked
I have even tried putting psapi.h in the source directory and including it as #include "psapi.h" and that STILL didn't work.
LDFLAGS is the wrong one.
LIBS=-lpsapi should do the trick.
The order is important for the linker. The libraries (LIBS) have to come after the objects, LDFLAGS can be before.
How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)
I am trying to run someone else's (4 year old) code from sourceforge. I downloaded cygwin and checked out the project with CVS.
Here is the compile line which is failing:
gcc ../block_display/block_display.c -o block_display -lopengl32 -lglut32 -lm
Here is the relevant include statement in block_display.c:
#include <GL/glut.h>
When I try to run the above compile line, I get this compile error:
$ gcc ../block_display/block_display.c -o block_display -lopengl32 -lglut32 -lm
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lglut32
collect2: ld returned 1 exit status
I admit I am new/rusty with cygwin. I tried a few things to get to this point, but since I don't entirely know where to put files, I am stuck on this error. Here is what I have tried:
Downloading all results for 'glut' in cygwin setup: libglut-devel, freeglut, libglut3
Downloading glut 3.7.6, copying glut32.dll to C:\Windows\SysWOW64, and copying glut.h to C:\cygwin\usr\include. I still have glut.def and glut32.lib sitting around, but I do not know exactly where to place them. I tried following this install guide, but since I am not running VC++, I do not know what the cygwin equivalent of VC++ path is.
Any idea what I could do to get this code to compile successfully? I am running Windows 7 64-bit.
You should use freeglut instead. The original glut is far outdated. Freeglut on the other hand is binary and source compatible with the original glut, and it's also open source.
Since glut32.dll is a windows DLL and cygwin is for emulating a unix environment on windows, you can't easily use the original glut with cygwin without recompiling from source.
I have downloaded the source of GMP library 5.02, and - as suggested here for maximum debuggability - I ran :
./configure --disable-shared --enable-assert --enable-alloca=debug --host=none CFLAGS=-g
and compiled it with make, then installed the library with make install. I then compiled my program like this: gcc -lgmp -std=c99 -g -c program.c and then I ran : ltrace ./a.out
However I realized that ltrace is not at all invoking the TRACE() functions I can find in the source code. I would like to trace the content that's in TRACE().
How should I go for that? Or is there any other straightforward way of debugging inside the GMP library? (I couldn't figure it out how to do it with gdb, it never wanted to step into gmp_printf)
Thanks.
EDIT:
I tried to investigate further, and realized that I couldn't modify the GMP library although I had the sources. I inserted a printf("hello\n"); at the very beginning of the mpz_init2 function which I do call at the beginning of my program, I recompiled all GMP (even after a make clean) re-installed the library with make install, then I compiled and launched my program, but it never printed "hello". I also made sure, I wasn't using another installed GMP library (when I do make uninstall my program cannot compile as it does not find the library). Still, I insisted that gcc looks for the library in the GMP source folder with the -L option.
I don't know what I'm doing wrong :(
Your final compile of a.out is not producing a statically linked a.out executable. So, even though as you state, during compilation of program.c the compiler is using your GMP library, at runtime it is picking up a shared library somewhere. You need to do one of two things:
Compile with -Bstatic (or something similar; check man page for your compiler)
Set the LD_LIBRARY_PATH (or something similar; check 'ld' or 'dyld' man pages)
I think #1 is actually your only choice given that you built only the static version of GMP. For #1 make sure you explicitly provide -L/path/to/gmplib in the compilation of program.c