在Windows下搭建NaCl开发平台


:)  喜欢编程、图形、游戏、运动。


最近一直在折腾Chrome的Native Client。网上的资料并不是很多,所以像debug这种功能都要自己摸索。不过好在有了些眉目,本文将会教你在Windows下如何使用chrome + nacl sdk + eclipse + python + nacl-automake搭建NaCl开发平台(包括可视化debug:))。

准备

请安装以下程序:

  1. Chrome浏览器
  2. 下载NaCl SDK(或者从这里下载
  3. Eclipse CDT或者Eclipse Classic(需要装CDT插件)
  4. Python 2.7.3(其他版本未尝试,主要是用于nacl-automake)
  5. nacl-automake(此module简化了NaCl项目Makefile的创建)

需要设置两个系统变量:

  1. CHROME_PATH   表示Chrome的安装路径(例如:C:\Users\Alex\AppData\Local\Google\Chrome\Application)
  2. NACL_SDK_ROOT  表示NaCl SDK的pepper版本目录(例如:D:\google\nacl_sdk\pepper_23)

开始搭建平台

运行eclipse:

step01step02

创建一个C++项目,名字叫做nacldebug:

step03step04step05

注意由于我们使用的是nacl自己的编译工具,所以该项目的类型是Makefile project并且编译工具是– Other Toolchain –。

按照下图创建项目目录和所需文件:

step06

build目录下都是一些和编译相关的文件,主要是一些批处理。

code是你的源码目录,所有的.h和.cc文件都放在这里。

out目录是最终编译输出文件,会包含最终编译好的.nexe、.a、.so、以及与html相关的文件。

接下来对项目进行配置:

step07

在C/C++Build项下设置我们的编译命令,请使用build\makefile下的make-debug.bat来编译项目。注意需要将编译目录也设置一下。
step08
将nacl的头文件目录放入我们的配置中。在C/C++ General -> Paths and Symbols -> Includes -> GNU C++中添加:
${NACL_SDK_ROOT}\include
${NACL_SDK_ROOT}\toolchain\win_x86_newlib\x86_64-nacl\include
${NACL_SDK_ROOT}\toolchain\win_x86_newlib\x86_64-nacl\include\c++\4.4.3\x86_64-nacl\bits

编辑文件

批处理相关:

build\makefile\naclmake.bat

%NACL_SDK_ROOT%\tools\make.exe %*

build\makefile\make-debug.bat

@echo off
echo ========== build nacldebug ==========
cd .\nacldebug
call automake
call make-debug %*
cd ..

build\makefile\make-deploy.bat

@echo off
echo ========== build nacldebug ==========
cd .\nacldebug
call make-deploy %*
cd ..

build\makefile\make-profile.bat

@echo off
echo ========== build nacldebug ==========
cd .\nacldebug
call make-profile %*
cd ..

build\makefile\nacldebug\make-debug.bat

@echo off
call ../naclmake -f makefile_debug %*

build\makefile\nacldebug\make-deploy.bat

@echo off
call ../naclmake -f makefile_deploy %*

build\makefile\nacldebug\make-profile.bat

@echo off
call ../naclmake -f makefile_profile %*

build\makefile\nacldebug\automake.bat

python automake.py

makefile相关:

build\makefile\nacldebug\automake.py

import naclautomake

mf = naclautomake.create('nacldebug', '/../../..', 'newlib', 'debug')

mf.includeFromSelf('code/nacldebug/inc')
mf.fileO('nacldebug', 'code/nacldebug/src')
mf.fileNEXE('nacldebug')

mf.setMakeType('debug')
mf.write('makefile_debug')
mf.setMakeType('profile')
mf.write('makefile_profile')
mf.setMakeType('deploy')
mf.write('makefile_deploy')

C/C++代码:

code\nacldebug\inc\nacldebug.h

#pragma once

#include <ppapi/cpp/module.h>
#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/var.h>

namespace nacl{

class CInstance
 : public pp::Instance
 {
 public:
 explicit CInstance(PP_Instance instance);
 virtual ~CInstance();

public:
 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
 virtual void DidChangeView(const pp::View& view);
 virtual bool HandleInputEvent(const pp::InputEvent& event);
 virtual void HandleMessage(const pp::Var& var_message);
 };

class CModule
 : public pp::Module
 {
 public:
 CModule();
 virtual ~CModule();

public:
 virtual bool Init();
 virtual pp::Instance* CreateInstance(PP_Instance instance);
 };

}

code\nacldebug\inc\nacldebug.cc

#include "nacldebug.h"

namespace nacl{

CInstance::CInstance(PP_Instance instance)
 : pp::Instance(instance)
 {
 //
 }

CInstance::~CInstance()
 {
 }

bool CInstance::Init(uint32_t argc, const char* argn[], const char* argv[])
 {
 return true;
 }

void CInstance::DidChangeView(const pp::View& view)
 {
 }

bool CInstance::HandleInputEvent(const pp::InputEvent& event)
 {
 return true;
 }

void CInstance::HandleMessage(const pp::Var& var_message)
 {
 PostMessage(var_message);
 }

CModule::CModule()
 : pp::Module()
 {
 //
 }

CModule::~CModule()
 {
 }

bool CModule::Init()
 {
 return true;
 }

pp::Instance* CModule::CreateInstance(PP_Instance instance)
 {
 return new CInstance(instance);
 }

}

namespace pp{

Module* CreateModule()
 {
 return new nacl::CModule;
 }

}

运行相关:

out\nacldebug\chrome-debug.bat

%CHROME_PATH%\chrome.exe --enable-nacl --enable-nacl-debug --no-sandbox --disable-hang-monitor localhost:5103/index_debug.html

out\nacldebug\debug.gdbinit

这里要注意路径

nacl-manifest E:/workspace/eclipse-nacl/nacldebug/out/nacldebug/newlib/debug/nacldebug.nmf
nacl-irt C:/Users/Alex/AppData/Local/Google/Chrome/Application/24.0.1312.52/nacl_irt_x86_64.nexe

out\nacldebug\http-server.bat

python -m SimpleHTTPServer 5103

网页相关:

out\nacldebug\index_debug.html

<!doctype html>

nacldebug</pre>
<div>
<h1>nacldebug</h1>
</div>
<div>
			<b>Status:</b><span id="status">waiting</span></div>
<div id="listener"><object id="nacl_module" width="100" height="100" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="newlib/debug/nacldebug.nmf" /><embed id="nacl_module" width="100" height="100" type="application/x-shockwave-flash" src="newlib/debug/nacldebug.nmf" /></object>
<script type="text/javascript" src="index_debug.js"></script></div>
<div><b>Output:</b><span id="output"></span></div>
<pre>

out\nacldebug\index_debug.js

var listener = document.getElementById('listener');
listener.addEventListener('load', moduleDidLoad, true);
listener.addEventListener('message', handleMessage, true);

function updateStatus(msg)
{
	var status = document.getElementById('status');
	status.innerHTML = msg;
}

function updateOutput(msg)
{
	var status = document.getElementById('output');
	status.innerHTML = msg;
}

function moduleDidLoad()
{
	module = document.getElementById('nacl_module');
	if (module == null)
	{
		updateStatus('module loaded failed');
		return;
	}
	updateStatus('module loaded success');

	// Send a message to the NaCl module.
	module.postMessage('hello');
}

function handleMessage(msg)
{
	updateOutput(msg.data);
}

编译代码

生成makefile:

运行build\makefile\nacldebug\automake.bat

在build\makefile\nacldebug目录中会自动生成三个makefile分别用于debug、profile和deploy。

编译代码

在项目上右键菜单中选择Build Project或者运行build\makefile\make-debug.bat编译出debug版本。在out\nacldebug目录中将会产生编译结果(我们这里使用的是newlib)。

step10step11

运行NaCl应用

启动HTTP服务器:

运行out\nacldebug\http-server.bat,将会在out\nacldebug目录下建立一个http服务器,端口为5103。

启动Chrome查看运行结果:

在Chrome中打开http://localhost:5103/index_debug.html。将会看到如下图:

step23

进行调试

配置调试:

step12step13

在C/C++ Remote Application中新建一个debug配置。

step14step15

注意我们需要手动配置GDB远程调试。

step16step17

设置GDB debugger为D:\google\nacl_sdk\pepper_23\toolchain\win_x86_newlib\bin\x86_64-nacl-gdb.exe(注意路径)。

设置GDB command file为E:\workspace\eclipse-nacl\nacldebug\out\nacldebug\debug.gdbinit(还是注意路径)。

将Connect的Port number设置4014(本人还不知道如何配置这个端口,请知者赐教)。

在.cc代码中设置断点,比如nacldebug.cc的第60行(在Chrome启动NaCl应用时会首先调用CreateModule,来创建一个module)。

启动NaCl应用:

关闭已经打开的Chrome,运行out\nacldebug\chrome-debug.bat。你将会启动一个没有沙盒的Chrome。并且启动后等待远程调试的访问。

启动调试:

在Eclipse中我们运行先前创建的nacldebug配置,等待几秒后Eclipse会切换到debug界面,光标停留在断点处。

step19step21step22

结束语

本文是提供了一个Native Client开发环境配置方案,感觉足够我们这些开发者动手做一些NaCl应用了。缺点在于配置过程比较长,有空学学Eclipse插件开发,看看能不能搞个方便的插件出来。

在使用过程中请注意各个路径,以确保路径的可用性。

如果你有什么好的建议或者问题,欢迎提出。

项目的下载地址:http://alexchi.me/files/nacl/nacldebug.zip

Fork me on GitHub
关于

喜欢编程、图形、游戏、运动。

文章分类 Chrome, HTML5, JavaScript, NaCl, 编程, 网页 标签: , , , , , , , , , , , , , ,
  • houwenbin

    脚本mf = naclautomake.create(‘nacldebug’, ‘/../../..’, ‘newlib’, ‘debug’)找不到create方法,何解?

    • http://alexchi.me/ Alex Chi

      抱歉,由于nacl的编译方式有了比较大的改变,本人时间有限,该项目暂停开发。

Info

Ohloh profile for Alex Chi