강좌 & 팁
글 수 2,412
2014.03.17 12:31:05 (*.134.169.166)
40821
자바 스크립트로 모든 것을 해결하면 좋겠지만
시스템에 따라서 필요한 것이 있죠...
이런거 만들때 C 나 C++ 로 만들어야 합니다.
이런것을 네이트브 애드온이라고 합니다.
네이티브 애드온은 C++ 프로그램을 공유라이브러리로 만들고
이를 자바 스크립트에서 바로 이용가능하게 만드는 겁니다.
이런 것을 만들기 위해서
우리는 nw-gyp 라는 것을 설치해야 합니다.
이것은 각 플랫폼별로 빌드를 할 수 있도록 도와 주는 툴인데
여기서는 자세한 설명을 하지 않으려 합니다.
이 강좌는 윈도우가 중심이고 관련된 강좌는 다른 곳을 참조 바랍니다.
하지만 nw-gyp 을 설치해야 하기 때문에
다음과 같이 명령창에서 실행합니다.
c:\> npm install -g nw-gyp
다음은 실행 결과 마지막 내용입니다.
C:\Users\frog\AppData\Roaming\npm\nw-gyp -> C:\Users\frog\AppData\Roaming\npm\node
_modules\nw-gyp\bin\nw-gyp.js
nw-gyp@0.10.9 C:\Users\frog\AppData\Roaming\npm\node_modules\nw-gyp
├── which@1.0.5
├── osenv@0.0.3
├── graceful-fs@2.0.1
├── rimraf@2.2.2
├── mkdirp@0.3.5
├── semver@2.1.0
├── nopt@2.1.2 (abbrev@1.0.4)
├── fstream@0.1.24 (inherits@2.0.1)
├── npmlog@0.0.6 (ansi@0.2.1)
├── glob@3.2.7 (inherits@2.0.1)
├── tar@0.1.18 (inherits@2.0.1, block-stream@0.0.7)
├── minimatch@0.2.12 (sigmund@1.0.0, lru-cache@2.3.1)
└── request@2.27.0 (json-stringify-safe@5.0.0, forever-agent@0.5.0, aws-sign@0.
3.0, qs@0.6.5, tunnel-agent@0.3.0, oauth-sign@0.3.0, cookie-jar@0.3.0, mime@1.2.11
, node-uuid@1.4.1, http-signature@0.10.0, hawk@1.0.0, form-data@0.1.2)
c:\>
자 이제 본격적인 네이티브 모듈을 한번 작성하고 사용해 봅니다.
역시나 윈도우가 되었던 뭐가 되었던 처음 짜는 프로그램 예제로는 "hello world" 죠...
이런 비스므리한 것으로 네이티브 애드온 모듈 작성법을 학습해 봅시다.
이 부분은 실행화면은 굳이 표시하지 않으려 합니다.
별로 의미가 없거든요...
메세지만 딸랑 뜰텐데 그걸 캡쳐 해서 표시하는 것이 더 나을 것 같습니다.
왜냐?
제가 귀찮거든요.. ㅜㅜ
다음과 같은 디렉토리를 일단 만듭니다.
C:\nw\addon\lib>
이곳으로 이동합니다.
다음 두 파일을 만듭니다.
binding.cc
binding.gyp
----[binding.cc]--------------------------------------------------------------
#include <node.h>
#include <v8.h>
using namespace v8;
Handle<Value> Method(const Arguments& args) {
HandleScope scope;
return scope.Close(String::New("world"));
}
void init(Handle<Object> target) {
NODE_SET_METHOD(target, "hello", Method);
}
NODE_MODULE(binding, init)
--------------------------------------------------------------------------------
----[binding.gyp]--------------------------------------------------------------
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ]
}
]
}
--------------------------------------------------------------------------------
내용은 설명하지 않겠습니다.
이 강좌는 빌드 과정에 집중합시다.
다른 강좌에서 이 부분에 대한 설명을 하나씩 할 것 이거든요...
여기서 다음과 같은 명령으로 빌드 환경을 잡습니다.
nw-gyp configure --target=<버전>
<버전>은 node-webkit 버전을 의미합니다.
버전은 어떻게 확인할까요?
처음 작성했던 hello world 예제 아시죠?
그걸 실행하면 브라우져 처럼 동작하죠?
URL 창에 다음 같이 칩니다.
nw:version
그러면 다음과 같이 브라우저에 버전 관련 정보가 뜹니다.
node-webkit v0.8.0-rc1
node.js v0.10.18
Chromium 30.0.1599.66
이 버전 중 우리가 필요한 것은 0.8.0 입니다.
일단 c:\nw\addon\lib 디렉토리를 이동합니다.
다음과 같이 수행합니다.
nw-gyp configure --target=0.8.0
다음은 수행 결과 입니다.
c:\nw\addon\lib>nw-gyp configure --target=0.8.0
gyp info it worked if it ends with ok
gyp info using nw-gyp@0.10.9
gyp info using node@0.10.22 | win32 | ia32
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw-headers-v0.8.0.tar.gz
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw-headers-v0.8.0.tar.gz
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp info spawn python
gyp info spawn args [ 'C:\\Users\\frog\\AppData\\Roaming\\npm\\node_modules\\nw-
gyp\\gyp\\gyp',
gyp info spawn args 'binding.gyp',
gyp info spawn args '-f',
gyp info spawn args 'msvs',
gyp info spawn args '-G',
gyp info spawn args 'msvs_version=auto',
gyp info spawn args '-I',
gyp info spawn args 'c:\\nw\\addon\\lib\\build\\config.gypi',
gyp info spawn args '-I',
gyp info spawn args 'C:\\Users\\frog\\AppData\\Roaming\\npm\\node_modules\\nw-
gyp\\addon.gypi',
gyp info spawn args '-I',
gyp info spawn args 'C:\\Users\\frog\\.nw-gyp\\0.8.0\\common.gypi',
gyp info spawn args '-Dlibrary=shared_library',
gyp info spawn args '-Dvisibility=default',
gyp info spawn args '-Dnode_root_dir=C:\\Users\\frog\\.nw-gyp\\0.8.0',
gyp info spawn args '-Dmodule_root_dir=c:\\nw\\addon\\lib',
gyp info spawn args '--depth=.',
gyp info spawn args '--generator-output',
gyp info spawn args 'c:\\nw\\addon\\lib\\build',
gyp info spawn args '-Goutput_dir=.' ]
gyp info ok
잘되는 군요 ^^
그리고 나서 빌드를 수행 합니다.
nw-gyp build
c:\nw\addon\lib> nw-gyp build
gyp info it worked if it ends with ok
gyp info using nw-gyp@0.10.9
gyp info using node@0.10.22 | win32 | ia32
gyp info spawn C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe
gyp info spawn args [ 'build/binding.sln',
gyp info spawn args '/clp:Verbosity=minimal',
gyp info spawn args '/nologo',
gyp info spawn args '/p:Configuration=Release;Platform=Win32' ]
Building the projects in this solution one at a time. To enable parallel build, please add the
"/m" switch.
binding.cc
c:\users\frog\.nw-gyp\0.8.0\src\node.h(124): warning C4996: 'v8::FunctionTemplate::New': was d
eclared deprecated [c:\nw\addon\lib\build\binding.vcxproj]
C:\Users\frog\.nw-gyp\0.8.0\deps\v8\include\v8.h(3338) : see declaration of 'v8::Fun
ctionTemplate::New'
..\binding.cc(12) : see reference to function template instantiation 'void node::Set
Method<v8::Handle<T>>(target_t,const char *,v8::InvocationCallback)' being compiled
with
[
T=v8::Object,
target_t=v8::Handle<v8::Object>
]
C:\Users\frog\.nw-gyp\0.8.0\deps\v8\include\v8.h(258): warning C4506: no definition for inline
function 'v8::Persistent<T> v8::Persistent<T>::New(v8::Handle<T>)' [c:\nw\addon\lib\build\bin
ding.vcxproj]
with
[
T=v8::Object
]
Creating library c:\nw\addon\lib\build\Release\binding.lib and object c:\nw\addon\lib\bui
ld\Release\binding.exp
Generating code
Finished generating code
binding.vcxproj -> c:\nw\addon\lib\build\Release\\binding.node
gyp info ok
c:\nw\addon\lib>
자 이제 어떤 결과가 되었는가를 확인해 봅시다.
c:\nw\addon\lib>tree
.
|-- binding.cc
|-- binding.gyp
|-- build
| |-- Release
| | |-- binding.exp
| | |-- binding.lib
| | |-- binding.node
| | |-- binding.pdb
| | `-- obj
| | `-- binding
| | |-- CL.read.1.tlog
| | |-- CL.write.1.tlog
| | |-- binding.lastbuildstate
| | |-- binding.obj
| | |-- binding.write.1.tlog
| | |-- cl.command.1.tlog
| | |-- link-cvtres.read.1.tlog
| | |-- link-cvtres.write.1.tlog
| | |-- link-rc.read.1.tlog
| | |-- link-rc.write.1.tlog
| | |-- link.command.1.tlog
| | |-- link.read.1.tlog
| | |-- link.write.1.tlog
| | `-- vc110.pdb
| |-- binding.sln
| |-- binding.vcxproj
| |-- binding.vcxproj.filters
| `-- config.gypi
`-- nw-gyp
4 directories, 25 files
c:\nw\addon\lib>
최종 결과 파일은
c:\nw\addon\lib\build\Release\\binding.node
이놈입니다.
자 이놈을 수행해 봅시다.
먼저 이전에 했던 것 처럼 package.json 을 다음과 같이 만듭니다 .
----[package.json]--------------------------------------------------------------
{
"name": "markdown",
"main": "index.html",
"window": {
"toolbar": false
}
}
--------------------------------------------------------------------------------
다음은 index.html 을 다음가 같이 작성합니다.
----[index.html]----------------------------------------------------------------
<html>
<head>
<meta http-equiv="content-Type" content="text/html; charset=utf-8" />
<title>네이티브 애드온 모듈 사용</title>
<script type="text/javascript" src="js/jquery-2.0.3.min.js"></script>
</head>
<body>
<h1>네이티브 애드온 모듈 사용</h1>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
--------------------------------------------------------------------------------
이제 모듈을 호출하고 실제 모듈에 포함된 함수를 호출하는 main.js 을 작성합니다.
----[main.js]-------------------------------------------------------------------
$(function(){
var gui = require('nw.gui');
var win = gui.Window.get();
win.showDevTools();
var assert = require('assert');
var binding = require('./lib/build/Release/binding');
assert.equal('world', binding.hello());
console.log('binding.hello() =', binding.hello());
});
--------------------------------------------------------------------------------
다음은 실행 결과 화면 입니다.
[그림 P001_실행.png]
강좌 잘 보고 있습니다.
감사합니다.