二进制文件不可执行 - C++ & irrklang
Binary file not executable - c++ & irrklang
我在使用 irrklang 库时遇到问题。我从 https://www.ambiera.com/irrklang/downloads.html 下载了 .zip 文件。我有一台装有 Mojave 10.14.6 的 MacBookPro。
我尝试编译了以下源代码:
#include <stdio.h>
#include <irrKlang.h>
using namespace irrklang;
#pragma comment(lib, "irrKlang.lib") // link with irrKlang.dll
int main(int argc, const char** argv){
printf("\nHello World!\n");
return 0;
}
我有一个包含
的目录
- main.cpp
- 包含 -> 头文件
- bin -> 它包含子目录
dotnet-4-64
、macosx-gcc
、linux-gcc-64
、winx64-visualStudio
- bell.wav、getout.ogg
- 生成文件
Makefile 非常简单(我从原始 .zip 文件的 examples
目录中改编了一个):
CPP = g++
OPTS = -dynamiclib -I"include" -L"bin/macosx-gcc" -lirrklang -pthread
all:
$(CPP) main.cpp -o example $(OPTS)
clean:
rm example
我添加了 -dynamiclib
选项,否则链接器会在 /usr/lib
.
中搜索库
当我 运行 Make
一切正常,没有错误,但是如果我尝试执行 ./example
我得到以下错误:
-bash: ./example: cannot execute binary file
我在网上搜索,我找到的唯一提示是检查 file ./example
与我的 OS 的兼容性:结果是
./example: Mach-O 64-bit dynamically linked shared library x86_64
正如预期的那样,二进制文件实际上在 OS 中是可执行的。我看不出问题,有人有什么建议吗?
dynamiclib 选项使 gcc 生成共享库而不是可执行文件。正如您在 file ./example
的输出中看到的,它确实是一个动态链接的共享库,而不是可执行文件。
您应该使用 -L
选项来指定库路径。尝试将绝对路径传递给 -L
选项。
除了此处的另一个答案之外,您还需要做一件事。 macOS 上的动态库包含一个 'load path',它告诉 OS 在启动关于它的可执行文件 link 时在哪里找到要加载它的库。此加载路径从 dylib 读取并在 link 时间烘焙到您的可执行文件中,这就是您在评论中报告的问题的原因。
Apple 提供了一个名为 install_name_tool
的实用程序,用于在 linking 之后修补可执行文件中的加载路径,因此从您发布的内容来看,您可能需要类似的内容:
install_name_tool -change libirrklang /bin/macosx-gcc/libirrklang example
这里有一篇很好的文章:
https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172
我在使用 irrklang 库时遇到问题。我从 https://www.ambiera.com/irrklang/downloads.html 下载了 .zip 文件。我有一台装有 Mojave 10.14.6 的 MacBookPro。
我尝试编译了以下源代码:
#include <stdio.h>
#include <irrKlang.h>
using namespace irrklang;
#pragma comment(lib, "irrKlang.lib") // link with irrKlang.dll
int main(int argc, const char** argv){
printf("\nHello World!\n");
return 0;
}
我有一个包含
的目录- main.cpp
- 包含 -> 头文件
- bin -> 它包含子目录
dotnet-4-64
、macosx-gcc
、linux-gcc-64
、winx64-visualStudio
- bell.wav、getout.ogg
- 生成文件
Makefile 非常简单(我从原始 .zip 文件的 examples
目录中改编了一个):
CPP = g++
OPTS = -dynamiclib -I"include" -L"bin/macosx-gcc" -lirrklang -pthread
all:
$(CPP) main.cpp -o example $(OPTS)
clean:
rm example
我添加了 -dynamiclib
选项,否则链接器会在 /usr/lib
.
当我 运行 Make
一切正常,没有错误,但是如果我尝试执行 ./example
我得到以下错误:
-bash: ./example: cannot execute binary file
我在网上搜索,我找到的唯一提示是检查 file ./example
与我的 OS 的兼容性:结果是
./example: Mach-O 64-bit dynamically linked shared library x86_64
正如预期的那样,二进制文件实际上在 OS 中是可执行的。我看不出问题,有人有什么建议吗?
dynamiclib 选项使 gcc 生成共享库而不是可执行文件。正如您在 file ./example
的输出中看到的,它确实是一个动态链接的共享库,而不是可执行文件。
您应该使用 -L
选项来指定库路径。尝试将绝对路径传递给 -L
选项。
除了此处的另一个答案之外,您还需要做一件事。 macOS 上的动态库包含一个 'load path',它告诉 OS 在启动关于它的可执行文件 link 时在哪里找到要加载它的库。此加载路径从 dylib 读取并在 link 时间烘焙到您的可执行文件中,这就是您在评论中报告的问题的原因。
Apple 提供了一个名为 install_name_tool
的实用程序,用于在 linking 之后修补可执行文件中的加载路径,因此从您发布的内容来看,您可能需要类似的内容:
install_name_tool -change libirrklang /bin/macosx-gcc/libirrklang example
这里有一篇很好的文章:
https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172