MAC OSX dylib's and how to use them - macos

I downloaded and installed (I think) gtk on the Mac OSX (Lion). Compilation of test program went fine after getting all the -I's correct. Now the link is failing. A grep for the missing entrypoints
_gtk_init
_gtk_window_new
... 11 more
found them in
/Users/ccpalmer/gtk/inst/lib/libgtk-quartz-2.0.0.dylib
/Users/ccpalmer/gtk/inst/lib/libgtk-quartz-2.0.dylib
Being less familiar with OSX's underlying Unix, I'm not sure how to get thru the link step. I must admit, I've never encountered a "dylib" before.
Are there any OSX dev smarties out there who might shed some light on my mystery?
Charles

As moshbear commented above, dylib files are how shared libraries are packaged on Mac OS X. To use such a shared library, you need to pass two switches to your compiler, -L and -l. The first adds the directory containing your dylib to the linker's library search path, and the second specifies the library to link against. Something like this, for a fictional libfoo.dylib that lives in /usr/mylibs:
clang code.c -L/usr/mylibs -lfoo

Related

homebrew llvm build cannot find iOS simulator library containing _wordexp symbol

I'm working on touching up homebrew's (OS X package manager) llvm formula. Unfortunately, something about the parts I added broke the build in a way I just cannot figure out.
tl;dr ld asks for a library containing a _wordexp symbol for iOS simulator, and I have absolutely no clue where it is, if it exists
Compilation consistently fails for me when the compiler is attempting to link the address sanitizer dylib for iOS Simulator.
Reproduction steps (OS X only as far as I know, don't have *nix systems handy):
install homebrew if it isn't already installed
replace homebrew's llvm formula with the WIP one above
Run brew install llvm --with-clang --with-lldb --verbose --debug
wait for the build to fail and ask you what to do
Drop into a debug shell
cd to projects/compiler-rt/lib/asan/CMakeFiles/clang_rt.asan_iossim_dynamic.dir
add the following line to link.txt
-Wl,-syslibroot /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
go back up to asan
Run make
At this point on my machine, something like this pops up:
Undefined symbols for architecture x86_64:
"_wordexp", referenced from:
_wrap_wordexp in asan_interceptors.cc.o
substitution_wordexp in asan_interceptors.cc.o
(maybe you meant: _wrap_wordexp)
ld: symbol(s) not found for architecture x86_64
I thought that it was just a matter of adding another folder to the linker search path. Turns out it isn't that simple:
wordexp.h is in <path-to-iPhoneSimulator.sdk>/usr/include, but running
find . -type f -name "*.dylib" -print0 | xargs -0 nm | grep -n "T _wordexp" -B <large number> | less
in Xcode-beta.app showed that the only .dylibs in Xcode that exported a _wordexp symbol were in the WatchSimulator.platform folder
Running the same command in /usr showed that 3 libraries in /usr/lib/system exported _wordexp (libsystem_asl, libsystem_c, and libsystem_blocks), but the linker doesn't seem to care when I add /usr/lib/system to the search path even when the code is the x86_64 code it wants, and the corresponding dylibs I found for other platforms didn't contain _wordexp
Googling about about this particular symbol missing turned up mostly stuff about Apple implementing wordexp() with Perl
I think I remember seeing something in the llvm-dev mailing list archives about *BSD/OSX not implementing wordexp, but the header file is definitely there, wordexp() shows up in the manpages, and the functions declared in the header file seem to work just fine when compiling for OSX
The symbol is not in the libc++(abi) dylibs compiled earlier in the build
Every other part of the build compiles just fine except for the asan folder and its parents
What am I missing? Given that this error does not seem to be particularly common, there could be a chance it's my machine, but I'm hoping the chances are pretty low, because I wiped and reinstalled my computer this weekend.
(OS X 10.11, Xcode/CLT 7.1, mid-2012 Retina pro)
If more info is needed I'll be happy to provide it.
Edit 1: Simplified link.txt fix. Turns out setting sysroot for clang++ doesn't do so for ld
Turns out the error was a result of the way homebrew processed compiler flags. That and a few other problems have been fixed since, so this probably isn't too useful any more.
For those curious about how exactly this broke, homebrew tries to change compiler flags to suppress warnings and create a more consistent building experience. One of these changes was to remove any -isysroot or -system flags, because that was added by homebrew itself at a later stage. Unfortunately, homebrew assumed that only the OS X SDK would be used, so when the build expected to build something with the iPhone simulator SDK it was pointed to the OS X SDK.

Statically link OpenSSL in XCode

I am trying to link libssl.a and libcrypto.a static libraries in XCode command line project [under Link Binary With Libraries]. I have included Openssl header files in search path.
Compilation succeeds but execution fails with dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Any help would be appreciable.
Why does it look for dylib when I am linking it statically? How can this be fixed?
Apple's linker uses the dylib or share object if its available, regardless of of your linker flags like -rpath and -Bstatic. They even do it on iOS, where dylib's are not allowed!
Its kind of a well known problem once you know about it :) See, for example, Installing Crypto++ 5.6.2 on Mac OS X. Crypto++ has the same problems with Apple's tools.
The fix is to stop using -L and -l options, and to link the object file or archive directly. An archive is just a collection of object files, so you can use them interchangeably.
To specify the object files or archives for the linker, see Linking to an object file. Under Xcode, you add the fully specified archive name (like /usr/local/openssl-ios/lib/libcrypto.a) to Other Linker Flags (the OTHER_LDFLAGS Xcode option).
When adding the full archive to OTHER_LDFLAGS, I believe you just add it verbatim without any switches, like -l or -L. You may need -Wl (-Wl,/usr/local/openssl-ios/lib/libcrypto.a), but you don't use -l (-l/usr/local/openssl-ios/lib/libcrypto.a).
You use -Wl when the option is passed through the compiler driver to the linker. If the linker is invoked directly, then you don't need -Wl and should not use it.
A second option is to set GCC_LINK_WITH_DYNAMIC_LIBRARIES to YES. Apple does not appear to document it in Xcode Build Setting Reference, but its clearly under my copy of Xcode. See How to link a static library for iOS on Stack Overflow.
I seem to recall having problems with this in the past. Its one of those things that should work in theory, but does not work in practice.
A third option is to remove the dylib or shared object from all paths used under Xcode so Xcode does not accidentally find it when using -lcrypto.
A fourth option is use allow dynamic linking, but execute the program with DYLD_LIBRARY_PATH. Its OS X's equivalent to LD_LIBRARY_PATH, and ensures your copy of OpenSSL is loaded (like 1.0.2), and not the system's version of OpenSSL (0.9.8).
But I don't like this option because it requires users of your software to do something.
Another possibility due to the message dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib is to code sign your copy of the library. Its a little odd its found but not loaded, so I'm going to toss this out there in case its OS X's Code Signing or Gatekeeper Service...
To code sign your copy of the library under the MAC Developer program, just:
codesign -fs "Johnny Developer" /usr/local/ssl/lib/libcrypto.so

