Skip to content
This repository

Allow building node as a library #3499

wants to merge 1 commit into from

9 participants

Joel Brandt Ben Noordhuis Nathan Sobo Bartek Kilian Ciuffolo Nodejs Jenkins Matt Mullens Mithgol Eric Le Lay
Joel Brandt

Node currently builds great as a shared or static library (for embedding in other applications).

However, the build scripts don't make this easy.

This change adds an optional --output-type command line option to configure to allow specifying a static or shared library build. It also fixes up vcbuild to allow setting output type on Windows.

... ... @@ -141,6 +141,11 @@ parser.add_option("--no-ifaddrs",
141 141 dest="no_ifaddrs",
142 142 help="Use on deprecated SunOS systems that do not support ifaddrs.h")
143 143
  144 +parser.add_option("--output-type",
  145 + action="store",
  146 + dest="output_type",
  147 + help="Type of output binary to build. Valid values are: executable, static_library, shared_library (default: 'executable')")
Ben Noordhuis
bnoordhuis added a note

Long line, wrap at 80 characters.

Joel Brandt
joelrbrandt added a note

fixed, and also rebased to master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Ben Noordhuis

The trouble with pull requests like this one is that pulling it in means supporting it. :-) Are there people besides you that will use this?

Other committers, what do you think?

Joel Brandt

@bnoordhuis :-) I thought that was a very likely reaction.

I'm not personally aware of anyone else using it, but it seems like a really compelling use case for Node. People like to embed python/lua/ruby/etc. interpreters in apps. Node is right around the corner.

In case you're interested in my particular use case, I work on Brackets:

And, my work with Node is driven by this architectural endeavor:

Joel Brandt

@bnoordhuis any further thoughts on this? Thanks again for your consideration.

Nathan Sobo

At GitHub we're also interested in embedding Node in an application. But in our case just building it as a library isn't enough. We need to figure out how to embed it without blocking our native application's event loop.

Joel Brandt

@nathansobo Not to oversimplify things, but is there a reason you can't start Node (i.e. call node::Start) in its own thread?

I've got a simple mac test app that does this (with the dylib version of node) at

This application starts node here: (See also the NodeWrapper class).

And, it communicates with the UI thread using performSelectorOnMainThread like this:

Hope that's helpful! Happy to chat further about this, but it probably makes sense to move the discussion to a different communication medium. :-) Feel free to shoot me an email.

Ben Noordhuis

@joelrbrandt I'm going to let this stew a little more. I'm not dead set against the idea but until there's more demand, I don't want to merge it.

Joel Brandt

@bnoordhuis No problem, thanks for letting me know.

Since we're using it, I'll be keeping the source branch of this pull updated/rebased to the latest v0.8.x release. If you decide you want to merge it, I'll be happy to fix it up for master. Just let me know.

czaber commented

I would also be interested in embedding Node.js into my C application. It so much better than embedding pure V8, since there is a lot more libraries for Node.js.

@joelrbrandt are you still maintaining your fork of node.js with building as a shared library? I ask, because I missed anything like that in your repo.

Kilian Ciuffolo


Joel Brandt

@czaber @kilianc I just rebased the build-as-library branch in joelrbrandt/node to master. I also created the build-as-library-v0.8.4 branch in the same repo that builds the v0.8.4 release as a library.

To build, you need to do

./configure --output-type shared_library

Hope that helps!

czaber commented

@joelrbrandt thanks! I had to add '-fPIC' flag to CXXFLAGS/CFLAGS in tools/gyp/pylib/gyp/generator/ and deps/npm/node_modules/node-gyp/legacy/tools/gyp/pylib/gyp/generator/ in order to build library on my Linux box.

Joel Brandt

@czaber Thanks for the note -- exploring this on linux is on my backlog, but I haven't gotten to it yet.

