在 mac 上的 gnu/clang 编译器中定义相对于可执行文件的框架路径
Defining Framework path relative to executable in gnu/clang compiler on mac
我正在尝试在 mac 10.9.5 和 clang++ 5.1 上使用 SDL2 Framework 编译一个简单的 c++ 测试程序。
我正在尝试了解如何在 gnu/clang 中手动使用框架进行编译,因此请避免回答需要 Xcode.
的问题
项目布局
Project/
|
|-- Output/
| |-- <Unix Executable File>
| |-- SDL2.framework
|
|-- Source/
| |-- main.cpp
|
|-- Frameworks/
| |-- SDL2.framework
其中 main.cpp 仅包含:
#include <iostream>
#include <SDL2/SDL.h>
int main(int, char**) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
std::cout << "SDL LOADED CORRECTLY!" << std::endl;
SDL_Quit();
return 0;
}
而SDL2.framework来自2.0.3 Mac Development Library。
正在编译
我可以通过 clang 成功编译和 link:
clang++ -framework SDL2 -FFrameworks Source/main.cpp -o Output/main_test
使用 -F
预处理器标志手动将 Frameworks
目录添加到框架包含文件的搜索路径。
运行
如果 SDL2.framework
存在于全局框架目录中,则生成的可执行文件 运行 正确,/Library/Frameworks/
:
$ sudo cp -R Frameworks/SDL2.framework/ /Library/Frameworks/SDL2.framework/
$ ./Output/main_test
SDL LOADED CORRECTLY!
但是,如果可执行文件使用输出目录中的 SDL2.framework
而不是全局框架目录中的
,我会更喜欢它。
但是没有全局框架,可执行文件不再 运行s:
$ sudo rm -rf /Library/Frameworks/SDL2.framework/
$ sudo cp -R Frameworks/SDL2.framework/ Output/SDL2.framework/
$ ./Output/main_test
dyld: Library not loaded: @rpath/SDL2.framework/Versions/A/SDL2
Referenced from: /Users/Jo/Desktop/Temp_Project/./Output/main_test
Reason: image not found
Trace/BPT trap: 5
问题
@rpath
是可执行文件 运行 的路径吗?在这种情况下,为什么找不到它?据我所知,所需的文件位于正确的位置:
$ ls -l Output/
total 32
drwxr-xr-x@ 6 Jo staff 204 Mar 15 2014 SDL2.framework
-rwxr-xr-x 1 Jo staff 15252 Jun 24 17:35 main_test
$ ls -l Output/SDL2.framework/Versions/A/
total 3448
drwxr-xr-x@ 56 Jo staff 1904 Mar 15 2014 Headers
drwxr-xr-x@ 3 Jo staff 102 Mar 15 2014 Resources
-rwxr-xr-x@ 1 Jo staff 1762208 Mar 15 2014 SDL2
drwxr-xr-x@ 3 Jo staff 102 Mar 15 2014 _CodeSignature
具有以下 otool
库输出:
otool -L Output/main_test
Output/main_test:
@rpath/SDL2.framework/Versions/A/SDL2 (compatibility version 1.0.0, current version 3.1.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
TL;DR
我在编译时是否遗漏了一个步骤,使可执行文件能够在相对于它的位置而不是绝对全局位置用于框架?
似乎 this Question 可能相关,但截至目前 post 尚未得到答复。
我花了一段时间,但我现在终于明白如何使用 @rpath
。
@rpath on a library/framework 意味着可执行文件可以提供一个路径,我们可以使用 -rpath
设置,我们可以根据 @executable_path
.[= 设置它18=]
在这种情况下,在编译我的 main_test
可执行文件时,我需要执行以下操作:
clang++ -framework SDL2 -F ./Frameworks Source/main.cpp -o ./Output/main_test -rpath @executable_path/
那么当 运行 main_test
时,因为 @rpath
将成为可执行文件 (@executable_path
) 的路径,库将从其相对位置正确加载.
我正在尝试在 mac 10.9.5 和 clang++ 5.1 上使用 SDL2 Framework 编译一个简单的 c++ 测试程序。
我正在尝试了解如何在 gnu/clang 中手动使用框架进行编译,因此请避免回答需要 Xcode.
的问题项目布局
Project/
|
|-- Output/
| |-- <Unix Executable File>
| |-- SDL2.framework
|
|-- Source/
| |-- main.cpp
|
|-- Frameworks/
| |-- SDL2.framework
其中 main.cpp 仅包含:
#include <iostream>
#include <SDL2/SDL.h>
int main(int, char**) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
std::cout << "SDL LOADED CORRECTLY!" << std::endl;
SDL_Quit();
return 0;
}
而SDL2.framework来自2.0.3 Mac Development Library。
正在编译
我可以通过 clang 成功编译和 link:
clang++ -framework SDL2 -FFrameworks Source/main.cpp -o Output/main_test
使用 -F
预处理器标志手动将 Frameworks
目录添加到框架包含文件的搜索路径。
运行
如果 SDL2.framework
存在于全局框架目录中,则生成的可执行文件 运行 正确,/Library/Frameworks/
:
$ sudo cp -R Frameworks/SDL2.framework/ /Library/Frameworks/SDL2.framework/
$ ./Output/main_test
SDL LOADED CORRECTLY!
但是,如果可执行文件使用输出目录中的 SDL2.framework
而不是全局框架目录中的
但是没有全局框架,可执行文件不再 运行s:
$ sudo rm -rf /Library/Frameworks/SDL2.framework/
$ sudo cp -R Frameworks/SDL2.framework/ Output/SDL2.framework/
$ ./Output/main_test
dyld: Library not loaded: @rpath/SDL2.framework/Versions/A/SDL2
Referenced from: /Users/Jo/Desktop/Temp_Project/./Output/main_test
Reason: image not found
Trace/BPT trap: 5
问题
@rpath
是可执行文件 运行 的路径吗?在这种情况下,为什么找不到它?据我所知,所需的文件位于正确的位置:
$ ls -l Output/
total 32
drwxr-xr-x@ 6 Jo staff 204 Mar 15 2014 SDL2.framework
-rwxr-xr-x 1 Jo staff 15252 Jun 24 17:35 main_test
$ ls -l Output/SDL2.framework/Versions/A/
total 3448
drwxr-xr-x@ 56 Jo staff 1904 Mar 15 2014 Headers
drwxr-xr-x@ 3 Jo staff 102 Mar 15 2014 Resources
-rwxr-xr-x@ 1 Jo staff 1762208 Mar 15 2014 SDL2
drwxr-xr-x@ 3 Jo staff 102 Mar 15 2014 _CodeSignature
具有以下 otool
库输出:
otool -L Output/main_test
Output/main_test:
@rpath/SDL2.framework/Versions/A/SDL2 (compatibility version 1.0.0, current version 3.1.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
TL;DR
我在编译时是否遗漏了一个步骤,使可执行文件能够在相对于它的位置而不是绝对全局位置用于框架?
似乎 this Question 可能相关,但截至目前 post 尚未得到答复。
我花了一段时间,但我现在终于明白如何使用 @rpath
。
@rpath on a library/framework 意味着可执行文件可以提供一个路径,我们可以使用 -rpath
设置,我们可以根据 @executable_path
.[= 设置它18=]
在这种情况下,在编译我的 main_test
可执行文件时,我需要执行以下操作:
clang++ -framework SDL2 -F ./Frameworks Source/main.cpp -o ./Output/main_test -rpath @executable_path/
那么当 运行 main_test
时,因为 @rpath
将成为可执行文件 (@executable_path
) 的路径,库将从其相对位置正确加载.