app的命令行链接可以为.dylib指定@executable_path

时间:2015-07-23 18:55:02

标签: xcode macos clang dylib

除了使用install_name_tool在链接后更改搜索路径或设置环境变量DYLD_LIBRARY_PATH之外,还有一个命令行链接器指令,它允许指定.dylib为@executable_path吗?我们希望将所有必需的.dylib文件放在应用程序包中。

当然,如果启动的可执行文件可以在启动时立即暂时设置DYLD_LIBRARY_PATH,那也可以。

这里的最终目标是允许自动化的makefile驱动的构建过程,以确保可以收集所需的动态库并将其放置在bundle中,以便可执行应用程序可以找到它们(使用@executable_path)。

注意:@rpath不是一个选项 - 我们需要的框架/ dylib不是由我们构建的。

2 个答案:

答案 0 :(得分:2)

您的选择是:

  • 链接库本身时指定-install_name <name>。 (不是在将可执行文件链接到库时)。我收集你的&#34;注意:&#34;这是不可能的。

  • 在将可执行文件链接到它们之前,使用install_name_tool -id <name>更改库的安装名称。这样,可执行文件将包含对它们的正确引用。为了完全安全,图书馆应与-headerpad_max_install_names

  • 相关联
  • 链接后,在可执行文件上使用install_name_tool -change <old> <new>,这是您正在寻找的替代方案。同样,为了安全起见,可执行文件应该与-headerpad_max_install_names链接。

不幸的是,这些是你唯一的选择。

如果您的目标是自动化构建,则可以自动更改可执行文件中库的引用。我们使用如下脚本:

#!/usr/bin/perl
use warnings;
use strict;

exit if ("$ENV{'ACTION'}" ne "build");

my $fullpath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";

open(my $otool, "otool -L '$fullpath' |") || die "otool: $fullpath: $!";

# The first line of otool output is the file name echoed.  Consume that.
my $file_echo = <$otool>;

# Process the lines listing dependent libraries
while (my $lib_line = <$otool>)
{
    if ($lib_line =~ m%[[:blank:]]+(.*/([^/]*\.dylib))[[:blank:]]+\(compatibility version%)
    {
        my $lib_orig_path = $1;
        my $lib_subpath = $2;

        my $command = "install_name_tool -change '$lib_orig_path' '\@executable_path/../Frameworks/$lib_subpath' '$fullpath'";
        print "$command\n";
        system($command) == 0 or die "system:install_name_tool:$fullpath: $!";
    }
}

open(my $timestamp_file, ">", "$ENV{'DERIVED_FILE_DIR'}/fixup_executable_lib_deps.timestamp") or die "open: $!";
print $timestamp_file time;
close($timestamp_file) or die "close: $!";

exit;

该脚本旨在用于Xcode项目的Run Script构建阶段,因此它依赖于Xcode设置的环境变量,但您可以将其更改为足以轻松使用命令行参数。

时间戳文件用作运行脚本构建阶段的输出,因此Xcode可以知道何时不需要重新运行。输入是可执行文件和此脚本文件本身。您可以将这些映射到文件目标。

答案 1 :(得分:0)

Ken Thomases的答案是详细而准确的,但是还有其他选择,而且看起来很好:

Macdylibbundler: (来自网站):“dylibbundler是一个小型命令行程序,旨在使捆绑.dylib尽可能简单。它会自动确定程序需要哪些dylib,复制这些库在应用程序包中,并修复它们和可执行文件以准备分发...所有这一切都在teminal上有一个命令!如果你的程序也使用具有依赖项的插件,它也会工作。