Project

General

Profile

Bug #49

Darwin: shared libraries have the wrong internal name

Added by Anonymous about 7 years ago. Updated almost 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
libgdp
Start date:
08/23/2016
Due date:
% Done:

0%


Description

I'm tracking down a problem where in GDP/JavaScript interface where debug flags are not preserved and ran across a problem where linking fails under Darwin with shared libraries.

The solution is that under Darwin, either we use create libgdp.0.7.dylib or run

 install_name_tool -id libgdp.0.7.dylib libs/libgdp.0.7.dylib 

Here's my setup inside the gdp tree:

bash-3.2$ cd test
bash-3.2$ ls ../libs
libep.3.0.dylib         libgdp.0.7.dylib        makelinks.sh
libep.a                 libgdp.a
libep.dylib             libgdp.dylib

In the above note that libgdp.0.7.dylib is in the libs/ directory.

Here's a small test case, where we set the debug file and then get it:

bash-3.2$ cat epTest.c
#include <stdio.h>
#include <ep.h>
#include <ep_dbg.h>

int main(int argc, char **argv) {
  FILE *fp = fopen("foo.txt", "w");
  ep_dbg_setfile(fp);
  printf("ep_dbg_getfile(): %p\n", ep_dbg_getfile());
}
bash-3.2$ cc -I ../ep/ -Wl,-rpath,/Users/cxh/ptII/vendors/gdp/gdp/libs -I .. epTest.c -L ../libs -lgdp.0.7

Sadly, Darwin does not have ldd, we have to use otool to see what dependencies we have.

bash-3.2$ otool -L a.out
a.out:
        libgdp.so.0.7 (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

In the above, note that the binary was created with a dependency on libgdp.so.0.7 instead of libgdp.0.7.dylib

bash-3.2$ ./a.out
dyld: Library not loaded: libgdp.so.0.7
  Referenced from: /Users/cxh/ptII/vendors/gdp/gdp/test/./a.out
  Reason: image not found
Trace/BPT trap: 5
bash-3.2$ 

In the above, the binary does not run.

However, if we copy the shared library to libgdp.so.0.7, then it works!

bash-3.2$ cp ../libs/libgdp.0.7.dylib ../libs/libgdp.so.0.7
bash-3.2$ otool -L a.out
a.out:
        libgdp.so.0.7 (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
bash-3.2$ ./a.out
ep_dbg_getfile(): 0x7fff7082b050
bash-3.2$ 

One possible solution is to have the Makefile generate libgdp.0.7.dylib.

Another possibility is to use the Mac install_name_tool:

bash-3.2$ rm ../libs/libgdp.so.0.7
bash-3.2$ install_name_tool -change libgdp.so.0.7 libgdp.0.7.dylib a.out
bash-3.2$ otool -L a.out
a.out:
        libgdp.0.7.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
bash-3.2$ ./a.out
ep_dbg_getfile(): 0x7fff7082b050
bash-3.2$ 

It would be nice if there was a command to update the LC_ID_DYLIB in the shared library. To see the value of LC_ID_DYLIB:

bash-3.2$ otool -l ../libs/libgdp.0.7.dylib
....
Load command 3
          cmd LC_ID_DYLIB
      cmdsize 40
         name libgdp.so.0.7 (offset 24)
   time stamp 1 Wed Dec 31 16:00:01 1969
      current version 0.0.0
compatibility version 0.0.0
...

It looks like install_name_tool -id will work, see http://stackoverflow.com/questions/33991581/install-name-tool-to-update-a-executable-to-search-for-dylib-in-mac-os-x

To replicate, clean the gdp with (cd ..; make clean; make all_noavahi), then:

bash-3.2$ cd test
bash-3.2$ install_name_tool -id libgdp.0.7.dylib ../libs/libgdp.0.7.dylib 
bash-3.2$ cc -I ../ep/ -Wl,-rpath,/Users/cxh/ptII/vendors/gdp/gdp/libs -I .. epTest.c -L ../libs -\
lgdp.0.7
cc -I ../ep/ -Wl,-rpath,/Users/cxh/ptII/vendors/gdp/gdp/libs -I .. epTest.c -L ../libs -lgdp.0.7
bash-3.2$ ./a.out
./a.out
ep_dbg_getfile(): 0x7fff7082b050
bash-3.2$ 

History

#1 Updated by Eric Allman about 7 years ago

  • Status changed from New to Resolved

I have changed the libs/makelinks.sh script to leave libgdp.so.0.7 around. I know this isn't the Apple-blessed way of doing things, but Darwin/Mac is not a supported platform, so this is good enough.

#2 Updated by Nitesh Mor about 7 years ago

  • Status changed from Resolved to Closed

#3 Updated by Anonymous about 7 years ago

This bug has not been fixed, so it should not be closed. Creating a .so file instead of a .dylib file causes problems on the Mac when linking.

The best solution would be to generate a .dylib file.

An alternative would be under Darwin to invoke install_name_tool.

#4 Updated by Eric Allman about 7 years ago

  • Status changed from Closed to Feedback

I have changed libs/makelinks.sh to do the

install_name_tool -id libgdp.0.7.dylib ../libs/libgdp.0.7.dylib

command. If this doesn't fix the problem, then I'll change the state of this to "Rejected". Darwin is not a supported platform, and I'm not willing to have the Makefiles jump through hoops to support an unsupported platform.

#5 Updated by Anonymous about 7 years ago

Thanks for making that fix, the path name is in the library is correct under Mac OS X and the binary that is created has the correct name reported by otool -L

A couple of small issues remain:

1) .so libraries are still being created:

bash-3.2$ find . -name "*.so*" -ls
6200922      200 -rwxr-xr-x    1 cxh              staff              100720 Sep  6 16:43 ./ep/libep.so.3.0
6200962      416 -rwxr-xr-x    1 cxh              staff              209840 Sep  6 16:43 ./gdp/libgdp.so.0.7
6200923      200 -rwxr-xr-x    2 cxh              staff              100720 Sep  6 16:43 ./libs/libep.so.3.0
6200963      416 -rwxr-xr-x    2 cxh              staff              209840 Sep  6 16:43 ./libs/libgdp.so.0.7

2) "make clean" does not remove the .dylib files:

BTW - you were not on the 8/26 Enhanced Classroom call where GDP platforms came up. My notes from https://www.terraswarm.org/urbanheartbeat/wiki/Main/2016-08-26 state:

Summary about Mac: It is a best effort platform, we would like to have a separate category for Mac platform issues.

I understand the hell of supporting multiple platforms, I've done it myself for many years. The reality is that if Edward can't run GDP clients locally on his Mac, then he probably won't use the GDP. The GDP support for the Mac is pretty good, things basically work. Renaming shared libraries from .so to .dylib causes subtle failures that most people will have a difficult time tracking down. I think what we have now is close. It would be great if these last two issues could be addressed. The fix for make clean is quick, just add *.dylib. I'd like to see the .so files not be created under Mac OS X because they cause confusion, but that would be a lower priority task.

#6 Updated by Eric Allman about 7 years ago

These issues should all be fixed now. As it turns out libs was never being cleaned at all.

#7 Updated by Anonymous almost 7 years ago

  • Status changed from Feedback to Closed

Thanks, this works for me now so I'm closing this.

Also available in: Atom PDF