翻译:云荒杯倾
本文是Emscripten-WebAssembly专栏系列文章之一,更多文章请查看专栏。
也可以去作者的博客阅读文章。
欢迎加入Wasm和emscripten技术交流群,群聊号码:939206522。

下面是正文:

如果只是想要入门Emscripten的话,使用Emscripten是非常简单的。本教学将教会你从命令行编译Emscripten代码的种种步骤,以及Emscripten代码中怎样使用文件和使用主要的编译优化flag。

要事优先

首先是确保你已经下载并且安装好了Emscripten。根据你的操作系统不同,下载和安装过程稍有不同。

Emscripten主要是通过emcc(Emscripten Compiler Frontend)来工作的。这是个命令行工具,它会调用其他编译需要的工具,可以将它看成是标准编译器比如gcc或者clang的命令行版本。wimdows系统的话,命令行中使用emcc,Linux下使用./emcc。

验证Emscripten

第一次使用Emscripten,请先使用以下命令验证Emscripten是否正确安装:

emcc -v

如果有警告发生,可能是因为缺少一些工具,请去看这个链接解决
如果没有警告或报错,就往下看。

运行Emscripten

现在就可以使用Emscripten把C/C++代码编译成JavaScript了。

首先,写一个待编译为JavaScript的C文件。比如hello_world.c,像下面这样:

    #include <stdio.h>int main() {printf("hello, world!\n");return 0;}

注:这是Emscripten提供的测试集中最简单的一个C文件。

为了编译这个C文件,你只需要在test目录下打开命令行,emcc后面跟上这个文件名就行了。

emcc tests/hello_world.c

注:test目录是Emscripten测试集的目录。

这样就会在test目录下生成一个a.out.js文件,你可以使用node运行这个a.out.js。

node a.out.js

就会在node控制台打印出hello world!了。

如果编译失败,你可以在emcc tests/hello_world.c后面加个-v,也就是变成emcc tests/hello_world.c -v ,这样呢就会有一些调试信息,你可以参考他们,找出编译失败的原因。

生成HTML

Emscripten能为刚才输出的那个JavaScript生成HTML文件,你可以使用-o命令指定要输出的html文件名。

emcc tests/hello_world.c -o hello.html

在浏览器打开这个hello.html。你会看到,这个HTML页面中有一块文本区域是为了显示C代码中printf()函数打印的内容。

实际上,这块区域不仅可以显示文本。如果你C代码中调用了SDL的API,那么也可以在一块canvas中显示一个五彩斑斓的cube。比如,hello_world_cube.cpp那个测试用例就是这样。那个测试用例的代码是:

#include <stdio.h>
#include <SDL/SDL.h>#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endifextern "C" int main(int argc, char** argv) {printf("hello, world!\n");SDL_Init(SDL_INIT_VIDEO);SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE);#ifdef TEST_SDL_LOCK_OPTSEM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; SDL.defaults.opaqueFrontBuffer = false;");
#endifif (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen);for (int i = 0; i < 256; i++) {for (int j = 0; j < 256; j++) {
#ifdef TEST_SDL_LOCK_OPTS// Alpha behaves like in the browser, so write proper opaque pixels.int alpha = 255;
#else// To emulate native behavior with blitting to screen, alpha component is ignored. Test that it is so by outputting// data (and testing that it does get discarded)int alpha = (i+j) % 255;
#endif*((Uint32*)screen->pixels + i * 256 + j) = SDL_MapRGBA(screen->format, i, j, 255-i, alpha);}}if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);SDL_Flip(screen); printf("you should see a smoothly-colored square - no sharp lines but the square borders!\n");printf("and here is some text that should be HTML-friendly: amp: |&| double-quote: |\"| quote: |'| less-than, greater-than, html-like tags: |<cheez></cheez>|\nanother line.\n");SDL_Quit();return 0;
}

使用文件

C/C++中,可以用libc库的fopen,fclose等API来访问文件

