New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: add initial support for single executable applications #45038
base: main
Are you sure you want to change the base?
src: add initial support for single executable applications #45038
Conversation
|
Review requested: |
Refs: nodejs/node#45038 Signed-off-by: Darshan Sen <raisinten@gmail.com>
|
@RaisinTen Don't forget to list this PR in https://github.com/nodejs/single-executable's README, for the record :) |
|
Question: does the executable require node to be installed? |
|
Adding |
|
Please make it print the experimental warning if that isn’t happening already. |
Fixes the following error I came across while integrating Postject in
Node.js:
```console
../deps/postject/src/dist/postject-api.h:30:13: error: unused function 'postject_options_init' [-Werror,-Wunused-function]
static void postject_options_init(struct postject_options* options) {
^
1 error generated.
```
Refs: nodejs/node#45038
Signed-off-by: Darshan Sen <raisinten@gmail.com>
|
Is it just me or the |
|
Off-topic: Having the source of |
This change has been extracted from the single executable application PR - nodejs#45038. I'm doing this in a separate PR because as James said in nodejs#45038 (comment), it is a rather sizeable addition on its own, so it should be easier to review and address related changes in this PR. This dependency takes care of the resource injection part of the single executable application work. Refs: https://github.com/nodejs/single-executable/blob/34b6765a871222e142f9dbac2bcde5b4e79ebfb2/blog/2022-08-05-an-overview-of-the-current-state.md#resource-injection Signed-off-by: Darshan Sen <raisinten@gmail.com>
@kapv89 no it does not. That's one of the main use cases for the single executables applications - so that it is possible to distribute a Node.js application to a user who does not already have Node.js installed on their system. |
This change has been extracted from the single executable application PR - nodejs#45038. I'm doing this in a separate PR because as James said in nodejs#45038 (comment), it is a rather sizeable addition on its own, so it should be easier to review and address related changes in this PR. This dependency takes care of the resource injection part of the single executable application work. Refs: https://github.com/nodejs/single-executable/blob/34b6765a871222e142f9dbac2bcde5b4e79ebfb2/blog/2022-08-05-an-overview-of-the-current-state.md#resource-injection Signed-off-by: Darshan Sen <raisinten@gmail.com>
@ovflowd it is the compiled version :) |
Do we need the compiled version? As |
|
@ovflowd as mentioned in #45066 (comment), that is the webassembly code which is precompiled in postject. It's built using the emsdk, not node-gyp. |
* fix: make sure that postject-api.h compiles without warnings
Fixes the following error I came across while integrating Postject in
Node.js:
```console
../deps/postject/src/dist/postject-api.h:30:13: error: unused function 'postject_options_init' [-Werror,-Wunused-function]
static void postject_options_init(struct postject_options* options) {
^
1 error generated.
```
Refs: nodejs/node#45038
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: resolve another compiler warning
```console
In file included from /root/project/test/test.c:4:
/root/project/test/../dist/postject-api.h: In function 'postject_find_resource':
/root/project/test/../dist/postject-api.h:96:9: error: unused variable 'ptr' [-Werror=unused-variable]
96 | void* ptr = NULL;
| ^~~
cc1: all warnings being treated as errors
```
Refs: https://app.circleci.com/pipelines/github/postmanlabs/postject/180/workflows/d0eb47c0-5482-4c85-9c63-aa854ddb0221/jobs/1398?invite=true#step-110-678
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: use -Wall -WX on Windows
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* chore: use -W4 instead of -Wall
-Wall produces too many warnings.
Refs: https://app.circleci.com/pipelines/github/postmanlabs/postject/185/workflows/48b0f126-8000-41d9-b39e-cb8b9e4bc9d6/jobs/1441?invite=true#step-107-693
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: another compilation warning on Windows
```console
C:\Users\circleci\project\test\../dist/postject-api.h(153,5): error C2220: the following warning is treated as an error [C:\Users\circleci\project\build\test\c_test.vcxproj]
C:\Users\circleci\project\test\../dist/postject-api.h(153,5): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [C:\Users\circleci\project\build\test\c_test.vcxproj]
C:\Users\circleci\project\test\test.c(13,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [C:\Users\circleci\project\build\test\c_test.vcxproj]
```
Refs: https://app.circleci.com/pipelines/github/postmanlabs/postject/186/workflows/f1389b9f-c958-4a24-9d6e-28af856ff776/jobs/1455?invite=true#step-107-694
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: compiler warning on Windows
```console
C:\Users\circleci\project\test\test.c(13,5): error C2220: the following warning is treated as an error [C:\Users\circleci\project\build\test\c_test.vcxproj]
C:\Users\circleci\project\test\test.c(13,5): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [C:\Users\circleci\project\build\test\c_test.vcxproj]
```
Refs: https://app.circleci.com/pipelines/github/postmanlabs/postject/187/workflows/8bcdcb96-646d-4008-93bf-294e92469b3d/jobs/1464?invite=true#step-107-694
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: use -EHsc for test.cpp
```console
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\ostream(743,1): error C2220: the following warning is treated as an error [C:\Users\circleci\project\build\test\cpp_test.vcxproj]
C:\Users\circleci\project\test\test.cpp(13): message : see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)' being compiled [C:\Users\circleci\project\build\test\cpp_test.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\ostream(743,1): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc [C:\Users\circleci\project\build\test\cpp_test.vcxproj]
```
Refs: https://app.circleci.com/pipelines/github/postmanlabs/postject/188/workflows/9107adc5-61a3-41ad-bd60-dd3eb0996765/jobs/1470?invite=true#step-107-696
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* fix: use / instead of - for Windows compiler options
Signed-off-by: Darshan Sen <raisinten@gmail.com>
* chore: use target_compile_options instead of set
Signed-off-by: Darshan Sen <raisinten@gmail.com>
Signed-off-by: Darshan Sen <raisinten@gmail.com>
|
@RaisinTen now that there is a separate PR to discuss how/where postject would be included, does it makes sense to remove that part from this PR so that it's easier to see just the key parts that are needed outside of postject? |
82806ed
to
00de9ff
Compare
I don't understand why it needs to be in the Node binary, to be honest (or even distributed with the main Node distribution). It seems to me only a very, very small handful of people would use it, and only when publishing applications - so why isn't it something left to userland to install, through a regular dependency (like is |
@mhdawson I have removed that part, PTAL.
@arcanis you can take a look at the second list of points I mentioned in #45066 (comment). |
00de9ff
to
520c5ab
Compare
| This feature allows the distribution of a Node.js application conveniently to a | ||
| system that does not have Node.js installed. | ||
|
|
||
| A bundled JavaScript file can be turned into a single executable application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably also add a comment that it can also be done with any other tool which can inject sections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can we use any other tools? Can you add them to the instructions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
objcopy can be used to accomplish this. I've created an issue in postject to discuss if it makes sense to use it internally: nodejs/postject#63.
However, after nodejs/postject#59 lands, it would also add another step - flipping the bits in the fuse. This can't be done purely by a section injection tool.
| @@ -475,4 +480,19 @@ void SetConstructorFunction(Local<v8::Context> context, | |||
| that->Set(context, name, tmpl->GetFunction(context).ToLocalChecked()).Check(); | |||
| } | |||
|
|
|||
| const char* FindSingleExecutableCode(size_t* size) { | |||
| if (single_executable_application_code_loaded == false) { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need the concept of a "fuse" here. Something like what I had in src/node_single_executable_application.cc on line 43, as borrowed from electron.
That ensures that if you are not using SEA, the overhead is as close to possible as 0. It does mean there is an extra step in the bundling but I don't see that as a big issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhdawson does nodejs/postject#59 look good to you?
| @@ -0,0 +1,44 @@ | |||
| # Single executable applications | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to this file I think we need something like doc/contributing/maintaining-single-executable-application-support.md in this PR which explains the strategy, layout of what's injected etc.
No need for it. Refs: nodejs/node#45038 (comment) Signed-off-by: Darshan Sen <raisinten@gmail.com>
chore: remove Postman copyright from postject-api.h No need for it. Refs: nodejs/node#45038 (comment) Signed-off-by: Darshan Sen <raisinten@gmail.com> Signed-off-by: Darshan Sen <raisinten@gmail.com>
Compile a JavaScript file into a single executable application:
```console
$ cat hello.js
console.log(`Hello, ${process.argv[2]}!`);
$ cp $(command -v node) hello
$ npx postject hello NODE_JS_CODE hello.js
$ ./hello world
Hello, world!
```
Signed-off-by: Darshan Sen <raisinten@gmail.com>
520c5ab
to
918a67b
Compare
| @@ -0,0 +1,79 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does anyone know how I can run this test on CI? I have placed it inside test/internet instead of test/parallel because it attempts to do npx postject which makes an outbound network connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking VCR_Cassettes, like in Ruby?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Node's CI runners? Or any sort of CI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During the single-executable meeting, we were discussing about including postject inside test/fixtures, just for testing. So that might solve this problem. PR to do that - #45298.
Refs: nodejs#45038 (comment) Signed-off-by: Darshan Sen <raisinten@gmail.com>
This should make it possible to test out the creation of Single Executable Applications on a PR without making outbound requests to download and run postject using npm. This is a needed for nodejs#45038. Refs: https://github.com/nodejs/single-executable/blob/1840f3d9c5f4fa0d29aabd5618c4ff9745f7be87/meetings/2022-10-31.md?plain=1#L75-L76 Signed-off-by: Darshan Sen <raisinten@gmail.com>
This should make it possible to test out the creation of Single Executable Applications on a PR without making outbound requests to download and run postject using npm. This is needed for nodejs#45038. Refs: https://github.com/nodejs/single-executable/blob/1840f3d9c5f4fa0d29aabd5618c4ff9745f7be87/meetings/2022-10-31.md?plain=1#L75-L76 Signed-off-by: Darshan Sen <raisinten@gmail.com>
This should make it possible to test out the creation of Single Executable Applications on a PR without making outbound requests to download and run postject using npm. This is needed for nodejs#45038. Refs: https://github.com/nodejs/single-executable/blob/1840f3d9c5f4fa0d29aabd5618c4ff9745f7be87/meetings/2022-10-31.md?plain=1#L75-L76 Signed-off-by: Darshan Sen <raisinten@gmail.com>
This should make it possible to test out the creation of Single Executable Applications on a PR without making outbound requests to download and run postject using npm. This is needed for nodejs#45038. Refs: https://github.com/nodejs/single-executable/blob/1840f3d9c5f4fa0d29aabd5618c4ff9745f7be87/meetings/2022-10-31.md?plain=1#L75-L76 Signed-off-by: Darshan Sen <raisinten@gmail.com>
This should make it possible to test out the creation of Single Executable Applications on a PR without making outbound requests to download and run postject using npm. This is needed for #45038. Refs: https://github.com/nodejs/single-executable/blob/1840f3d9c5f4fa0d29aabd5618c4ff9745f7be87/meetings/2022-10-31.md?plain=1#L75-L76 Signed-off-by: Darshan Sen <raisinten@gmail.com> PR-URL: #45298 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Tierney Cyren <hello@bnb.im>


Compile a JavaScript file into a single executable application:
Signed-off-by: Darshan Sen raisinten@gmail.com
It was decided in the Node.js Collaborator Summit that we want to come up with an MVP that is capable of compiling a single JavaScript file into a single executable application. More features will be added incrementally.
Meeting notes for reference: https://github.com/nodejs/single-executable/blob/c7008ecd67a395c7c902d602f2f116e2c5744bc9/meetings/2022-10-01.md
Note for reviewers: The change inside
deps/has been moved to #45066, so if you have any concerns regarding that portion of this PR, feel free to post your comments in #45066!cc @nodejs/single-executable