1

I'm working on a PHP 7 extension using Swig and am trying to link to libphp7.so. From my CMakeLists.txt file:

find_library(php7_lib php7 PATHS "/usr/local/Cellar/php/7.3.0/lib/httpd/modules" NO_DEFAULT_PATH)
target_link_libraries(navdb_php7_client_api ${php7_lib} dl)

But I get an error:

[100%] Linking CXX shared module .../lib/libnavdb_php7_client_api.so 
...
ld: can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB) file '/usr/local/Cellar/php/7.3.0/lib/httpd/modules/libphp7.so' for architecture x86_64

The file I'm trying to link to:

$ file /usr/local/Cellar/php/7.3.0/lib/httpd/modules/libphp7.so
/usr/local/Cellar/php/7.3.0/lib/httpd/modules/libphp7.so: Mach-O 64-bit bundle x86_64

Any ideas on how to resolve this?

Cinder Biscuits
  • 4,880
  • 31
  • 51
Jason
  • 531
  • 6
  • 19

2 Answers2

0

Although Apple recommends bundles be given the extension .bundle many developers give them the .so extension for the sake of cross-platform familiarity. On Linux, no distinction is made between a shared module (a bundle on MacOS) and a shared library (a dylib on MacOS.)

Understanding that, as ld states, you cannot link to an MH_BUNDLE on MacOS. It either needs to be a dylib to link it, or you need to load the .so using the dyld APIs.

This link gives an example of how to dynamically load a bundle on MacOS:

#include <stdio.h>
#import <mach-o/dyld.h>

int main( )
{
  int the_answer;
  int rc;                // Success or failure result value
  NSObjectFileImage img; // Represents the bundle's object file
  NSModule handle;       // Handle to the loaded bundle
  NSSymbol sym;          // Represents a symbol in the bundle

  int (*get_answer) (void);  // Function pointer for get_answer

  /* Get an object file for the bundle. */
  rc = NSCreateObjectFileImageFromFile("libanswer.bundle", &img);
  if (rc != NSObjectFileImageSuccess) {
    fprintf(stderr, "Could not load libanswer.bundle.\n");
    exit(-1);
  }

  /* Get a handle for the bundle. */
  handle = NSLinkModule(img, "libanswer.bundle", FALSE);

  /* Look up the get_answer function. */
  sym = NSLookupSymbolInModule(handle, "_get_answer");
  if (sym == NULL)
  {
    fprintf(stderr, "Could not find symbol: _get_answer.\n");
    exit(-2);
  }

  /* Get the address of the function. */
  get_answer = NSAddressOfSymbol(sym);

  /* Invoke the function and display the answer. */
  the_answer = get_answer( );
  printf("The answer is... %d\n", the_answer);

  fprintf(stderr, "%d??!!\n", the_answer);
  return 0;
}
Cinder Biscuits
  • 4,880
  • 31
  • 51
  • Thanks for the info, but when creating libnavdb_php7_client_api.so how do I link to libphp7.so? If I don't link to it I get missing symbol errors. – Jason Jan 03 '19 at 06:24
0

I found out how/what to do from this link: Clang and undefined symbols when building a library

The libphp7.so doesn't need to be linked to at compile time, run-time works fine. This can be enabled by setting a CXX_FLAG (see the link for details).

Jason
  • 531
  • 6
  • 19