Building a Boost.Python application on MacOS 10.9 (Mavericks) - c++

I upgraded to Mavericks, and am now unable to build my application after much troubleshooting.
During linking, I receive the errors
Undefined symbols for architecture x86_64:
"boost::python::objects::function_object(boost::python::objects::py_function const&, std::pair<boost::python::detail::keyword const*, boost::python::detail::keyword const*> const&)
.
.
.
"boost::python::objects::register_dynamic_id_aux(boost::python::type_info, std::pair<void*, boost::python::type_info> (*)(void*))"
I am using g++ from macports, specifically g++-mp-4.4. Clang is not an option for my project, as my project depends upon OpenMP, which is currently incompatible with Clang.
I have not been using the C++11 runtime, but the Boost.Python library from macports (the one I am using during linking) is linked against it.
otool -L libboost_python-mt.dylib
libboost_python-mt.dylib:
/opt/local/lib/libboost_python-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
Is this the root of my problem? Compiling part of my project with Clang succeeds (and hurdles this linking error stage), yet as I mentioned, I required OpenMP.
Notably, running:
nm libboost_python-mt.dylib | c++filt | grep boost::python::objects::function_object
outputs
0000000000013d60 T boost::python::objects::function_object(boost::python::objects::py_function const&)
0000000000013d00 T boost::python::objects::function_object(boost::python::objects::py_function const&, std::__1::pair<boost::python::detail::keyword const*, boost::python::detail::keyword const*> const&)
which have std::__1 prefixes, which do not match what is expected in the undefined symbols errors...

The solution was achieved by installing and linking against a version of Boost that was not compiled with c++11. The version of Boost provided by Macports apparently built Boost.Python with C++11, despite the fact that I specifically set the Macports compiler to be g++-mp-4.4, which should not be able to build with C++11...
Note that at the time of writing, it is quite difficult to install Boost libraries compiled with g++ via Macports, and I eventually installed Boost libraries from source.

Related

SFML: dyld: Library not loaded error even though lib paths updated

I am trying to link my program (writing it with vim) with SFML. I have my src folder, which contains my code, and the SFML libraries are located at /opt/local/lib. This is the command I am using to compile my code:
g++ src/main.cpp -L/opt/local/lib -lsfml-graphics.2.5 -lsfml-network.2.5 -lsfml-system.2.5 -lsfml-audio.2.5 -lsfml-window.2.5
The code compiles, however, when running the executable I get this error:
dyld: Library not loaded: #rpath/../Frameworks/freetype.framework/Versions/A/freetype
Referenced from: /opt/local/lib/libsfml-graphics.2.5.dylib
Reason: image not found
This is strange, because otool -L a.out tells me that the dylibs are in the correct place:
/opt/local/lib/libsfml-graphics.2.5.dylib (compatibility version 2.5.0, current version 2.5.1)
/opt/local/lib/libsfml-network.2.5.dylib (compatibility version 2.5.0, current version 2.5.1)
/opt/local/lib/libsfml-system.2.5.dylib (compatibility version 2.5.0, current version 2.5.1)
/opt/local/lib/libsfml-audio.2.5.dylib (compatibility version 2.5.0, current version 2.5.1)
/opt/local/lib/libsfml-window.2.5.dylib (compatibility version 2.5.0, current version 2.5.1)
These paths are the correct paths, and #rpath is not listed anywhere in these paths, but the error still says that there is a problem with a dylib with #rpath in its path, which is very weird. Why is this happening and how can I fix it?
Fixed! Turns out that I didn't add the dependencies to /opt/local/lib.

errors linking clang-built executable with g++-v6-built boost library

I have a boost regex library built myself with g++ version 6.3.1 on Fedora Linux.
Then I have my own library using the boost regex, built with clang++ 4.0 as shared object.
Building this works fine.
At last I have an executable which links to my library and this produces the following error:
undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform[abi:cxx11](char const*, char const*) const'
Building and linking with g++ only works correctly.
Can this be solved with some commandline argument to clang++?
As nobody seems to have a solution for this, I compiled boost a second time with
./b2 toolset=clang
and now my problems are gone.

Link only libc, and not libc++ in C++

