使用 Clang 编译的可执行文件中的 emscripten

Posted

技术标签:

【中文标题】使用 Clang 编译的可执行文件中的 emscripten【英文标题】:Use emscripten from Clang compiled executable 【发布时间】:2015-06-15 15:11:49 【问题描述】:

是否可以在 clang 编译的可执行文件上执行 emcc(来自 emscripten)?

我试过了,结果是:

ERROR root: pdfium_test: Input file has an unknown suffix, don't know what to do with it!

我尝试这样做是因为我无法找到使用 emcc 编译 PDFium 项目的解决方案,但使用 clang 一切都很好。

原因是:

Emscripten 是一个交叉编译器,因此特定于操作系统的宏 在构建 C/C++ 代码时,主机系统的所有内容都应该是未定义的。 如果您查看 tools/shared.py,Emscripten 会特别注意 -U Clang 可能会自动尝试添加的所有特定于主机的标志。

但是 PDFium 中有很多特定于平台的代码,所以我得到:

#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro.

如果定义了__linux__宏(例如),就定义了这个宏,这里是代码sn-p:

#ifndef _FX_OS_
#if defined(__android__)
#define _FX_OS_ _FX_ANDROID_
#define _FXM_PLATFORM_ _FXM_PLATFORM_ANDROID_
#elif defined(_WIN32)
#define _FX_OS_ _FX_WIN32_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_
#elif defined(_WIN64)
#define _FX_OS_ _FX_WIN64_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_WINDOWS_
#elif defined(__linux__)
#define _FX_OS_ _FX_LINUX_DESKTOP_
#define _FXM_PLATFORM_ _FXM_PLATFORM_LINUX_
#elif defined(__APPLE__)
#define _FX_OS_ _FX_MACOSX_
#define _FXM_PLATFORM_ _FXM_PLATFORM_APPLE_
#endif
#endif  // _FX_OS_ 

#if !defined(_FX_OS_) || _FX_OS_ == 0
#error Sorry, can not figure out target OS. Please specify _FX_OS_ macro.
#endif

所以,我尝试手动定义 __linux__ 宏:

emmake make -j5 BUILDTYPE=Release __linux__=1

...但同样的错误。也许这不是好方法?

提前谢谢你。

编辑: JF Bastien 的回答对我帮助很大。但现在我有这个构建错误,我不知道该怎么做。如果有人有想法...

clang-3.7: warning: argument unused during compilation: '-msse2'
clang-3.7: warning: argument unused during compilation: '-mmmx'
error: unknown FP unit 'sse'

编辑 2: 解决上述问题:从 v8/build/toolchain.gypi 中删除“-msse2、-mmmx 和 -mfpmath”标志

【问题讨论】:

【参考方案1】:

移植到 Emscripten 与移植到任何其他平台相同:您必须使用该平台自己的平台特定标头。有些会有很好的等价物,有些则没有。

在大多数情况下,您需要找到这些特定于平台的#if defined(...) 链并添加#elif defined(__EMSCRIPTEN__),然后在那里做正确的事情。这比听起来更复杂:你不能进行内联汇编,你不能依赖(大多数)特定于平台的标头,......但在某些情况下很容易。

Emscripten 拥有examples which do this,并拥有porting guide。

特别是对于 PDFium,您必须避免所有特定于平台的字体渲染、任何与线程相关的事情以及沙盒(安全性不应该是一个大问题,因为 javascript 本身就是一个沙盒)。您还必须弄清楚如何进行文件 I/O,并且可能想要禁用所有网络代码。

或者你可以使用other ports of PDFium to Emscripten。

【讨论】:

非常感谢您的回答。我会在我的原始帖子中添加和编辑。如果您知道我的问题是什么,那就太好了。

以上是关于使用 Clang 编译的可执行文件中的 emscripten的主要内容,如果未能解决你的问题,请参考以下文章

从多个编译单元引用模板化静态变量时,Clang 链接到不同位置

在 Android Studio 中使用 ollvm 版本的 clang 编译 so

mingw 包含哪些

在 Visual Studio 调试模式编译的可执行文件: jmp 到函数体而不是调用中的直接地址

Emscripten Clang 生成 ELF 64 位可执行文件和 wasm 二进制交叉编译器目标

Android NDK独立编译链