how to create dylibs that link to boost - c++

I am using clang and boost 1.57 on OSX Yosemite. I am trying to create a dylib for a python application (used swig to make the wrappers). I have successfully compiled this code for Windows and Linux, so I know it is the build/link phase on OSX that is causing me issues. Here is my makefile (which is wrong, somehow):
CC=clang++
vpath %.c ./
vpath %.h ./
SRCS=RecorderLib.cpp RecorderLib_wrap.cpp
OBJS=$(SRCS:.cpp=.o)
LIBS= -lpython2.7 -lboost_iostreams-mt -lboost_system-mt -lboost_thread-mt -lboost_date_time-mt -lboost_chrono-mt -lboost\
_filesystem-mt -lboost_regex-mt -lboost_atomic-mt -lboost_serialization-mt -lboost_program_options-mt
CFLAGS=-arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.5 -pipe -O2 -c -stdlib=libstdc++
LINKFLAGS = -dynamiclib -undefined suppress -flat_namespace
.PHONY: RecorderLib64.dylib
all: RecorderLib_wrap.o RecorderLib.o RecorderLib64.dylib
RecorderLib_wrap.o:
$(CC) RecorderLib_wrap.cpp $(CFLAGS) $(LIBS) -o RecorderLib_wrap.o
RecorderLib.o:
$(CC) RecorderLib.cpp $(CFLAGS) $(LIBS) -o RecorderLib.o
RecorderLib64.dylib:
$(CC) $(LINKFLAGS) $(OBJS) $(LIBS) \
-o RecorderLib64.dylib
mv RecorderLib64.dylib ../../
clean:
rm *.o
If I remove the -undefined suppress -flat_namespace flags, the thing will toss me a million symbol not found for architecture x86_64 errors for all the boost functions that I reference.
When I include those flags, the library compiles but when I fire up the host application I get an error such as
OSError: dlopen(/Users/myself/RecorderApp/src/RecorderLib64.dylib, 6): Symbol not found: __ZN5boost9iostreams15file_descriptor4seekElSt12_Ios_Seekdir
which I interpret to mean the dylib doesn't know about boost.
One other thing that I don't understand, but is possibly related, is that when I compile the source objects, it tosses me errors such as:
clang: warning: -lpython2.7: 'linker' input unused
On linux, you want to link to libraries both at the compile stage and the link stage (at least this is my understanding -- in any case my Makefile.gnu which I am basing this off of does this and works beautifully).
I should also mention that I can compile applications on this system that link to boost and various dylibs and they work perfectly, so I know my boost installation etc. is alright. Also, inspecting the libraries I link to with the file command tells me they are of the correct x86_64 architecture.
Later:
So, I realize now that the symbol(s) not found for architecture x86_64 errors were actually pointing to functions in the stdlib (but were referenced from boost), i.e.:
"std::basic_streambuf<char, std::char_traits<char> >::setbuf(char*, long)", referenced from:
vtable for boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink, std::char_traits<char>, std::allocator<char>, boost::iostreams::output> in RecorderLib.o
Changing the makefile so that the min osx version is 10.7 and using -stdlib=libc++ gets rid of all theses errors, but I am still getting symbol(s) not found for a boost:iostreams call:
"boost::iostreams::file_descriptor::seek(long,std::__1::ios_base::seekdir)"

Related

Igraph makevars will not link to static library, i can use data structures but cannot functions while importing igraph c++ library

I am trying to install my C++ igraph library from https://github.com/igraph/igraph to visual studio code using the following method this is my makefile made according to this link.
CXX = g++
CXX_FLAGS = -std=c++17 -O3 -march=native -DNDEBUG
LIB = -Llib
INC = -Iinclude
.PHONY: all
all: a.out
a.out: main.cpp
$(CXX) $(CXX_FLAGS) $(INC) $(LIB) -ligraph -lm -lstdc++ -lgomp -lpthread -o $# main.cpp
.PHONY: clean
clean:
rm a.out
The compiler will always return something like:
g++ -std=c++17 -O3 -march=native -DNDEBUG -Iinclude -Llib -ligraph -lm -lstdc++ -lgomp -lpthread -o a.out main.cpp
/usr/bin/ld: /tmp/ccqJLfvi.o: in function `main':
main.cpp:(.text.startup+0x9): undefined reference to `igraph_rng_default'
/usr/bin/ld: main.cpp:(.text.startup+0x16): undefined reference to `igraph_rng_seed'
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: a.out] Error 1
If i only want to use data structures such as igraph_t graph* it will work, but if i try to call fucntion it will return error and will not generate a.out file. It would be incredablly good if someone would be able to explain why this happens cuz it really got on my nerve right now.
Please follow the instructions in the documentation to set up your package to link to igraph.
Instructions to install igraph: https://igraph.org/c/html/latest/igraph-Installation.html Note that you must both build and install the package. Make a note of the location you used to install it to (the value of CMAKE_INSTALL_PREFIX)
Instructions on compiling your first igraph program: https://igraph.org/c/html/latest/igraph-Tutorial.html Unless you are already comfortable with writing C programs and linking them to external libraries, I strongly recommend that you use CMake to set up your project, as described in the linked tutorial. CMake works the same way on all platforms (Windows/macOS/Linux) and will automatically figure out how to link your program to igraph correctly. When configuring your project, be sure to set CMAKE_PREFIX_PATH to the location where you installed igraph earlier.

ld: unrecognized -a option `tic-libstdc++' when using -static-libstdc++ in Makefile?