Is it possible, with both clang and gcc, in a portable way to not link libstdc++ or libc++, but still link libc and use all the features of C++ (well, only classes).
-nodefaultlibs doesn't seem to work after my first test (tested on OS X), it does not link libstdc++, but it also doesn't link with libSystem, which is required.
The best, and most portable solution is, to just not link any default libraries, and link everything manually.
Adding:
-nodefaultlibs -lc
will not link anything, and afterwards just link libc. Now you've got C with Classes.
You can verify that with either otool -L (on OS X) or ldd (on Linux).
On OSX the output now is:
$ otool -L ./test
test:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
instead of
$ otool -L ./test
./test:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)

OpenSceneGraph Linker error on Mac with Macports

I am having a problem getting an OpenSceneGraph project to link properly on my Mac. I installed it via macports and I have gotten osgviewer and other osg programs to work, meaning it was compiled and linked somehow. The code is part of a larger project, however I separated out the OSG code down to the bare bones to isolate my problems. I first thought it was a CMake issue, so I created a Makefile to try and isolate there. That made no difference.
Here is the the sample code.
// OpenSceneGraph Libraries
#include <osg/Geode>
#include <osg/Group>
#include <osg/ShapeDrawable>
#include <osgUtil/Optimizer>
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/Simplifier>
#include <osg/Node>
#include <osg/Texture1D>
#include <osg/Texture2D>
#include <osg/TexGen>
#include <osg/Material>
#include <osgViewer/Viewer>
#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osgDB/ReadFile>
#include <osgSim/Version>
#include <osgFX/Version>
#include <osgTerrain/Version>
#include <osgVolume/Version>
// C++ Libraries
#include <iostream>
#include <string>
/**
* #brief Main Application
*/
int main( int argc, char* argv[] )
{
// Define Write Options
osgDB::Options* write_options = new osgDB::Options("WriteImageHint=IncludeData Compressor=zlib");
// Create the Root Nodes
osg::ref_ptr<osg::Group> root_node(new osg::Group());
// Write the Node File
osgDB::writeNodeFile( *root_node.get(),
"output.osgb",
write_options );
// Return
return 0;
}
Here is the Makefile code. I have added way more than needed to no effect.
OSG_LIBS=-lOpenThreads -losgDB -losg -losgUtil -losgTerrain
LIBS=-L/opt/local/lib $(OSG_LIBS)
INCL=-I/opt/local/include
CPP=clang++
foo: foo.cpp
$(CPP) foo.cpp $(LIBS) $(INCL)
Here is the make output with VERBOSE=1 on the specific command.
$ make VERBOSE=1
clang++ foo.cpp -L/opt/local/lib -lOpenThreads -losgDB -losg -losgUtil -losgTerrain -I/opt/local/include
Undefined symbols for architecture x86_64:
"osgDB::writeNodeFile(osg::Node const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, osgDB::Options const*)", referenced from:
_main in foo-2c45f6.o
"osgDB::Options::parsePluginStringData(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char, char)", referenced from:
osgDB::Options::Options(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in foo-2c45f6.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [foo] Error 1
I have run otool and other apps against the shared libraries to try and find where the undefined reference is. I know when I run nm, the symbol for both of these methods are in libosgDB.dylib, yet linking it does not work.
I am starting to compile OpenSceneGraph from source, but that is also creating compile errors on its own. I have a long fight ahead of me. Thank you very much in advance for your time.
Update:
Observations
Reordering the libraries on the compiler line does not work.
Hm, I can reproduce your problem. It seems the libosgDB.dylib installed by MacPorts' OpenSceneGraph port links against libstdc++:
$ otool -L /opt/local/lib/libosgDB.dylib
/opt/local/lib/libosgDB.dylib:
/opt/local/lib/libosgDB.100.dylib (compatibility version 100.0.0, current version 3.2.1)
/opt/local/lib/libosgUtil.100.dylib (compatibility version 100.0.0, current version 3.2.1)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 157.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 22.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/opt/local/lib/libosg.100.dylib (compatibility version 100.0.0, current version 3.2.1)
/opt/local/lib/libOpenThreads.20.dylib (compatibility version 20.0.0, current version 3.2.1)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1255.1.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 728.4.0)
I consider this to be a bug of the OpenSceneGraph port. Please file a ticket to get this fixed. Meanwhile, use -stdlib=libstdc++ in your compiler command line to get your example to link. Note that this means you cannot use C++11 features.

Is it possible to link libstdc++ statically in Mac OSX 10.6?