js运行在浏览器的沙盒环境中,并不能直接访问本地文件系统,不过,Emscripten模拟了一个文件系统,这样你可以在你的C/C++代码中继续使用libc的API。

你想访问的文件应该通过preload或者embedded的方式打包到Emscripten虚拟的文件系统中。

测试集中,hello_world_file.cpp展示了怎么加载一个文件。测试代码和测试文件hello_world_file.txt如下面所示:

    #include <stdio.h>int main() {FILE *file = fopen("tests/hello_world_file.txt", "rb");if (!file) {printf("cannot open file\n");return 1;}while (!feof(file)) {char c = fgetc(file);if (c != EOF) {putchar(c);}}fclose (file);return 0;}
    ==This data has been read from a file.The file is readable as if it were at the same location in the filesystem, including directories, as in the local filesystem where you compiled the source.==

下面命令是在任何编译代码运行前指定一个数据文件预加载到Emscripten的虚拟文件系统。这个方法很有用,因为浏览器只能异步获取数据的,而原生代码(C/C++)很多都是使用的同步文件API,那么,用这个方法可以确保数据加载完成之前,编译代码(C/C++编译之后的js)不会从Emscripten的虚拟文件系统中去取数据,也就不会出错。下面是编译命令:

./emcc tests/hello_world_file.cpp -o hello.html --preload-file tests/hello_world_file.txt

运行生成的HTML,就能看到hello_world_file.txt文件的内容。

优化代码

默认情况下,和gcc以及clang等编译器一样,Emscripten生成的编译代码没有经过编译优化。那么,你可以在命令行参数中使用-O1,生成轻微优化的代码。

./emcc -O1 tests/hello_world.cpp

因为编译生成a.out.js的过程实际上并不真的需要优化,所以实际上你加不加-O1,从编译时间(或者说编译速度)上,你是看不出区别的。

但是真的没区别吗?

你可以看看生成的a.out.js文件,就能发现还是有区别的。-O1的优化有一些微小的优化并且清除了一些运行时断言,比如,在生成的代码中,printf函数,会被替换成put。

想编译优化,不仅可以用-O1,还可以用-O2,-O2优化的程度更厉害。你可以试一下,它的编译代码跟-O1又有很大差别。

Emscripten 测试集

Emscripten给大家提供了非常多的测试用例,几乎覆盖了Emscripten的所有功能。对于开发者来说,这是非常好的资源。

关于测试集的更多情况,可以点击了解。

小贴士和下一步

本教学告诉了你使用Emscripten的第一步,就是使用命令行编译一个c/c++代码为js或者HTML。为了了解更多Emscripten,给你几个小贴士:

  • 本站点还有很多高级一点的教程,比如,关于编译和构建一个项目,整合你的原生代码到web环境,打包你的代码等。
  • 关于怎么用Emscripten,测试集是一个很好的参考的地方。比如你想了解--pre-js选项怎么工作,你就在测试集里面搜--pre-js,通常来说你会搜到好几个例子。
  • 读一下本站的settings.js、emcc和emscripten.h的部分。
  • 读一下本站的FAQ。

Emscripten主题系列文章是emscripten中文站点的一部分内容。
第一个主题介绍代码可移植性与限制
第二个主题介绍Emscripten的运行时环境
第三个主题第一篇文章介绍连接C++和JavaScript
第三个主题第二篇文章介绍embind
第四个主题介绍文件和文件系统
第六个主题介绍Emscripten如何调试代码