How to compile fortran code to run without gfortran installed

I have downloaded Bellhop, which is an underwater acoustic simulator written in Fortran. It can be found here with the Makefile.
Question 1: I would like to know if it is possible to compile Fortran code, including everything needed, so a user without gfortran installed, can run it.
I have read here the following:
static linking
This section does not apply to Windows users, except for Cygwin users with gcc4-4.3.2-2 or later.
gfortran is composed of two main parts: the compiler, which creates the executable program from your code, and the library, which is used when you run your program afterwards. That explains why, if gfortran is installed in a non-standard directory, it may compile your code fine but the executable may fail with an error message like library not found. One way to avoid this (more ideas can be found on the binaries page) is to use the so-called "static linking", available with option -static gfortran then put the library code inside the program created, thus enabling it to run without the library present (like, on a computer where gfortran is not installed). Complete example is:
gfortran -static myfile.f -o program.exe
Reading this, I suppose that it is possible to do what I'm asking but I'm not very familiarized with fortran and makefiles. I don't understand this:
put the library code inside the program created
Question 2: How can I put the library code inside the program? Where can I find the library? What does "inside the program" means?
I'm running OSX 10.9.4 and gfortran
I solved my problem about compiling Fortran code with gfortran using static libraries.
As #M.S.B. said, using static-libgfortran worked for me under MacOS.
If somebody is having issues with linking the libquadmath.0.dylb library, remove libquadmath.0.dylib and libquadmath.dylib from /usr/local/gfortran/lib/
This doest the trick. Further information can be found here
I think the meaning of the bold part is actually
gfortran then puts the library code inside the
program created
That means using -static should be enough, there is no additional step. Just be advised you will need a static version of all the libraries that you link with.
I know this is very old tracker, but maybe somebody will be still interested in the solution that works.
Let's say we have code:
! fort_sample.f90
program main
write (*,*) 'Hello'
stop
end
First, compile the stuff:
gfortran -c -o fort_sample.o fort_sample.f90
Then, link stuff
ld -o ./fort_sample -no_compact_unwind \
-arch x86_64 -macosx_version_min 10.12.0 \
-lSystem \
/usr/local/gfortran/lib/libgfortran.a \
/usr/local/gfortran/lib/libquadmath.a \
/usr/local/gfortran/lib/gcc/x86_64-apple-darwin16/6.3.0/libgcc.a \
fort_sample.o
You can execute it
./fort_sample
Hello
You can notice that quadmath is no longer there
> otool -L fort_sample
fort_sample:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.51.1)
I guess this is what you were looking for in a first place. No removing dylibs, no symbolic links, etc.
The current version of the option is -static-libgfortran. This means that the Fortran specific libraries of gfortran will be included into the executable. These are libraries are automatically found for a good installation of gfortran. This should produce an executable that should run on other computers with the same OS, even if that computer doesn't have gfortran installed. This option likely doesn't statically link all libraries, so there is some risk that some other shared library used on your computer won't be available on the other computer.

