Skip to content

Commit 2124ad1

Browse files
drywolfirbull
authored andcommitted
build-system unit-testing & other extras
- fix install.alpine.packages.sh chmod +x - refactor nodejs.py sub-commands (git-CLI style) - add j2v8-cli convenience scripts with command aliases (for win32/linux/macos) - do not run NodeJsTest when native lib was not compiled with node features included - add check in CMake node js lib scripts if all njs lib files exist, exit with error if any is missing - add node 7.9.0 patch file (works for linux, but not windows currently) - j2v8jni build-step is now called j2v8cpp - j2v8jni is a new build-step using javah to regenerate J2V8 JNI header files - j2v8jni build-step is skipped if the required V8.class file does not yet exist - implement basic unit-testing for build-system - centralize maven build-steps logic and also just run maven pre-build actions once per build-process (e.g. copy native J2V8 libs to the Java directories)
1 parent 9a5735d commit 2124ad1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1395
-243
lines changed

BUILDING.md

+22-5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ Override build-steps ? (leave empty to run pre-configured steps): j2v8
4141

4242
The J2V8 build-system performs several build steps in a fixed order to produce the final J2V8 packages for usage on the designated target platforms. What follows is a short summary for what each of the executed build-steps does and what output artifacts are produced by each step.
4343

44+
```
45+
Node.js --> CMake --> JNI --> C++ --> Optimize --> Java/Android --> JUnit
46+
```
4447
---
4548
## Node.js
4649

@@ -56,9 +59,10 @@ __Inputs:__
5659
__Artifacts:__
5760
- Node.js & V8 static link libraries
5861
- `./node/out/`
59-
- `./node/build/`
60-
- `./node/Debug/`
61-
- `./node/Release/`
62+
- *win32 specific*
63+
- `./node/build/`
64+
- `./node/Debug/`
65+
- `./node/Release/`
6266
---
6367
## CMake
6468

@@ -75,12 +79,25 @@ __Artifacts:__
7579
- CMake generated Makefiles / IDE Project-files
7680
- `./cmake.out/{platform}.{architecture}/`
7781
---
78-
## JNI
82+
## JNI Header Generation
83+
84+
Generate the JNI glue header file from the native method definitions of the Java `V8` class.
85+
86+
__Inputs__:
87+
- Java V8.class file
88+
- `./target/classes/com/eclipsesource/v8/V8.class`
89+
90+
__Artifacts:__
91+
- J2V8 C++ JNI header file
92+
- `./jni/com_eclipsesource_v8_V8Impl.h`
93+
---
94+
## C++
7995

80-
Compile and link the J2V8 C++ shared libraries (.so/.dylib/.dll), which provide the JNI bridge to interop with the C++ code of Node.js / V8.
96+
Compile and link the J2V8 native shared libraries (.so/.dylib/.dll), which contain the C++ JNI bridge code to interop with the embedded Node.js / V8 parts.
8197

8298
__Inputs__:
8399
- CMake generated Makefiles / IDE Project-files
100+
- Node.js / V8 static link libraries & C++ header files
84101
- J2V8 C++ JNI source code
85102
- `./jni/com_eclipsesource_v8_V8Impl.h`
86103
- `./jni/com_eclipsesource_v8_V8Impl.cpp`

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ set(J2V8_JDK_DIR ${Java_ROOT} CACHE STRING "Path to the Java JDK dependency")
3434
set(J2V8_NODEJS_DIR "${CMAKE_SOURCE_DIR}/node" CACHE STRING "Path to the Node.js dependency")
3535

3636
# get the required Node.js link libraries
37-
get_njs_libs(${J2V8_NODEJS_DIR} "Debug")
38-
get_njs_libs(${J2V8_NODEJS_DIR} "Release")
37+
get_njs_libs(${J2V8_NODEJS_DIR} "Debug" FALSE)
38+
get_njs_libs(${J2V8_NODEJS_DIR} "Release" TRUE)
3939

4040
# j2v8 build options
4141
set(J2V8_TARGET_ARCH "" CACHE STRING "The target architecture for the build.")

build_system/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test-reports

build_system/build_constants.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
CLIStep(c.build_node_js, " Builds the Node.js & V8 dependency artifacts that are later linked into the J2V8 native bridge code.\n" +
2020
" (only works if the Node.js source was checked out into the J2V8 ./node directory)"),
2121
CLIStep(c.build_j2v8_cmake, " Uses CMake to generate the native Makefiles / IDE project files to later build the J2V8 C++ native bridge shared libraries."),
22-
CLIStep(c.build_j2v8_jni, " Compile and link the J2V8 C++ shared libraries (.so/.dylib/.dll), which provide the JNI bridge to interop with the C++ code of Node.js / V8."),
22+
CLIStep(c.build_j2v8_jni, " Generate the J2V8 JNI C++ Header files."),
23+
CLIStep(c.build_j2v8_cpp, " Compile and link the J2V8 C++ shared libraries (.so/.dylib/.dll), which provide the JNI bridge to interop with the C++ code of Node.js / V8."),
2324
CLIStep(c.build_j2v8_optimize, " The native J2V8 libraries are optimized for performance and/or filesize by using the available tools of the target-platform / compiler-toolchain."),
2425
CLIStep(c.build_j2v8_java, " Compiles the Java source code and packages it, including the previously built native libraries, into the final package artifacts.\n" +
2526
" For the execution of this build-step Maven (Java) or Gradle (Android) are used for the respective target platforms."),

