OSX/Darwin unresolved symbols when linking functions from <math.h> - xcode

I'm in the process of porting a large'ish (~1M LOC) project from a Window/Visual Studio environment to other platforms, the first of which happens to be Mac OS X.
Originally the project was configured as Visual Studio solutions and projects, but now I'm using (the excellent) Premake (http://industriousone.com/premake) to generate project files for multiple platforms (VS, XCode, GMake).
I configured, ported and built the first few projects without any significant problems, but having ported the math lib, I ran into this weird linking error that I haven't been able to resolve: Any functions used from math.h will fail to link (causing unresolved symbols).
For reference, I'm using Premake v4.2.1 to generate projects for XCode v3.2.1, which is building using gcc v4.2 for the x86_64 architecture. (All this on 64-bit Snow Leopard) I've tried to persuade gcc to link and build everything against a 'known' SDK by adding -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.6 to the build command line.
Now under normal circumstances, adding -lm should take care of this, however in Darwin, those math libs are included in libSystem, which, as far as I can tell, gets implicitly linked by gcc/ld.
I've tried creating a dummy project from within XCode which just runs:
float f = log2(2.0)+log2f(3.f)+log1p(1.1)+log1pf(1.2f)+sin(8.0);
std::cout << f << std::endl;
and as expected, this builds just fine. However, if I put the same thing in the code inside the Premake generated project, all those math functions end up unresolved.
Now comparing the linking command from the 'native' XCode project with my generated XCode project, they seem pretty identical (except that my generated project links other libs as well).
'Native' project:
/Developer/usr/bin/g++-4.2 -arch x86_64 -dynamiclib -isysroot /Developer/SDKs/MacOSX10.6.sdk -Lsomepath -Fsomepath -filelist somefile -install_name somename -mmacosx-version-min=10.6 -single_module -compatibility_version 1 -current_version 1 -o somename
Generated project:
/Developer/usr/bin/g++-4.2 -arch x86_64 -dynamiclib -Lsomepath -Fsomepath -filelist somefile -install_name somename -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.6 somelib.a somelib2.a somelib.dylib somelib2.dylib -single_module -compatibility_version 1 -current_version 1 -o somename
Any help or hints about how to proceed would be most appreciated. Are there any gcc flags or other tools that can help me resolve this?

I finally managed to resolve/work-around this.
By replacing
#include <math.h>
float f = sinf(1.f);
with
#include <cmath>
float f = std::sin(1.f);
everything links as expected.
I'll accept the fact that the cmath solution is probably the code I should have written in the first place, although I'd happily accept further opinions about why my C approach failed so miserably.

Related

Link issue on Windows with pthreads - Is gcc or SystemC to blame?