Emscripten教程之入门指导相关推荐

  1. 网站制作入门指导教程

    作者:韩亚飞_yue31313_韩梦飞沙 QQ:313134555 网站制作入门指导教程 目录 前言...2 第一步:网站基础知识学习...5 第二步:最简单的网站架设与制作过程...7 第三步:HT ...

  2. vue入门到启动_一篇超完整的Vue新手入门指导教程

    前言 新建项目近些年前端开发快速发展,现在学习前端已经不像以前那样仅仅学习一个语法就可以了,它已经是一门编程技术了,它们有自己独立的类似Main函数的入口,有像MVC一样规范好的层次结构,有自己的开发 ...

  3. 新手入门指导:Vue 2.0 的建议学习顺序

    起步 1. 扎实的 JavaScript / HTML / CSS 基本功.这是前置条件. 2. 通读官方教程 (guide) 的基础篇.不要用任何构建工具,就只用最简单的 <script> ...

  4. python图纸教程_python入门教程 python入门神图一张

    初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...

  5. 新手必看:生成对抗网络的初学者入门指导

    新手必看:生成对抗网络的初学者入门指导 https://www.cnblogs.com/DicksonJYL/p/9698877.html 本文为 AI 研习社编译的技术博客,原标题 A Beginn ...

  6. 万事开头难(一)——Cocos2d-JS游戏开发入门指导

    当你信心满满,斗志昂扬地下定决心学习新技术时,你是否也有这样的感觉:技术还没学,却在配置环境上浪费了大量时间, 最重要的是,无论怎样,就是配不对,想怒砸电脑!!!你是否还有这样的感觉:一头扎进去学了好 ...

  7. solr教程从入门到精通(solr5搜索引擎)-任亮-专题视频课程

    solr教程从入门到精通(solr5搜索引擎)-8191人已学习 课程介绍         Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Sol ...

  8. python新手入门指导_python新手入门指导

    python新手入门指导 来源:天津IT培训学院时间:2020/8/21 9:34:54 首先,这篇文章是写给想入门Python但是编程基础0或者刚接触的新手同学.不管你是因为兴趣还是工作以及转行需求 ...

  9. ChatGPT 教程 - 从入门到精通-part2-完整版

    文章目录 简介: 1.引言 2.ChatGPT 简介 2.1 什么是 ChatGPT? 2.2 ChatGPT 的应用领域 2.3 ChatGPT 的优势和限制 3.准备工作 3.1 安装 ChatG ...

最新文章

  1. 观《逻辑思维,如何成为一个高手》
  2. Web服务评估工具Nikto
  3. ListView在列表中新增一行的操作(增加、取消)
  4. 笔记:深入理解JVM 第3章 垃圾回收器与内存分配策略
  5. php 遍历 目录,PHP采用自定义函数实现遍历目录下所有文件的方法
  6. 先生,要点单吗? (HTTP协议概览)
  7. vc6下usb编程_5款免费的C/C++语言编程器
  8. 喵喵的QQ小程序登录
  9. Django 现可在 Windows Azure 上使用
  10. 02年计算机学院成立,教育部关于成立2002年-2006年教育部高等学校外语专业等科类教学指导委员会的通知...
  11. 二阶高通有源滤波器设计与仿真测试
  12. Python:正则re.sub实现简易的模板引擎
  13. CRACK小试牛刀:关于GALGAME银色遥远爆破记录
  14. UE4 加载外部图片作为贴图
  15. 中国荫罩对准器市场深度研究分析报告
  16. 高考数学95分能学计算机吗,数学模考5分到高考95分?
  17. python中怎么输入正斜杠,详解Python中的正斜杠与反斜杠
  18. python下tkinter模块和mysql构建图书管理系统实验
  19. CentOS 7 安装 OTRS工单提交跟踪系统
  20. 微信好友所在城市可视化分析

热门文章

  1. boost::geometry::detail::copy_segments的用法测试程序
  2. Boost:aligned delete对齐删除的测试程序
  3. ITK:拉普拉斯递归高斯图像滤波器
  4. VTK:PolyData之ProcrustesAlignmentFilter
  5. VTK:PolyData之PointLocatorRadius
  6. VTK:图片之ImageSeparableConvolution
  7. VTK:Filtering之SurfaceFromUnorganizedPoints
  8. OpenGL地形渲染
  9. QT的QScriptContext类的使用
  10. QT的QGLFormat类的使用