Proper way to upgrade from llvm-g++-4.2 to g++-4.7 on Mac

I have Lion 10.7.3 with the Command-line tool installed. I wanted to experiment with C++11, so I used homebrew to install GCC 4.7 as documented here.
How can I now upgrade the /usr/bin/g++ to be the one installed by Homebrew? Is it as simple as symlinking it? I just want to double check and make sure. Thanks!
First, are you sure you need g++ 4.7? As you can see from the C++11 implementation status page, recent versions of clang support most of C++11 too. Of course there are still things that g++ handles and clang doesn't, but there are also still things that clang supports and g++ doesn't. And, more importantly, you already have a recent version of clang, from Apple, configured and ready to go, as your default compiler. Plus, g++ after 4.2 doesn't support Mac extensions like, say, -arch, which means you can't use it to build a whole lot of third-party software (because most configure scripts assume that if you're on a Mac, your compiler supports Mac extensions).
But if you want g++ 4.7, you can do it. Just not by trying to replace /usr/bin/g++ with a different version. Never replace anything in /usr/bin (or /System) with non-Apple stuff except in a few very rare cases (when you have a strong reassurance from someone who knows what they're talking about).
A better thing to do is to just install another compiler in parallel. Just let Homebrew install its favorite way (so it installs into some prefix like /usr/local/Cellar/gcc/4.7, then symlinks all the appropriate stuff into /usr/local/bin, etc.), and use it that way.
When compiling your code, instead of writing g++, write /usr/local/bin/g++, or g++-4.7.
If you get tired of doing that, put /usr/local/bin higher on your PATH that /usr/bin, or create a shell alias, or stick it in the environment variable CXX and write $CXX instead of g++.
If you're using a GUI IDE, you should be able to configure it to use your compiler by setting the path to it somewhere. (Unless you're using Xcode, which you can only configure to work with Apple-tested compilers.)
This is all you need for experimenting with your own code. If you want to compile third-party applications with this compiler, that may be a bit more complicated. You don't often actually compile each source file and link the result together; you just do configure && make and let them do the heavy lifting for you.
Fortunately, most packages will respect the standard environment variables, especially CXX for specifying a default C++ compiler and CC for a default C compiler. (That's why I suggested the name CXX above.)
Just remember that, again, g++ 4.7 doesn't support Mac extensions, so if you're not prepared to debug a bunch of autoconf-based configure scripts complaining that your compiler can't generate code because it assumed it could throw -arch x86_64 at any compiler on a Mac, etc., don't do this.

Problems compiling TCC on OS X

Has anyone successfully compiled TCC on OS X?
From what I know it should be possible but when I run make I get the following error:
$ make
gcc -o tcc tcc.c -DTCC_TARGET_I386 -O2 -g -Wall -fno-strict-aliasing -mpreferred-stack- boundary=2 -march=i386 -falign-functions=0 -Wno-pointer-sign -Wno-sign-compare -D_FORTIFY_SOURCE=0 -lm -ldl
tcc.c:1: error: CPU you selected does not support x86-64 instruction set
tcc.c:1: error: CPU you selected does not support x86-64 instruction set
tcc.c:1: error: -mpreferred-stack-boundary=2 is not between 4 and 12
make: *** [tcc] Error 1
./configure runs fine and gives the following output:
$ ./configure
Binary directory /usr/local/bin
TinyCC directory /usr/local/lib/tcc
Library directory /usr/local/lib
Include directory /usr/local/include
Manual directory /usr/local/man
Doc directory /usr/local/share/doc/tcc
Target root prefix
Source path /Users/aaron/Downloads/tcc-0.9.25
C compiler gcc
CPU x86
Big Endian no
gprof enabled no
cross compilers no
use libgcc no
Creating config.mak and config.h
I'm pretty sure the issue is something simple, but I haven't compiled enough programs on OS X to be aware of the pratfalls...
The primary purpose for installing TCC was to get libtcc so I could start experimenting with dynamic code generation from Ruby (in case that makes a difference :-p)
Thanks!
I have just spent some serious time trying to make tcc run on osx. I have included several fixes, including the one from the answer above, and now they are all in the development repository at http://repo.or.cz/w/tinycc.git. Building, some tests and all examples should work.
I am not sure if you are aware, but http://bellard.org/tcc/ site that belongs to Fabrice Bellard who started this project, is not being updated very regularly. Mostly because there are not many 'official' tcc releases. tcc is one of those projects that mostly lives off of live sources and updates. So if you want to give this another try, please go to http://repo.or.cz/w/tinycc.git and get the 'mob' branch (not 'master'). Please see http://repo.or.cz/w/tinycc.git for details, and do join the mailing list to get involved.
I'll consolidate my comments now.
There seem to be several issues.
There has been a change in the naming scheme for the x86 register access as of Mac OS 10.5. See Access EIP and EBP via ucontext on OS X. This will require hacking the source until the maintainer can be convinced to support Mac OS X.
The executable formats supported by tcc do not overlap with those that Mac OS X will run natively. However, XBinary may address this. (I didn't find either a fink package or a MacPorts package, however and don't have it installed yet. Not sure that I will--this is deep magic, and could in theory do very bad things indeed.) Ah... this was already on SO too: Possibility of loading/executing ELF files on OSX.
The errors can be fixed by edit configure script of TCC package (ver 0.9.25).
In the configure script, line 36 says
cpu=uname -m
If you run uname -m in the console of Mac OS X, it prints "i386" even if it is a 64-bit system.
A solution is to comment off this line, and replace it with cpu=x86_64,
Then some compiling errors will show up because of the register naming conventions in Mac OS X, as mentioned by dmckee in this thread.
My fix is to add a few lines to libtcc.c around line 1512.
Finally it will look like
#ifdef __DARWIN_UNIX03
*paddr = uc->uc_mcontext->__ss.__rip;
#else
*paddr = uc->uc_mcontext.gregs[REG_RIP];
#endif
return 0;
} else {
#ifdef __DARWIN_UNIX03
fp = uc->uc_mcontext->__ss.__rbp;
#else
fp = uc->uc_mcontext.gregs[REG_RBP];
#endif
It compiles then.

Resources