I am trying to link the "fstream" library to my kernel in C++.
But linker has to have -static-libstdc++ in order for this to work (And G++). But when I go to compile, it says:
ld: unrecognized -a option `tic-libstdc++'
PS: I typed the whole thing (-static-libstdc++)
Does anybody know why this is happening?
Here is my linker command:
ld -z max-page-size=0x1000 -Ttext=0x01000000 -static -Bsymbolic -static-libstdc++ -o $(TARGET) $(OBJS) build/GDT/GDTASM.o
-static-libstdc++ is a compiler option, not a linker option. You already set the linker to link the object files with static libraries (-static). Use -lstdc++:
ld -z max-page-size=0x1000 -Ttext=0x01000000 -static -Bsymbolic -o $(TARGET) $(OBJS) build/GDT/GDTASM.o -lstdc++
Libraries must be listed after object files.
It is better if you do not use ld:
g++ -static-libstdc++ -Wl,-z -Wl,max-page-size=0x1000 -Wl,-Ttext=0x01000000 -Wl,-Bsymbolic -o $(TARGET) $(OBJS) build/GDT/GDTASM.o

dyld: Library not loaded: #rpath/libopenblas.dylib

When I make my file, I have this error:
dyld: Library not loaded: #rpath/libopenblas.dylib Referenced
from: /Users/danyunhe2/reinf_learning2/cpp_original/./navig_test
Reason: image not found Abort trap: 6
I tried ln -sf <original path> /usr/local/lib but it didn't work.
From brew info openblas I got:
openblas: stable 0.3.5 (bottled), HEAD [keg-only]
Optimized BLAS library
https://www.openblas.net/
/usr/local/Cellar/openblas/0.3.5 (22 files, 120.7MB)
Poured from bottle on 2019-02-18 at 01:27:14
From: https://github.com/Homebrew/homebrew- core/blob/master/Formula/openblas.rb
==> Dependencies
Required: gcc ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
openblas is keg-only, which means it was not symlinked into /usr/local,
because macOS provides BLAS and LAPACK in the Accelerate framework.
For compilers to find openblas you may need to set:
export LDFLAGS="-L/usr/local/opt/openblas/lib"
export CPPFLAGS="-I/usr/local/opt/openblas/include"
It told me to set compiler with LDFLAGS and CPPFLAGS. I tried but it didn't work. Anyone know how to deal with this?
I have my config.mk as:
# C++ compiler
cxx=g++-7 -fopenmp
# Compilation flags
cflags=-Wall -ansi -pedantic -O3
# BLAS/LAPACK flags for linear algebra
lp_lflags=-framework Accelerate
# FFTW flags (installed via Homebrew)
fftw_iflags=
fftw_lflags=-lfftw3
# libpng flags (installed via Homebrew)
png_iflags=
png_lflags=-lpng
and Makefile:
# Load the common configuration file
include config.mk
iflags=`gsl-config --cflags`
lflags=`gsl-config --libs`
objs=navigate.o reinf_learn.o common.o
src=$(patsubst %.o,%.cc,$(objs))
execs=navig_test
all:
$(MAKE) executables
executables: $(execs)
depend: $(src)
$(cxx) $(iflags) -MM $(src) >Makefile.dep
-include Makefile.dep
navig_test: navig_test.cc $(objs)
$(cxx) $(cflags) $(iflags) -o $# $^ $(lflags)
%.o: %.cc
$(cxx) $(cflags) $(iflags) -c $<
clean:
rm -f $(execs) $(objs)
.PHONY: clean all executables depend
On OSX it's DYLD_LIBRARY_PATH, which you need to specify at runtime like so:
export DYLD_LIBRARY_PATH=/usr/local/opt/openblas/lib
However, please appreaciate brew's warning regarding the Accelerate framework. It is way faster with many of the BLAS operations on all sorts of levels. You will just make programs run slower.

Installing twitcurl on OS X

I am attempting to install twitcurl on OS X and have met with some problems.
At first, running make would return the clang error: ld: unknown option: -soname. I looked through the responses from other users with similar problems on OS X and found the following advice:
In the makefile, change:
LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
to:
LDFLAGS += -rpath=$(STAGING_DIR)/usr/lib
change:
$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 $(LDFLAGS) -o lib$(LIBNAME).so.1.0 .o -L$(LIBRARY_DIR) -lcurl
to:
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib .o -L$(LIBRARY_DIR) -lcurl
I tried this, but the only result was another clang error: clang: error: unknown argument: '-rpath=/usr/lib'
Any advice towards installing twitcurl on an OS X system will be greatly appreciated.
----UPDATE----
I just wanted to put in one place all the steps I took to make this work, in case any OS X users with similar problems come across this in the future. My thanks to Andy Piper for the crucial pieces.
open the makefile and replace:
LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
with:
LDFLAGS += -rpath $(STAGING_DIR)/usr/lib
and:
$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 $(LDFLAGS) -o lib$(LIBNAME).so.1.0 .o -L$(LIBRARY_DIR) -lcurl
with:
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib *.o -L$(LIBRARY_DIR) -lcurl
(note that this is different by two characters from the advice another OS X user gave above)
after running make, copy libtwitcurl.dylib into /usr/lib/
Downloading the twitterClient (which is also the only code example I could find) will be the same, but for compiling it or your own programs you will need to link -lcurl as well. (g++ appname.cpp -ltwitcurl -lcurl)
Finally, once you compile a program, the path name will likely be incorrect in the executable which is created. Use install_name_tool to correct it. For me this looks like:
install_name_tool -change libtwitcurl.dylib.1 /usr/lib/libtwitcurl.dylib nameofexecutable
but if that doesn't work for you, use otool to find the actual path:
otool -L nameofexecutable
and then the first argument after -change should be the erroneous path for libtwitcurl. You can use otool again after running install_name_tool to be sure the change was successful.
I can get the shared / dynamic library to compile but needed to make a couple of adjustments to your Makefile:
LDFLAGS += -rpath $(STAGING_DIR)/usr/lib
and
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib *.o -L$(LIBRARY_DIR) -lcurl
I've now also built the associated twitterClient utility. To do so, I had to symbolically link libtwitcurl.dylib as libtwitcurl.dylib.1 and also change the consumer key and secret in the code to match a valid one from apps.twitter.com on my account. Works fine.
I assume you want to use the twitcurl library from code? Twitter maintains a Ruby-based utility, twurl, which has a similar function and may also be useful.

Problem with wxWidgets on Snow Leopard

I have a problem with getting compiled an wxWidget-application. I have installed the latest version of the library as follows:
set arch_flags="-arch x86_64 "
./configure -with-osx_cocoa --disable-shared --disable-compat24 --enable-unicode --enable-universal-binary CFLAGS="$arch_flags" CXXFLAGS="$arch_flags" CPPFLAGS="$arch_flags" LDFLAGS="$arch_flags" OBJCFLAGS="$arch_flags" OBJCXXFLAGS="$arch_flags"
sudo make install
I'am trying to compile a simple hello-world example with:
WXWIDGETS = -I/usr/local/include/wx-2.9/
CXXFLAGS = -O2 -g -Wall -Wextra -fmessage-length=0
CXX = $(shell wx-config --cxx)
PROGRAM = wxProjectExample
OBJECTS = $(PROGRAM).o
# implementation
.SUFFIXES: .o .cpp
.cpp.o :
$(CXX) -c `wx-config --static=yes --libs` `wx-config --static=yes --cxxflags` -o $# $<
all: $(PROGRAM)
$(PROGRAM): $(OBJECTS)
$(CXX) -o $(PROGRAM) $(OBJECTS) `wx-config --libs`
clean:
rm -f *.o $(PROGRAM)
But the compilation fails while linking with:
ld: warning: in /System/Library/Frameworks//QuickTime.framework/QuickTime, missing required architecture x86_64 in file
ld: warning: in /usr/lib/libwx_macud-2.8.dylib, missing required architecture x86_64 in file
Undefined symbols:
"wxWindowBase::DoSetVirtualSize(int, int)", referenced from:
vtable for MyFramein wxProjectExample.o
Where could be a problem or have somebody had similar problems with this framework?
Thx.
PS
System: SnowLeopard (64 bit) 10.6.5. with an intel proc, gcc 4.2.
i fixed this problem by adding the path to the new wx-binaries to PATH
$ export PATH=/usr/local/Cellar/wxmac/2.8.11/bin:$PATH
i'm using brew to install wxmac.
I'm surprised that you have libwx_xxx in /usr/lib when the default installation prefix is /usr/local. Are you sure you don't have multiple incompatible libraries versions on your system?
Also, when using static linking the libraries containing the dependencies of your code must come after the object file referencing them so the wx-config --libs part should be at the end of your rule.