Emscripten教程之emcc编译命令

绮霰
• 阅读 19376

emcc(Emscripten Compiler Frontend)介绍

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

emcc用于从命令行调用Emscripten的编译器,它实际上是标准编译器gcc或者clang的一个替换。

语法


emcc [options] file ...

这个输入文件file,既可以是clang可以编译的C/C++语言,也可以是二进制形式的llvm bitcode或者人类可读形式的llvm assembly文件。

参数

大部分clang或者gcc的选项(option)都是可以工作的,比如:

# 显示信息
emcc --help
# 显示编译器版本信息
emcc --version

如果想看当前Emscripten中clang版本支持的全部选项列表,可以直接使用命令:
clang --help.

emcc修改的或者emcc中新的选项列在下面:

首先是一些编译优化flag,它们-O0,-O1,-O2,-Os,-Oz,-O3。

-O0:
不进行编译优化(这是默认情况)。当你刚开始移植项目是推荐使用它,因为它会包含许多断言。

-O1:
简单优化。推荐你在既想缩短编译时间又想编译优化时使用。它毕竟比-O2级别的优化编译起来快多了。它会进行asm.js和llvm的-O1进行优化,它会relooping,会删除运行时断言和C++异常捕获,它也会使得-s ALIASING_FUNCTION_POINTERS=1。

想要C++异常捕获重新可用,请设置:-s DISABLE_EXCEPTION_CATCHING=0。

-O2:
和-O1类似,不过多了JavaScript级别的优化以及一些llvm -O3的优化项。当你想发布项目的时候,推荐使用本级别优化。

-O3:
和-O2类似,不过比-O2又多了一些JavaScript优化,而且编译时间明显比-O2长。这个也推荐在发布版本的时候使用。

-Os:
和-O3类似,不过增加了额外的优化以减小生成的代码体积,代价是比-O3性能差一点。-Os优化会同时影响llvm bitcode 和JavaScript文件的生成。

-Oz:
和-Os类似,不过进一步减小了代码体积。

-s OPTION=VALUE
传给编译器的所有涉及到JavaScript代码生成的选项。选项列表,请见settings.js

对于某个选项的值,不仅可以直接在emcc命令行里面设定,也可以把他们写成json文件。比如下面,就是将DEAD_FUNCTIONS选项的值放到了path/to/file文件里,emcc里面传这个文件的路径。

-s DEAD_FUNCTIONS=@/path/to/file
note:
1、文件内容可以是:["_func1","_func2"];
2、文件路径必须是绝对的,不能是相对的。

-g:
这是保留调试信息flag。

  • 如果只是编译到bitcode,那就和clang和gcc中的-g一样。
  • 如果是要编译到JavaScript,-g就等于-g3。

-g<level>
控制打印的调试信息数量,每一个level都是在前一个level的基础上编译的:

  • -g0:不保留调试信息。
  • -g1:保留空格,不压缩。
  • -g2:保留函数名。
  • -g3:保留变量名,与-g同。变量名一般不是必须编译后保留的,但是如果保留了,可以推断变量的目的,对吧。
  • -g4:保留llvm 调试信息,这是能调试的最高级别。
note:
优化级别越高,编译时间越长

--profiling:

--profiling-funcs:

--tracing:
启用Emscripten的tracing API。

--emit-symbol-map:

--js-opts<level>:
允许JavaScript优化,有两个值:
0:不允许JavaScript优化器允许;
1:使用JavaScript优化器。
通常用不到我们设置这一项, 因为设置-O后面的level的时候,这个项就能顺便取到一个合适的值。

note:
有些选项会重写这个flag的值,比如EMTERPRETIFY, DEAD_FUNCTIONS, OUTLINING_LIMIT, SAFE_HEAP 和 SPLIT_MEMORY会将js-opts=1,因为他们依赖js优化器。

--llvm-opts<level>:
启用llvm优化。它的取值有有:

  • 0:不使用llvm优化
  • 1:llvm -O1优化
  • 2:llvm -O2优化
  • 3:llvm -O3优化

和--js-opts<level>一样,通常用不到我们设置这一项, 因为设置-O后面的level的时候,这个项就能顺便取到一个合适的值。

--llvm-lto<level>:
启用llvm 连接时 优化。可以取值0,1,2,3。

--closure <on>:
运行压缩编译器(Closure Compiler),可能的取值有,0,1,2:

  • 0:是不启用压缩编译器。
  • 1:启用。
  • 2:启用。

