Skip to content

Latest commit

 

History

History
159 lines (95 loc) · 8.74 KB

扩展阅读.md

File metadata and controls

159 lines (95 loc) · 8.74 KB

该页面 Wiki 仍处于构建状态

如何编译AngelScript库?

编译库

在 sdk/angelscript/projects 目录中,你会发现许多流行编译器的项目文件。然而,这些项目文件并不总是与库的最新版本保持同步。如果你遇到任何编译器或链接器错误,请确保项目文件包含了 sdk/angelscript/source 目录中的所有文件,并根据本文设置项目设置。

如果你没有找到适用于你的编译器的项目文件,你可以通过添加 sdk/angelscript/source 目录中的所有文件,并适当配置项目,轻松创建你自己的项目。如果你有一个新编译器/目标,之前没有与 AngelScript 一起使用过,你可能需要编辑 as_config.h 文件,以确保库被正确编译。

另见 特定平台的考虑事项

设置编译时选项

代码尽量在尽可能少的地方包含编译器差异。为此创建了头文件 as_config.h。在那里,你会发现一些 #defines,它们允许不同的编译器工作。你大概不需要更改这个文件,但如果你使用的是一个之前未使用过的编译器,并且你遇到了编译器错误,那么查看这个文件可能是值得的。

代码中还使用了其他一些 #defines 来改变编译。在编译库时,你可能想要定义 ANGELSCRIPT_EXPORT,以便导出库函数。如果你直接在应用程序项目中包含库源代码,你就不需要定义这个标志。

如果定义了 AS_DEPRECATED,那么就会保持一些向后兼容性,这可以帮助你更平滑地升级到最新版本。然而,不能保证会保持向后兼容性,所以尽快去除对弃用函数的使用。

与库链接

有四种编译和链接 AngelScript 的方法以使用它。我建议使用静态库进行链接。注意,这四种方法之间的互换只需要在你的代码中做一些小改动,即在包含头文件之前定义一个标志,可能还需要一个手动加载 dll 的例程。你的代码的其他部分对于每种选择应该看起来完全相同。

  1. 在项目中包含库源文件 你可以直接将 AngelScript 的源文件包含在你的项目中。这样做的好处是,你可以确保对库和宿主应用程序使用了相同的编译器选项,例如多线程或单线程 CRT。缺点是你的项目将被库文件污染

需要使用库的文件应该包含 angelscript.h 头文件,无需任何特殊设置。

// 包含库接口
#include "angelscript.h"

// ...开始使用库
  1. 编译静态库并链接到项目 **最推荐的方式是编译一个静态库,你的项目将与之链接。**在编译静态库时,你必须确保使用了正确的编译器设置,以便在链接 CRT 函数时不会出现冲突。这会发生在例如你用动态链接的多线程 CRT 编译库,而你的应用程序用静态链接的单线程 CRT 时。(对于 Visual C++,你可以在 Project -> Settings -> C/C++ -> Category: Code Generation 下找到这些设置)

使用库,你只需要包含 angelscript.h 头文件。

// 包含库接口
#include "angelscript.h"

// ...开始使用库
  1. 编译一个动态加载库并带有导入库 使用 Microsoft Visual C++,可以编译一个带有导入库的动态加载库。导入库将负责加载 dll 并绑定函数所需的工作。这种方法的一个可能的缺点是,如果加载库失败,你将无法提供任何用户友好的错误消息。

要使用库,你必须在包含 angelscript.h 头文件之前定义 ANGELSCRIPT_DLL_LIBRARY_IMPORT。

// 包含库接口
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
#include "angelscript.h"

// ...开始使用库
  1. 手动加载动态加载库 如果你想使用 dll,例如在应用程序之间共享代码,我建议手动加载库,因为你可以优雅地处理任何加载或绑定函数的失败。

要使用手动加载的 dll,你应该在包含 angelscript.h 头文件之前定义 ANGELSCRIPT_DLL_MANUAL_IMPORT。这将确保头文件不会声明函数原型,因为你很可能想要使用这些名称来为函数指针。

// 包含库接口
#define ANGELSCRIPT_DLL_MANUAL_IMPORT
#include "angelscript.h"