​
Hi,
I've recently come across a link issue that I cannot explain.
Here is an example that couldn't really be simpler:
sc_main.cpp:
#include <systemc.h>
int sc_main (int argc, char* argv[])
{
sc_start(SC_ZERO_TIME);
return(0);
}
I use the following to compile and link, with winlibs-x86_64-posix-seh-gcc-10.2.0-mingw-w64-8.0.0-r7.7z:
g++ -pthread main_sc.cpp -o main_sc.exe -s $(LDFLAGS) -I$(SYSTEMC_HOME)/include -L$(SYSTEMC_HOME)/lib-mingw64 -lsystemc
Now, because I'm targeting Win64, and because I want to make an executable without any dependence on MinGW-64 run-time libraries, there are a number of possible settings that I've been looking at:
Option 1 - LDFLAGS := -static
Option 2 - LDFLAGS := -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
Option 3 - LDFLAGS := -static-libgcc -static-libstdc++ -Wl,-Bstatic,--whole-archive -lpthread -Wl,-Bdynamic -Wl,--no-whole-archive
At this point, sometimes it works, sometimes it doesn't, depending on the SystemC release I'm using:
SytemC 2.3.2 + Option 1 : fine
SytemC 2.3.3 + Option 1 : libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'
libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text$_ZN7sc_core13sc_host_mutex6unlockEv[_ZN7sc_core13sc_host_mutex6unlockEv]+0xa): undefined reference to `__imp_pthread_mutex_unlock'
libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text$_ZN7sc_core17sc_host_semaphore7trywaitEv[_ZN7sc_core17sc_host_semaphore7trywaitEv]+0x2f): undefined reference to `__imp_pthread_mutex_unlock'
but
SytemC 2.3.2 + Option 2 or 3 : fine
SytemC 2.3.3 + Option 2 or 3 : libpthread.dll.a(d000077.o):(.text+0x0): multiple definition of `pthread_mutex_unlock' ; mingw-w64-v8.0.0/mingw-w64-libraries/winpthreads/src/mutex.c:207: first defined here
 
Note that I the toolchain I am using is based on gcc 10.2.0 but that's not relevant. I only used this toolchain because it's based on the latest MinGW libraries (8.0.0)
In fact, I have generated my own (cross-compilation) toolchain (running on linux), based on the same MinGW 8.0.0 libraries and on gcc 6.3.0 and I'm seeing the exact same results.
Any idea what's going on ? Am I doing anything wrong ? I'm not too sure if the issue has to do with SystemC or with GCC/winpthreads, but I'm tempted to think that SystemC can be exonerated.
So who's to blame, and is there a workaround ?
The behavior reported in the OP is only observed when SystemC libraries are cross-compiled for Windows, using the configure based flow.
When the SystemC libraries are cross-compiled using the cmake based flow, or when they are natively compiled on Windows, then everything works as expected.
The different behavior between SytemC 2.3.2 and 2.3.3 is explained by the fact that 2.3.2 does not include <pthread.h> (but relies on Windows Semaphore), whereas 2.3.3 does (via the inclusion of <mutex>) which exposes the issue mentioned here.

Compiling library in g++ using C++11

I'm been attempting to compile an open-source C++ library (QuantLib-1.7) on my mac for several days but I seem to be encountering some kind of C++11 compatibility issue.
When I run make && sudo make install from the terminal the compilation seems to work except for a bunch of errors of the form
Making all in BermudanSwaption
g++ -DHAVE_CONFIG_H -I. -I../../ql -I../.. -I../.. -I/opt/local/include -g -O2 -MT BermudanSwaption.o -MD -MP -MF .deps/BermudanSwaption.Tpo -c -o BermudanSwaption.o BermudanSwaption.cpp
In file included from BermudanSwaption.cpp:22:
In file included from ../../ql/quantlib.hpp:43:
In file included from ../../ql/experimental/all.hpp:25:
In file included from ../../ql/experimental/volatility/all.hpp:21:
In file included from ../../ql/experimental/volatility/zabr.hpp:31:
In file included from ../../ql/math/statistics/incrementalstatistics.hpp:35:
In file included from /opt/local/include/boost/accumulators/statistics/stats.hpp:14:
In file included from /opt/local/include/boost/accumulators/statistics_fwd.hpp:12:
/opt/local/include/boost/mpl/print.hpp:50:19: warning: in-class initialization
of non-static data member is a C++11 extension [-Wc++11-extensions]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^
1 warning generated.
I'm guessing this has something to do with g++ not being correctly configured for C++11. I'm familiar with the fact that C++11 can be invoked by compiling with g++ -std=c++11. However, despite a lot of googling I can't find a way to modify the makefile such that -std=c++11 is called when I run make && sudo make install.
Any help would be greatly appreciated.
Here is the section of the makefile which I believe is relevant:
BOOST_INCLUDE = -I/opt/local/include
BOOST_LIB = -L/opt/local/lib
BOOST_THREAD_LIB =
BOOST_UNIT_TEST_DEFINE = -DQL_WORKING_BOOST_STREAMS
BOOST_UNIT_TEST_LIB = boost_unit_test_framework-mt
BOOST_UNIT_TEST_MAIN_CXXFLAGS = -DBOOST_TEST_DYN_LINK
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS = -I/opt/local/include
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
Here is the output from running "g++ -v":
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
Makefile.am: https://www.dropbox.com/s/v5j7qohwfup81od/Makefile.am?dl=0
Makefile.in: https://www.dropbox.com/s/t92hft9ea2ar1zw/Makefile.in?dl=0
QuantLib-1.7 directory: https://www.dropbox.com/sh/ulj0y68m8x35zg8/AAA-w7L2_YWIP8_KnwURErzYa?dl=0
Full error log: https://www.dropbox.com/s/g09lcnma8skipv7/errors.txt?dl=0
Add something like
CXXFLAGS += -std=c++11
to your Makefile. This will work regardless of the Darwin-specific munging of the g++ executable---it's really clang++.
References:
https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options
https://gcc.gnu.org/projects/cxx0x.html
http://clang.llvm.org/cxx_status.html
https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
As you already have, and are familiar with homebrew, my suggestion would be to use that to install and manage quantlib like this:
brew install quantlib
That will then build and put all the files in /usr/local/Cellar/quantlib under some version number that is not of importance. The important thing is the the tools are then linked into /usr/local/bin so all you need to do is make sure that /usr/local/bin is in your PATH.
That gives you access to the tool quantlib-config which is always linked to the latest version and it knows which version that is. So, if you run:
quantlib-config --cflags
it will tell you what the correct path is for your includes like this:
-I/usr/local/Cellar/quantlib/1.6.1/include
Likewise, if you run:
quantlib-config --libs
it will tell you the correct linking directories and libraries for your latest version.
In short, all you need to do to compile is:
g++ $(quantlib-config --cflags --libs)
and it will always pull in the version you are using.
Note that if you use a Makefile, you will need to double the dollar signs.
This is how I eventually managed to compile the Quantlib library for future reference. It is probably not the most efficient/elegant method but it appears to work.
I followed the steps given in http://quantlib.org/install/macosx.shtml and found that running make && sudo make install led to the error reported in the OP.
Create a new static library C++ project in Eclipse called 'Quantlib'
Copy the ql directory located in the .tar file to the Quantlib Eclipse workspace
Right-click Quantlib > Properties > C/C++ Build > Settings > Cross G++ Compiler: Change the Language standard to ISO C++ 11 (-std=c++0x)
Right-click Quantlib > C/C++ General > Paths and Symbols: Add the following include directories for GNU C++
opt/local/include
/Quantlib (check "Is a workspace directory")
/opt/local/include/boost.
Build the Quantlib project (around 34 min on MacBook Air 1.8 GHz Intel Core i7)
Create a new C++ executable project (e.g. BermudanSwaption) and copy the BermudanSwaption.cpp into the BermudanSwaption Eclipse workspace
Repeat steps 4. and 5. for the BermudanSwaption Eclipse project
Right-click BermudanSwaption > Properties > C/C++ General > Paths and Symbols > References: check Quantlib (the Library Paths tab should now contain the entry '/Quantlib/Debug')
Build and run the BermudanSwaption executable project
QuantLib-1.7
OSX Yosemite 10.10.5
Eclipse C/C++ Development Tools Version: 8.8.0.201509131935
Xcode Version 7.1 (7B91b)
xcode-select version 2339.

Unit testing Objective-C++ frameworks with Xcode 4.x

I'm writing a framework using Objective C++ and I am having trouble setting up unit tests for it.
Compiling just the framework target works fine.
But when I tell Xcode to compile and run the test bundle I get:
Ld ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests normal x86_64
cd "~/Projects/TestFramework"
setenv MACOSX_DEPLOYMENT_TARGET 10.7
"/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++" -arch x86_64 -bundle -isysroot "/Applications/Xcode 4.5.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" -L~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib -F~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug "-F/Applications/Xcode 4.5.app/Contents/Developer/Library/Frameworks" -filelist ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Intermediates/TestFramework.build/Debug/TestFrameworkTests.build/Objects-normal/x86_64/TestFrameworkTests.LinkFileList -mmacosx-version-min=10.7 -v -fobjc-arc -fobjc-link-runtime -fprofile-arcs -stdlib=libc++ -framework SenTestingKit -framework Cocoa -framework TestFramework -o ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests
Apple clang version 4.0 (tags/Apple/clang-421.10.48) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
"/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -bundle -macosx_version_min 10.7.0 -syslibroot "/Applications/Xcode 4.5.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk" -o ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug/TestFrameworkTests.octest/Contents/MacOS/TestFrameworkTests -L~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib -filelist ~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Intermediates/TestFramework.build/Debug/TestFrameworkTests.build/Objects-normal/x86_64/TestFrameworkTests.LinkFileList -framework SenTestingKit -framework Cocoa -framework TestFramework -force_load "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a" -framework Foundation -lobjc -lc++ "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.0/lib/darwin/libclang_rt.profile_osx.a" -lSystem "/Applications/Xcode 4.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/4.0/lib/darwin/libclang_rt.osx.a" -F~/Library/Developer/Xcode/DerivedData/TestFramework-axdefcbatoubjbbfqiyxildilobl/Build/Products/Debug "-F/Applications/Xcode 4.5.app/Contents/Developer/Library/Frameworks"
Undefined symbols for architecture x86_64:
"Foo::Bar::Bar()", referenced from:
-[FooBar_Tests testBaz] in FooBar_Tests.o
"Foo::Bar::baz() const", referenced from:
-[FooBar_Tests testBaz] in FooBar_Tests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have:
C++ Language Dialect: c++11
C++ Standard Library: libc++
set on both build targets (framework & test bundle).
And I am of course linking against the framework in my test bundle target.
Furthermore, all framework headers are marked public.
I also tried adding the framework files to the test bundle's target and leaving them out. None of these fixed the problem.
I am a bit puzzled as to what's going wrong here, right now. Any ideas?
This is how my C++ class looks like (kind of):
//FooBar.hh
namespace Foo {
class Bar {
public:
bool baz() const;
}
}
//FooBar.mm
#import "FooBar.hh"
namespace Foo {
bool Bar::baz() const {
return true;
}
}
And this my test case:
//FooBar_Tests.hh
#import <SenTestingKit/SenTestingKit.h>
#interface FooBar_Tests : SenTestCase
#end
//FooBar_Tests.mm
#import "FooBar_Tests.hh"
#import <TestFramework/FooBar.hh>
//this one fails as well (compiles fine, fails one linkage):
//#import "FooBar.hh"
#implementation FooBar_Tests
- (void)testBaz {
Foo::Bar bar();
STAssertEquals(bar.baz(), true, nil);
}
Edit: Split code up into .hh&.mm files. Still getting the same errors though.
One possible problem is that your unit tests are in the header file. Header files do not do much in OCUnit. You can even get rid of the header file and put all your test case code in the implementation file. Add an Objective-C unit test class to your project, give it the extension .mm, and move your test case code there. Does that fix the problem?
When I unit test C++ code with OCUnit, I find I have to add the C++ files in my app to the unit test target to avoid link errors. I'm not sure if it applies to Objective-C++ code, but it's something to look into.
I eventually added a new unit test target to my project, enabled C++11 and tried compiling/running it. Success.
Somehow my original unit test target must have gone bad in regards to C++11. Had compiled just fine before.
Now it's time to migrate my test cases to the new test bundle, I guess.
…and I thought I was going mad. Oh well…

How can I compile and use Haskell as a C library using Xcode LLVM compiler?

I want to set up a project to take my .hs code, and my main .c program, and result in a statically linked executable through the use of LLVM compiler. I can get things working via ghc command line options to build a .hs, produce the stubs, and compile and link a driver application using ghc entirely. However, I get various issues within Xcode.
My first issue was that I of course need to use 32 bit compiling environment in Xcode. That solved, I had to fiddle with paths to explicitly include the HsFFI.h. That solved, I get a linker error:
Ld "build/Debug/FFI Test.app/Contents/MacOS/FFI Test" normal i386
cd "/Users/rcl/TestXCodeProjects/FFI Test"
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/clang -arch i386
-isysroot /Developer/SDKs/MacOSX10.6.sdk
"-L/Users/rcl/TestXCodeProjects/FFI Test/build/Debug"
"-L/Users/rcl/TestXCodeProjects/FFI Test/FFI Test"
"-F/Users/rcl/TestXCodeProjects/FFI Test/build/Debug"
-filelist "/Users/rcl/TestXCodeProjects/FFI Test/build/FFI Test.build/
Debug/FFI Test.build/Objects-normal/i386/FFI Test.LinkFileList"
-mmacosx-version-min=10.6 -framework Cocoa
"/Users/rcl/TestXCodeProjects/FFI Test/FFI Test/ForeignExportCost.a"
-o "/Users/rcl/TestXCodeProjects/FFI Test/build/Debug/FFI Test.app/
Contents/MacOS/FFI Test"
Undefined symbols for architecture i386:
"_hs_init", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
"_simpleFunction", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
"_hs_exit", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The "simpleFunction" is in "ForeignExportCost.a" library which I compile using ghc like this:
ghc -no-hs-main -fPIC -c ForeignExportCost.hs
ghc -no-hs-main -shared ForeignExportCost.o -o ForeignExportCost.a
What am I missing or doing wrong?
Ugh - it looks like the answer to my question is detailed here, telling me how to painfully add a ton of .a's to my project. And this blog post gave some helpful tips to getting on the way.
Although if someone tells me "hey wait, there's an easier way than iteratively figuring out failed deps" that would be awesome. Because I want to reuse this framework several times and this is a real pain of a way to get things up and going!

shared library locations for matlab mex files:

I am trying to write a matlab mex function which uses libhdf5; My Linux install provides libhdf5-1.8 shared libraries and headers. However, my version of Matlab, r2007b, provides a libhdf5.so from the 1.6 release. (Matlab .mat files bootstrap hdf5, evidently). When I compile the mex, it segfaults in Matlab. If I downgrade my version of libhdf5 to 1.6 (not a long-term option), the code compiles and runs fine.
question: how do I solve this problem? how do I tell the mex compilation process to link against /usr/lib64/libhdf5.so.6 instead of /opt/matlab/bin/glnxa64/libhdf5.so.0 ? When I try to do this using -Wl,-rpath-link,/usr/lib64 in my compilation, I get errors like:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libhdf5.so.0, needed by /opt/matlab/matlab75/bin/glnxa64/libmat.so, may conflict with libhdf5.so.6
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
mex: link of 'hdf5_read_strings.mexa64' failed.
make: *** [hdf5_read_strings.mexa64] Error 1
ack. the last resort would be to download a local copy of the hdf5-1.6.5 headers and be done with it, but this is not future proof (a Matlab version upgrade is in my future.). any ideas?
EDIT: per Ramashalanka's excellent suggestions, I
A) called mex -v to get the 3 gcc commands; the last is the linker command;
B) called that linker command with a -v to get the collect command;
C) called that collect2 -v -t and the rest of the flags.
The relevant parts of my output:
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtbeginS.o
hdf5_read_strings.o
mexversion.o
-lmx (/opt/matlab/matlab75/bin/glnxa64/libmx.so)
-lmex (/opt/matlab/matlab75/bin/glnxa64/libmex.so)
-lhdf5 (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libhdf5.so)
/lib64/libz.so
-lm (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libm.so)
-lstdc++ (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libstdc++.so)
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/lib64/libpthread.so.0
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtendS.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crtn.o
So, in fact the libhdf5.so from /usr/lib64 is being referenced. However, this is being overriden, I believe, by the environment variable LD_LIBRARY_PATH, which my version of Matlab automagically sets at run-time so it can locate its own versions of e.g. libmex.so, etc.
I am thinking that the crt_file.c example works either b/c it does not use the functions I am using (H5DOpen, which had a signature change in the move from 1.6 to 1.8 (yes, I am using -DH5_USE_16_API)), or, less likely, b/c it does not hit the parts of Matlab internals that need hdf5. ack.
The following worked on my system:
Install hdf5 version 1.8.4 (you've already done this: I installed the source and compiled to ensure it is compatible with my system, that I get gcc versions and that I get the static libraries - e.g. the binaries offered for my system are icc specific).
Make a target file. You already have your own file. I used the simple h5_crtfile.c from here (a good idea to start with this simple file first a look for warnings). I changed main to mexFunction with the usual args and included mex.h.
Specify the static 1.8.4 library you want to load explicitly (the full path with no -L for it necessary) and don't include -lhdf5 in the LDFLAGS. Include a -t option so you can ensure that there is no dynamic hdf5 library being loaded. You also need -lz, with zlib installed. For darwin we also need a -bundle in LDFLAGS:
mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v
For linux, you need an equivalent position-independent call, e.g. fPIC and maybe -shared, but I don't have a linux system with a matlab license, so I can't check:
mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
Run the h5_crtfile mex file. This runs without problems on my machine. It just does a H5Fcreate and H5Fclose to create "file.h5" in the current directory, and when I call file file.h5 I get file.h5: Hierarchical Data Format (version 5) data.
Note that if I include a -lhdf5 above in step 3, then matlab aborts when I try to run the executable (because it then uses matlab's dynamic libraries which for me are version 1.6.5), so this is definitely solving the problem on my system.
Thanks for the question. My solution above is definitely much easier for me than what I was doing before. Hopefully the above works for you.
I am accepting Ramashalanka's answer because it led me to the exact solution which I will post here for completeness only:
download the hdf5-1.6.5 library from the hdf5 website, and install the header files in a local directory;
tell mex to look for "hdf5.h" in this local directory, rather than in the standard location (e.g. /usr/include.)
tell mex to compile my code and the shared object library provided by matlab, and do not use the -ldfh5 flag in LDFLAGS.
the command I used is, essentially:
/opt/matlab/matlab_default/bin/mex -v CC#gcc CXX#g++ CFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include" CXXFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include " -O -lmwblas -largeArrayDims -L/usr/lib64 hdf5_read_strings.c /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0
this gets translated by mex into the commands:
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG hdf5_read_strings.c
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG /opt/matlab/matlab75/extern/src/mexversion.c
gcc -O -pthread -shared -Wl,--version-script,/opt/matlab/matlab75/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o hdf5_read_strings.mexa64 hdf5_read_strings.o mexversion.o -lmwblas -L/usr/lib64 /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 -Wl,-rpath-link,/opt/matlab/matlab_default/bin/glnxa64 -L/opt/matlab/matlab_default/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
this solution should work on all my various target machines and at least until I upgrade to matlab r2009a, which I believe uses hdf5-1.8. thanks for all the help, sorry for being so dense with this--I think I was overly-committed to using the packaged version of hdf5, rather than a local set of header files.
Note this would all have been trivial if Mathworks had provided a set of the header files with the Matlab distribution...

Resources