I'm pretty surprised that gyp doesn't automatically set -fPIC for shared_library output types on linux. :-( Whenever I get around to working on linux support, I'll see if I can figure out how to set this by modifying node.gyp (or, less ideally, by modifying the configure script) rather than any of the tools files. If you figure it out, please send me a patch!

Ben Noordhuis

-fPIC is not (or not always) required on some architectures and it can have a pretty severe impact on code speed and/or size, that's why.

Joel Brandt

FYI: For anyone using this, I just rebased this source branch to (almost) master, as well as created the branch 'build-as-library-v0.8.8' which is based at the v0.8.8 tag. (All in the repo joelrbrandt/node )

Kilian Ciuffolo

I going to use it right now.

I think everyone who wants to embed node, is using it with NSTask ping/ponging and using stdin-stdout as some sort of IPC, it works but is so feeble and workaround-ish.

I think that supporting this would be a great value for the community.

Nodejs Jenkins

Can one of the admins verify this patch?

Matt Mullens
hoonto commented

In my case I also had to split out node::Start into two separate functions, I needed the V8 context to be handed back to the wrapping application before dropping into uv_run. node::Start is like a main, a monolithic non-API entry point. So adding a couple API functions that allow the functionality in node::Start to be called, one stage at a time by a wrapping application would be handy. I happened to call the split up node::Start functions node::buildContext which builds the V8 context and node::runContext which then calls uv_run. However, the way I did it was pretty ugly I think there could be a much more clean way of doing it, hence not submitting a pull request for the work - but would love input on how I could achieve this better, etc. I'd be happy to do the work on cleaning it up and submitting pull request. Oh, the branch I reference is: (v0.10.12-plnode-0.0.1) where changes are in and node.h. I posted to node.js google group but no response there, probably I was in the wrong place. Also that was on the 0.10 stable, node::Start has changed in master, so of course this plnode piece doesn't work on the latest master, but easy to update would just need the isolate stuff.


I posted to node.js google group but no response there, probably I was in the wrong place.

The correct Google Group is not “node.js” but “nodejs” (without the dot). So you was in the wrong place (unless you've visited the nodejs group but later here added the dot).

Matt Mullens
hoonto commented

@Mithgol Yes, thank you for the correction, you are right I added the dot here later - I was in nodejs

Eric Le Lay

hi everybody,

I build node.js as a shared_library and my main program compile.
However when I call node::Start I hit this exception:

        char* argv[] = {(char *) "node",  (char *) "/home/test.js" };   
    int argc = 2;
    node::Start(argc, argv);

../deps/uv/src/unix/proctitle.c:54: uv_setup_args: Assertion `process_title.len + 1 == size' failed.

argc and argv seems right, so I've no idea about this problem.

Node version is : v0.10.13 under ubuntu 12.04 LTS

Someone have succesfull with a recent node.js build as shared_library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Sep 01, 2012
Joel Brandt joelrbrandt modify the build files to allow building static and shared library ve…
…rsions of node
This page is out of date. Refresh to see the latest.

Showing 3 changed files with 14 additions and 3 deletions. Show diff stats Hide diff stats

  1. +7 0 configure
  2. +1 1  node.gyp
  3. +6 2 vcbuild.bat
7 configure
@@ -165,6 +165,12 @@ parser.add_option("--with-arm-float-abi",
165 165 help="Specifies which floating-point ABI to use. Valid values are: "
166 166 "soft, softfp, hard")
167 167
  168 +parser.add_option("--output-type",
  169 + action="store",
  170 + dest="output_type",
  171 + help="""Type of output binary to build. Valid values are:
  172 + executable, static_library, shared_library (default: 'executable')""")
  173 +
168 174 (options, args) = parser.parse_args()
169 175
170 176
@@ -317,6 +323,7 @@ def configure_node(o):
317 323 o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
318 324 o['variables']['node_install_npm'] = b(not options.without_npm)
319 325 o['default_configuration'] = 'Debug' if options.debug else 'Release'
  326 + o['variables']['output_type'] = options.output_type or 'executable'
320 327
321 328 host_arch = host_arch_win() if == 'nt' else host_arch_cc()
322 329 target_arch = options.dest_cpu or host_arch
2  node.gyp
@@ -54,7 +54,7 @@
54 54 'targets': [
55 55 {
56 56 'target_name': 'node',
57   - 'type': 'executable',
  57 + 'type': '<(output_type)',
58 58
59 59 'dependencies': [
60 60 'deps/cares/cares.gyp:cares',
8 vcbuild.bat
@@ -16,6 +16,7 @@ set config=Release
16 16 set msiplatform=x86
17 17 set target=Build
18 18 set target_arch=ia32
  19 +set output_type=executable
19 20 set debug_arg=
20 21 set nosnapshot_arg=
21 22 set noprojgen=
@@ -41,6 +42,8 @@ if /i "%1"=="clean" set target=Clean&goto arg-ok
41 42 if /i "%1"=="ia32" set target_arch=ia32&goto arg-ok
42 43 if /i "%1"=="x86" set target_arch=ia32&goto arg-ok
43 44 if /i "%1"=="x64" set target_arch=x64&goto arg-ok
  45 +if /i "%1"=="sharedlibrary" set output_type=shared_library&goto arg-ok
  46 +if /i "%1"=="staticlibrary" set output_type=static_library&goto arg-ok
44 47 if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
45 48 if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
46 49 if /i "%1"=="nosign" set nosign=1&goto arg-ok
@@ -80,7 +83,7 @@ if defined noetw set noetw_arg=--without-etw& set noetw_msi_arg=/p:NoETW=1
80 83 if defined noprojgen goto msbuild
81 84
82 85 @rem Generate the VS project.
83   -python configure %debug_arg% %nosnapshot_arg% %noetw_arg% --dest-cpu=%target_arch%
  86 +python configure %debug_arg% %nosnapshot_arg% %noetw_arg% --dest-cpu=%target_arch% --output-type=%output_type%
84 87 if errorlevel 1 goto create-msvs-files-failed
85 88 if not exist node.sln goto create-msvs-files-failed
86 89 echo Project files generated.
@@ -187,12 +190,13 @@ python tools/closure_linter/closure_linter/ --unix_mode --strict --noj
187 190 goto exit
188 191
189 192 :help
190   -echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [nobuild] [nosign] [x86/x64]
  193 +echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [nobuild] [nosign] [x86/x64] [sharedlibrary/staticlibrary]
191 194 echo Examples:
192 195 echo vcbuild.bat : builds release build
193 196 echo vcbuild.bat debug : builds debug build
194 197 echo vcbuild.bat release msi : builds release build and MSI installer package
195 198 echo vcbuild.bat test : builds debug build and runs tests
  199 +echo vcbuild.bat sharedlibrary : builds release build as a dll
196 200 goto exit
197 201
198 202 :exit

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.