无法使用 CMake link 到 Mac 上的 .so 文件
Can't link to .so file on Mac with CMake
我正在使用 Swig 开发 PHP 7 扩展,我正在尝试 link 到 libphp7.so。来自我的 CMakeLists.txt 文件:
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)
但是我得到一个错误:
[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
我正在尝试 link 的文件:
$ 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
关于如何解决这个问题有什么想法吗?
尽管 Apple 建议为捆绑包提供 .bundle
扩展名,但许多开发人员出于跨平台熟悉度的考虑为他们提供了 .so
扩展名。在 Linux 上,共享模块(MacOS 上的捆绑包)和共享库(MacOS 上的 dylib)没有区别。
请理解,正如 ld
所述,您不能 link 到 MacOS 上的 MH_BUNDLE。它要么需要是 link 的 dylib,要么需要使用 dyld API 加载 .so
。
This link 给出了如何在 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;
}
我发现 how/what 可以从这个 link 中做到:
Clang and undefined symbols when building a library
libphp7.so 不需要在编译时 linked,运行-time 工作正常。这可以通过设置 CXX_FLAG 来启用(有关详细信息,请参阅 link)。
我正在使用 Swig 开发 PHP 7 扩展,我正在尝试 link 到 libphp7.so。来自我的 CMakeLists.txt 文件:
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)
但是我得到一个错误:
[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
我正在尝试 link 的文件:
$ 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
关于如何解决这个问题有什么想法吗?
尽管 Apple 建议为捆绑包提供 .bundle
扩展名,但许多开发人员出于跨平台熟悉度的考虑为他们提供了 .so
扩展名。在 Linux 上,共享模块(MacOS 上的捆绑包)和共享库(MacOS 上的 dylib)没有区别。
请理解,正如 ld
所述,您不能 link 到 MacOS 上的 MH_BUNDLE。它要么需要是 link 的 dylib,要么需要使用 dyld API 加载 .so
。
This link 给出了如何在 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;
}
我发现 how/what 可以从这个 link 中做到: Clang and undefined symbols when building a library
libphp7.so 不需要在编译时 linked,运行-time 工作正常。这可以通过设置 CXX_FLAG 来启用(有关详细信息,请参阅 link)。