build_system/build_executor.py

+38-27
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
from shell_build import ShellBuildSystem
99
import immutable
1010

11-
# collection of all parsed build-steps that will then be passed on to the core build function
12-
# (this list must only contain atomic steps after all step evaluations are finished)
13-
parsed_steps = set()
11+
class BuildState:
12+
# collection of all parsed build-steps that will then be passed on to the core build function
13+
# (this list must only contain atomic steps after all step evaluations are finished)
14+
parsed_steps = set()
1415

15-
# a registry/dictionary of evaluation-functions that translate from their corresponding step/alias
16-
# into the list of atomic build-steps (see parsed_steps above)
17-
step_evaluators = {}
16+
# a registry/dictionary of evaluation-functions that translate from their corresponding step/alias
17+
# into the list of atomic build-steps (see parsed_steps above)
18+
step_evaluators = {}
1819

1920
#-----------------------------------------------------------------------
2021
# Advanced build-step parsing (anti-steps, multi-steps)
@@ -28,11 +29,14 @@ def atomic_step(step, alias = None):
2829
if (alias is None):
2930
alias = step
3031

32+
step_eval = BuildState.step_evaluators
33+
parsed_steps = BuildState.parsed_steps
34+
3135
# add step handler (step => step)
32-
step_evaluators[alias] = lambda: parsed_steps.add(step)
36+
step_eval[alias] = lambda: parsed_steps.add(step)
3337

3438
# add anti-step handler (step => ~step)
35-
step_evaluators["~" + alias] = lambda: parsed_steps.discard(step)
39+
step_eval["~" + alias] = lambda: parsed_steps.discard(step)
3640

3741
# register additional anti-step in CLI
3842
bc.avail_build_steps.append("~" + alias)
@@ -43,15 +47,18 @@ def multi_step(alias, include, exclude = []):
4347
the defined step alias name was detected. Also the inverted anti-steps sequence
4448
will be evaluated if the "~" prefixed alias is recognized.
4549
"""
50+
51+
step_eval = BuildState.step_evaluators
52+
4653
# add aliased step-sequence (alias => step1, step2, ... , stepN)
47-
step_evaluators[alias] = lambda: \
48-
[step_evaluators.get(s)() for s in include] + \
49-
[step_evaluators.get("~" + s)() for s in exclude]
54+
step_eval[alias] = lambda: \
55+
[step_eval.get(s)() for s in include] + \
56+
[step_eval.get("~" + s)() for s in exclude]
5057

5158
# add aliased anti-step-sequence (~alias => ~step1, ~step2, ... , ~stepN)
52-
step_evaluators["~" + alias] = lambda: \
53-
[step_evaluators.get("~" + s)() for s in include] + \
54-
[step_evaluators.get(s)() for s in exclude]
59+
step_eval["~" + alias] = lambda: \
60+
[step_eval.get("~" + s)() for s in include] + \
61+
[step_eval.get(s)() for s in exclude]
5562

5663
# register additional anti-step in CLI
5764
bc.avail_build_steps.append("~" + alias)
@@ -74,6 +81,7 @@ def init_buildsteps():
7481
c.build_node_js,
7582
c.build_j2v8_cmake,
7683
c.build_j2v8_jni,
84+
c.build_j2v8_cpp,
7785
c.build_j2v8_optimize,
7886
])
7987

@@ -83,11 +91,11 @@ def init_buildsteps():
8391

8492
def evaluate_build_step_option(step):
8593
"""Find the registered evaluator function for the given step and execute it"""
86-
step_eval_func = step_evaluators.get(step, raise_unhandled_option(step))
94+
step_eval_func = BuildState.step_evaluators.get(step, raise_unhandled_option(step))
8795
step_eval_func()
8896

8997
def raise_unhandled_option(step):
90-
return lambda: sys.exit("INTERNAL-ERROR: Tried to handle unrecognized build-step \"" + step + "\"")
98+
return lambda: utils.cli_exit("INTERNAL-ERROR: Tried to handle unrecognized build-step \"" + step + "\"")
9199

92100
# initialize the advanced parsing evaluation handlers for the build.py CLI
93101
init_buildsteps()
@@ -115,35 +123,38 @@ def execute_build(params):
115123
if (isinstance(params, dict)):
116124
params = cli.BuildParams(params)
117125

126+
# can be used to force output of all started sub-processes through the host-process stdout
127+
utils.redirect_stdout_enabled = hasattr(params, "redirect_stdout") and params.redirect_stdout
128+
118129
if (params.target is None):
119-
sys.exit("ERROR: No target platform specified")
130+
utils.cli_exit("ERROR: No target platform specified")
120131

121132
if (params.docker and params.vagrant):
122-
sys.exit("ERROR: Choose either Docker or Vagrant for the build, can not use both")
133+
utils.cli_exit("ERROR: Choose either Docker or Vagrant for the build, can not use both")
123134

124135
target = params.target
125136

126137
if (not target in bc.platform_configs):
127-
sys.exit("ERROR: Unrecognized target platform: " + target)
138+
utils.cli_exit("ERROR: Unrecognized target platform: " + target)
128139

129140
# this defines the PlatformConfig / operating system the build should be run for
130141
target_platform = bc.platform_configs.get(target)
131142

132143
if (params.arch is None):
133-
sys.exit("ERROR: No target architecture specified")
144+
utils.cli_exit("ERROR: No target architecture specified")
134145

135146
avail_architectures = target_platform.architectures
136147

137148
if (not params.arch in avail_architectures):
138-
sys.exit("ERROR: Unsupported architecture: \"" + params.arch + "\" for selected target platform: " + target)
149+
utils.cli_exit("ERROR: Unsupported architecture: \"" + params.arch + "\" for selected target platform: " + target)
139150

140151
if (params.buildsteps is None):
141-
sys.exit("ERROR: No build-step specified, valid values are: " + ", ".join(bc.avail_build_steps))
152+
utils.cli_exit("ERROR: No build-step specified, valid values are: " + ", ".join(bc.avail_build_steps))
142153

143154
if (not params.buildsteps is None and not isinstance(params.buildsteps, list)):
144155
params.buildsteps = [params.buildsteps]
145156

146-
global parsed_steps
157+
parsed_steps = BuildState.parsed_steps
147158
parsed_steps.clear()
148159

149160
# go through the raw list of build-steps (given by the CLI or an API call)
@@ -155,7 +166,7 @@ def execute_build(params):
155166
parsed_steps = [step for step in bc.atomic_build_step_sequence if step in parsed_steps]
156167

157168
if (len(parsed_steps) == 0):
158-
sys.exit("WARNING: No build-steps to be done ... exiting")
169+
utils.cli_exit("WARNING: No build-steps to be done ... exiting")
159170

160171
build_cwd = utils.get_cwd()
161172

@@ -168,7 +179,7 @@ def execute_build(params):
168179
# try to find the configuration parameters to run the cross-compiler
169180
if (cross_sys):
170181
if (cross_configs.get(cross_sys) is None):
171-
sys.exit("ERROR: target '" + target + "' does not have a recognized cross-compile host: '" + cross_sys + "'")
182+
utils.cli_exit("ERROR: target '" + target + "' does not have a recognized cross-compile host: '" + cross_sys + "'")
172183
else:
173184
cross_cfg = cross_configs.get(cross_sys)
174185

@@ -231,14 +242,14 @@ def execute_build_step(build_system, build_step):
231242
cross_cfg = cross_configs.get(params.cross_agent)
232243

233244
if (cross_cfg is None):
234-
sys.exit("ERROR: internal error while looking for cross-compiler config: " + params.cross_agent)
245+
utils.cli_exit("ERROR: internal error while looking for cross-compiler config: " + params.cross_agent)
235246

236247
build_cwd = cross_cfg.build_cwd
237248

238249
# execute all steps from a list that parsed / evaluated before (see the "build-step parsing" section above)
239250
for step in parsed_steps:
240251
if (not step in build_steps):
241-
print("INFO: skipping build step \"" + step + "\" (not configured and/or supported for platform \"" + params.target + "\")")
252+
print("WARNING: skipping build step \"" + step + "\" (not configured and/or supported for platform \"" + params.target + "\")")
242253
continue
243254

244255
target_step = build_steps[step]

build_system/build_interactive.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import build_configs as bcfg
55
import build_executor as bex
6+
import build_utils as utils
67

78
def run_interactive_cli():
89
idx = 0
@@ -20,7 +21,7 @@ def run_interactive_cli():
2021
else input("Select a predefined build-configuration to run: ")
2122

2223
if not isinstance(sel_index, int) or sel_index < 0 or sel_index > len(bcfg.configs):
23-
sys.exit("ERROR: Must enter a valid test index in the range [0 ... " + str(len(bcfg.configs)) + "]")
24+
utils.cli_exit("ERROR: Must enter a valid test index in the range [0 ... " + str(len(bcfg.configs)) + "]")
2425

2526
sel_cfg = bcfg.configs[sel_index]
2627

build_system/build_structures.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def cross_compiler(self, cross_host_name):
3333
compiler = self.cross_compilers.get(cross_host_name)
3434

3535
if (not compiler):
36-
sys.exit("ERROR: internal error while looking for cross-compiler: " + cross_host_name)
36+
utils.cli_exit("ERROR: internal error while looking for cross-compiler: " + cross_host_name)
3737

3838
return compiler()
3939

0 commit comments

Comments
 (0)