在mac

时间:2015-06-25 01:11:14

标签: c++ macos clang sdl

我尝试使用clang ++ 5.1在mac 10.9.5上使用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链接:

clang++ -framework SDL2 -FFrameworks Source/main.cpp -o Output/main_test

使用-F预处理程序标志手动将Frameworks目录添加到Framework包含文件的搜索路径中。


运行

如果全局框架目录SDL2.framework中存在/Library/Frameworks/,则生成的可执行文件正确运行:

$ sudo cp -R Frameworks/SDL2.framework/ /Library/Frameworks/SDL2.framework/
$ ./Output/main_test
SDL LOADED CORRECTLY!

但是,如果可执行文件在Output目录中使用SDL2.framework而不是在Global frameworks目录中需要一个,那么我更喜欢它。

但是没有全局框架,可执行文件不再运行:

$ 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可能是相关的,但截至本文时尚未得到解答。

1 个答案:

答案 0 :(得分:1)

我花了一段时间,但现在我终于明白了如何使用@rpath

库/框架上的@rpath意味着可执行文件可以提供我们可以使用-rpath设置的路径,我们可以使用@executable_path设置它。

在这种情况下,在编译我的main_test可执行文件时,我需要执行以下操作:

clang++ -framework SDL2 -F ./Frameworks Source/main.cpp -o ./Output/main_test -rpath @executable_path/

然后在运行main_test时,由于@rpath将成为可执行文件(@executable_path)的路径,因此库将从其相对位置正确加载。