// 声明函数指针
typedef asIScriptEngine * AS_CALL t_asCreateScriptEngine(int);
t_asCreateScriptEngine *asCreateScriptEngine = 0;

// ...声明其余的函数

// 加载 dll 并绑定函数(为了清晰起见省略了错误处理)
HMODULE dll = LoadLibrary("angelscript.dll");
asCreateScriptEngine = (t_asCreateScriptEngine*)GetProcAddress(dll, "_asCreateScriptEngine");

// ...绑定其他函数

// ...开始使用库

特定平台的考虑事项

如前所述,对于大多数平台,编译库就像包含所有源文件并编译它们一样简单。然而,在一些平台上,需要执行特定的操作才能正确编译库。

Windows 64位

MSVC 编译器不支持 x86 64位 CPU 系列的内联汇编器。为了支持这个平台,创建了一个单独的汇编器文件:as_callfunc_x64_msvc_asm.asm。

要编译这个文件,需要配置一个自定义构建命令,如下所示:

ml64.exe /c /nologo /Fo$(OutDir)\as_callfunc_x64_msvc_asm.obj /W3 /Zi /Ta $(InputDir)$(InputFileName)

Microsoft Visual C++

虽然 AngelScript 不使用 Microsoft 的语言扩展,但如果禁用了语言扩展,你仍然可能在编译库时遇到麻烦。这是因为 Microsoft 自己的 SDK 可能包含依赖于语言扩展的代码,例如在版本 6.0a 中,你可能会因为 specstrings.h 头文件中宏定义中存在 $ 而得到编译器错误。Microsoft 在他们的 SDK 版本 6.1 中修复了这个特定问题,但可能还有其他问题,所以保持语言扩展开启可能更容易。

基于 GNUC 的编译器

为了在不需要包装器的情况下与 C++ 正确集成,AngelScript 使用了大量的指针转换。不幸的是,由于这一点,不可能总是保证严格的别名,所以在基于 GNUC 的编译器上,需要禁用假设严格别名的编译器优化

使用以下编译器参数禁用此功能:

-fno-strict-aliasing

带有 ARM CPU 的 Pocket PC

MSVC 编译器不支持 ARM CPU 的内联汇编器,因此为此代码编写了一个单独的汇编器文件:as_callfunc_arm_msvc.asm。

为了正确编译这个文件,需要配置一个自定义构建命令,如下所示:

armasm -g $(InputPath)

Marmalade

Marmalade 是一个为移动设备设计的跨平台 SDK。它通过使用自己的 C 运行时库来抽象底层操作系统,尽管它使用常见的 C++ 编译器,例如 Windows 上的 MSVC,以及 Linux 和 Mac 上的 GNUC。

当使用 Marmalade 编译适用于 iOS 和 Android 的 AngelScript 时,必须使用 scons 才能正确编译原生 ARM 汇编例程。对于 Windows Phone,你应该能够正常使用 MSVC。

库的大小

库的大小取决于许多不同的因素,例如编译器品牌、编译器标志,以及包含的 AngelScript 功能。然而,为了给出库在磁盘和内存中将占用多少空间的概念,我以几种不同的方式编译了 asrun 示例,并记录了大小。

选项 磁盘上的二进制文件大小
32位 / 多线程 dll / 优化速度(不包括 AngelScript) 14KB
32位 / 多线程 dll / 优化速度(使用 AngelScript 和插件) 796KB
32位 / 多线程 dll / 优化速度(不包括编译器的 AngelScript 和插件) 453KB
32位 / 多线程静态 / 优化速度(使用 AngelScript 但不包括插件) 867KB
32位 / 多线程静态 / 优化速度(使用 AngelScript 和插件) 1015KB
64位 / 多线程静态 / 优化速度(使用 AngelScript 和插件) 1336KB
32位 / 多线程静态 / 优化大小(使用 AngelScript 和插件) 797KB
32位 / 多线程 dll / 优化大小(使用 AngelScript 和插件) 582KB

根据这些,我们可以得出结论,当优化速度时,引擎和 VM 大约占用 300KB,编译器增加另外 350KB,插件再增加 150KB。

注意 这些测试是使用 MSVC 2012 和版本 2.30.2 的库进行的。


知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。