--pre-js <file>
生成代码前,指定一个要把内容添加进来的文件。

--post-js <file>
生成代码后,指定一个要把内容添加进来的文件。

--embed-file <file>
指定一个带路径的文件嵌入到编译生成的js代码里。路径是相对于编译时的当前路径。如果传的是一个目录,则目录下所有文件的内容都会被嵌入到将来生成的js代码中。

--preload-file <name>
异步运行编译代码前,指定一个预加载的文件。路径是相对于编译时的当前路径。如果传的是一个目录,则目录下所有文件的内容都会被预加载到一个.data文件中。

--exclude-file <name>
从 –embed-file and –preload-file后面的目录中排除一些文件,支持使用通配符*。

--use-preload-plugins
告诉文件打包器当文件加载时,运行预加载插件。它用来执行诸如使用浏览器解码器解码图片和音频等。

--shell-file <path>
指定要生成HTML的模板文件。

--source-map-base <base-url>

--minify 0
等于-g1。

--js-transform <cmd>
优化之前,生成代码之后,设定这一条命令。这条命令可以让你修改JavaScript代码。之后,编译器会将修改的和未修改的一起进行编译优化。

--bind
启用bingdings编译源代码。bingings是Emscripten中连接C++和JavaScript代码的一类API。

--ignore-dynamic-linking
告诉编译器忽视动态链接,之后用户就得手动链接到共享库。

--js-library <lib>
定义除了核心库(src/library_*)以外的js库。

-v
打开详细输出。
这个设置为把-v传给clang,并且启用EMCC_DEBUG生成编译阶段的中间文件。它也会运行Emscripten关于工具链的内部的完整性检查。

tip:
emcc -v是诊断错误的有用工具,不管你是否附加其他参数。

--cache

--clear-cache

--clear-ports

--show-ports

--save-bc PATH

--memory-init-file <on>
规定是否单独生成一个内存初始化文件。取值包括0和1.

  • 0:不单独生成.mem文件。
  • 1:单独生成.mem文件。

-Wwarn-absolute-paths
启用在-I和-L命令行指令中使用绝对路径的警告。这是用来警告无意中使用了绝对路径的。在引用非可移植的本地系统头文件时,使用绝对路径有时是很危险的。

--proxy-to-worker

--emrun
使生成的代码能够感知emrun命令行工具。当运行emran生成的应用程序时,这样设置就允许stdout、stderr和exit(returncode)被捕获。

--cpuprofiler
在生成的页面上嵌入一个简单的CPU分析器。使用这个来执行粗略的交互式性能分析。

--memoryprofiler
在生成的页面上嵌入内存分配跟踪器,使用它来分析应用程序Emscripten堆的使用情况。

--threadprofiler
在生成的页面上嵌入一个线程活动分析器。当进行多线程编译时,使用它来分析多线程应用程序。
--em-config

--default-obj-ext .ext

--valid-abspath path
设置一个绝对路径的白名单,以防止关于绝对路径的警告。

-o <target>
编译输出的文件格式。target可以取值为:

  • name.js:JavaScript文件;
  • name.html:HTML+js文件。把js单独生成是为了减小页面加载时间。
  • name.bc:llvm bitcode。这是默认值。
  • name.o:和上面一样。
note:
如果你用了--memory-init-file,则还会从js文件中再单独分出一部分代码为.mem文件。

-c
生成llvm bitcode代码,而不是JavaScript。

--separate-asm
把asm.js文件单独生成到一个文件中。这样可以减少启动时的内存加载。

--output_eol windows|linux
规定生成的文本文件的行尾,如果是–output_eol windows,就是windows rn行尾,如果是–output_eol linux,则生成Linux行尾的文本文件。

--cflags

环境变量


emcc会受到几个环境变量的影响,如下:

  • EMMAKEN_JUST_CONFIGURE
  • EMMAKEN_JUST_CONFIGURE_RECURSE
  • EMCONFIGURE_JS
  • EMCONFIGURE_CC
  • EMMAKEN_CXX
  • EMMAKEN_COMPILER
  • EMMAKEN_CFLAGS
  • EMCC_DEBUG

这几个里面比较有意思的是EMCC_DEBUG。比如,如果你在编译之前设置set EMCC_DEBUG=1,那么编译的时候会把编译过程的调试信息和编译各个阶段的中间文件输出到一个临时目录,这算是给开发者提供一些编译期间的帮助或者说调试信息吧。


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

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这