I am trying to run my C++ program on other Mac OSX machines which may have an older copy of libstdc++, but have all the other tools. I tried to follow this approach, also mentioned in this SO question, even though it discusses a linux setup. I have small program try.cpp:
#include <iostream>
int main() {
int a = 10;
std::cout << a << '\n';
return 1;
}
Obviously, if I just compile it, I get
$ /usr/bin/g++ try.cpp
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
I understand the dependency on libSystem.B.dylib, and we can leave that aside. To try to get rid of libstdc++, I try this:
$ /usr/bin/g++ try.cpp /usr/lib/libstdc++-static.a
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
So, I try
$ ln /usr/lib/libstdc++-static.a .
$ /usr/bin/g++ try.cpp -L.
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
or,
$ /usr/bin/g++ try.cpp -L. -lstdc++-static
$ otool -L a.out
a.out:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
Finally, this works:
$ /usr/bin/gcc try.cpp -L. -lstdc++-static
$ otool -L a.out
a.out:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)
Is this alright? (To use gcc to link C++ programs with libstdc++). I've heard somewhere that g++ is actually a script that uses gcc and libstdc++ to compile C++ programs. If that is the case, and we use it correctly, it should be ok.
However, I am actually using the macport compiler and a more complicated program, for which gcc generates some warnings, while it is C++ compliant. Something to the effect of:
ld: warning: std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf() has different visibility (hidden) in /opt/local/lib/gcc44/libstdc++.a(sstream-inst.o) and (default) in /var/folders/2u/2uLPtE+3HMi-BQIEfFVbSE+++TU/-Tmp-//ccoE2rqh.o
This suggests that we shouldnt be using gcc for c++ compilations. So to sum up, the questions are:
How to link libstdc++ statically
If g++ doesn't do it, is it ok to use gcc and supply the libstdc++ manually? Then why the visibility warnings?
If neither of the two approaches work because of the visibility problems in the compiled libraries, why not use libstdc++ source files (sstream.h, list.h, vector.c) etc and just include them in the compilation. Even though this will make the compilation slow, it might be useful for certain applications. It might even lead to better optimization!
It sounds like you just want to target earlier Mac OS X versions, which can be done without statically linking with libstdc++. I think the GCC that ships with Xcode targets the host environment by default. However, it can handle a special flag called -mmacosx-version-min to change the target environment. If you provide this with the target OS X version number then it will automatically create binaries compatible with that version of Mac OS X.
#include <iostream>
int main(void)
{
std::cout << "Hello world!" << std::endl;
return 0;
}
Compile like this:
g++ -mmacosx-version-min=10.4 test.cpp
I compiled this program twice, once with the flag and once without, and then I copied both binaries to a Mac running 10.4. The one compiled with the flag executed properly, however the one compiled without the flag said “Bad CPU type in executable” (despite the fact that it was compiled on an identical machine just running a later version of OS X).
Some of the headers have macro guards that prevent you from using functions/classes introduced in 10.5 or 10.6 if you have specified 10.4 as a minimum target (I'm not sure about C++ headers, but the Cocoa, Foundation, AppKit etc. framework headers definitely do).
This is a stretch for my knowledge but I see few responses here so!
GCC is a compiler driver that will also drive the linker. g++ to my understanding is more of just a compiler. So to get G++ to build properly I believe you need to build the object files and link them manually. Of the top of my head I can't say how to do this as I'm IDE brain damaged at the moment.
As to the error you have seen that might be due to the wrong files being linked in. I'm on my iPhone right now so I'm not about to dechiper the error message you printed. I'm not a fan at all of MacPorts so don't be surprised that, that installation is screwed up. First though make sure you are using the MacPorts libs with the MacPorts compiler.
In the end I have no doubt that you can do what you want to do. You will need to however start reading Make files and more of the documentation of the GCC tool set. Focus on building and linking files into programs. You might want to find a small open source program tha builds nicely on a mac and look at the Make files there.
Of course finding a good C++ based project to learn from is not easy. I would however reccomend installing LLVM & CLang especially considering the new rev is suppose to be C++ ready. Obviously a different set of tools but CLang may resolve your issues or at least give you better debugging info. Maybe somebody can chime in with an opensource C++ project with simple clean make files. The closest I've seen lately is a project called HeeksCAD.
In the end when building anything non trivial you end up needing more than just GCC. A lot of that is taken care of with IDEs these days, however I'm not certain if XCode can be properly configured to do what you want.