Renaming atom.exe breaks native modules #713

Closed
natevw opened this Issue Oct 16, 2014 · 20 comments

Projects

None yet

5 participants

@natevw
natevw commented Oct 16, 2014

After renaming "atom.exe" in my Windows app bundle, I get the following message as I try to load a native module:

$ build/myutility/renamed.exe
Renderer process started
"Uncaught Error: The specified module could not be found.
C:\Users\natevw\Development\project\build\myutility\resources\app\node_modules\node-hid\build\Release\HID.node", source: c:\Users\natevw\Development\project\build\myutility\resources\atom\common\lib\asar.js (422)

Changing "renamed.exe" back to "atom.exe" makes the error go away. So contrary to #291 this does not seem to be totally okay. (Renaming the OS X Atom.app is fine though with same module.)

@paulcbetts
Contributor

Native node modules link to a node.lib which hard-codes the name atom.exe into the import table for the node module:

I'm digging into atom/node to see what I can do about this, but I feel as if I'll be forking a whole lot of projects (atom/node, atom/atom-shell, atom/apm, atom/grunt-atom-shell-downloader, etc etc). Any ideas on how this could be done in a more sane way? /cc @zcbenz who might have a clue

@zcbenz
Contributor
zcbenz commented Oct 31, 2014

The node.lib is generated by the generate_node_lib target in atom.gyp, it may not have much connections with atom/node.

To test the node.lib I usually do following steps:

1. Generate node.lib

$ cd .../atom-shell/
$ ./script/build.py -c Release -t generate_node_lib

2. Overwrite node.lib downloaded by apm

$ cd .../atom-shell/
$ cp out/Release/node.lib $USERPROFILE/.atom/.node-gyp/.node-gyp/0.18.0/

3. Rebuild the module

$ cd ../node-nslog
$ node-gyp rebuild

4. Open the module in atom-shell

$ cd .../atom-shell/
$ env ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 ./out/Release/atom.exe
> require('../node-nslog');

Or just

$ env ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 ./out/Release/atom.exe -e "require('../node-nslog');"
@paulcbetts
Contributor

@zcbenz This is good info, lemme see what I can dig out of that today.

@paulcbetts
Contributor

Ok, so here's what I've got so far, I'm a bit stuck:

  1. Creating your own node.lib that links to an arbitrary EXE name is pretty easy (especially with #763).
  2. So once we've got that, we need to make sure that this node.lib is actually used. To do that, we need to set ATOM_HOME to something that isn't .atom.
  3. In grunt-download-atom-shell, we automatically download the latest Atom Shell then immediately call apm rebuild - we need to hook this somehow to copy in our node.lib. So, I tried to separate out the rebuild from the download and create a separate explicit rebuild-native-modules.coffee - check it out here.

Unfortunately, this is where we get stuck. We can see that apm rebuild eventually calls node-gyp --install with the --dist-url of https://gh-contractor-zcbenz.s3.amazonaws.com/atom-shell/dist. We don't have a chance to copy in our lib file before node-gyp rebuilds the modules, so we end up with a bunch of modules that target atom.exe

@kevinsawicki, any thoughts? What's the least Crazytown way to work around this?

@zcbenz
Contributor
zcbenz commented Nov 3, 2014

After apm rebuild has done, you can override the node.lib and call node-gyp rebuild for the module:

$ python ./script/build
...
$ cp ~/github/atom-shell/out/Release/node.lib $USERPROFILE/.atom/.node-gyp/.node-gyp/0.18.0/
$ cd node_modules/node-nslog
$ node-gyp rebuild

it should be able to rebuild the module with new node.lib.

@kevinsawicki
Contributor

@kevinsawicki, any thoughts? What's the least Crazytown way to work around this?

I would think we could just add a setting to apm rebuild that would be like --node-lib and would be a path to the node.lib file, it would copy it to the right place after it installs the other files but before it builds the modules.

How does that sound?

@paulcbetts
Contributor

@kevinsawicki That would work great for us, yeah

@kevinsawicki
Contributor

@paulcbetts Just to confirm, you are doing a fork/custom build of Atom Shell to get this working right?

Just thinking we should probably put a doc together for this case if you are so other people have a smoother time.

@natevw
natevw commented Nov 12, 2014

@kevinsawicki @paulcbetts I for one would greatly appreciate a guide. I hope to be shipping a "rebranded" app built atop atom-shell in the next few weeks, and any additional tips for renaming the executable (and replacing icons, etc.) on the Windows side would be helpful. (On OS X there is a relevant discussion #249 which I'm not sure how up-to-date it is.)

@paulcbetts
Contributor

@kevinsawicki So, we currently need to check out Atom Shell and run the generate-node-lib build task to generate node.lib linked against the correct name - however, we can use the binary release of Atom Shell and just rename it. I haven't actually implemented this, but that's The Plan™

@kevinsawicki
Contributor

@paulcbetts you are distributing that custom built node.lib with your app right?

@paulcbetts
Contributor

@kevinsawicki Yeah, so .lib files are like .a files on Linux, they're going to be glommed onto all of the native node modules that get built

@zcbenz
Contributor
zcbenz commented Nov 13, 2014

however, we can use the binary release of Atom Shell and just rename it. I haven't actually implemented this, but that's The Plan™

This sounds great!

@natevw
natevw commented Nov 21, 2014

To be clear, is there any way I can rename atom.exe — version 0.17.2 specifically, had compiling trouble again past that — and have native modules still work? Or are you discussing future (or at least since that version) build process changes you intend to make in support of this?

@paulcbetts
Contributor

@natevw You can successfully do this today, if you do what I describe - but since it's not built into anything, you'll have to do this by-hand. I'll probably be tackling this task soonish (next week?) and I'll definitely post a guide back here once I do

@bwin
Contributor
bwin commented Nov 25, 2014

@natevw if the exe filename you want is 4(-5) chars then here's a cheap trick (works regardless of atom-shell version):
Open the compiled modules .libnode-files (for example node_sqlite3.libnode) in a hex editor and replace "atom.exe" with "abcd.exe". (In the case of sqlite3 there are 2 null chars after that, so I can even use "abcde.exe".) If you need a longer name, you have to recompile.

Offtopic here, but what compiling problems prevent you from upgrading beyond 017.2? (I also had this problem. Couldn't upgrade because of mapbox/node-sqlite3.)

edit: corrected

@paulcbetts
Contributor

I've started work on this, once I've got the package rebuilding done, I'm going to put this into a grunt-build-atom-shell package: https://gist.github.com/paulcbetts/7047866b60a523cb7938. It should be a drop-in replacement for grunt-download-atom-shell modulo some config changes

@bwin
Contributor
bwin commented Dec 6, 2014
@paulcbetts
Contributor

I put my solution to this problem into a Grunt task, check out https://github.com/paulcbetts/grunt-build-atom-shell. This task handles rebuilding native modules as well, so we should be able to close this out. Note that on OS X, this task depends on #898 which will hopefully get merged soon.

@zcbenz
Contributor
zcbenz commented Dec 8, 2014

I think we can close this now since we have a working solution.

@zcbenz zcbenz closed this Dec 8, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment