Skip to content

Commit 50be3a5

Browse files
galpeterrerobika
authored andcommitted
Document and improve the single-source generation (#2986)
Changes done: * Added usage/configuration info for this mode. * Created `tools/srcgenerator.py` to allow source/header generation without using CMake. * Adapted CMake to use the `srcgenerator.py` script. * Added jerry-libm single-source build. * Improved the `srcmerger.py` script to correctly handle the line numbering. JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
1 parent 7685afd commit 50be3a5

File tree

7 files changed

+259
-63
lines changed

7 files changed

+259
-63
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ if(DEFINED EXTERNAL_LINKER_FLAGS)
231231
jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS})
232232
endif()
233233

234+
# Used for placeholder to attach single source build targets
235+
add_custom_target(generate-single-source)
236+
234237
# Jerry's libm
235238
if(JERRY_LIBM)
236239
add_subdirectory(jerry-libm)

docs/01.CONFIGURATION.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,40 @@ This option is disabled by default.
250250
| C: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=0/1` |
251251
| CMake: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=ON/OFF` |
252252
| Python: | `--mem-stress-test=ON/OFF` |
253+
254+
255+
# Single source build mode
256+
257+
There is a special mode to use/"build" JerryScript. That is generating a single C file which can be
258+
included into projects quickly. To achive this the following command can be executed to create
259+
a set of files into the `gen_src` directory (Note that the command is executed in the jerryscript root directory
260+
but can be adapted to run outside of the project root dir):
261+
262+
```sh
263+
$ python tools/srcgenerator.py --output-dir gen_src --jerry-core --jerry-port-default --jerry-libm
264+
```
265+
266+
The command creates the following files in the `gen_src` dir:
267+
268+
* `jerryscript.c`
269+
* `jerryscript.h`
270+
* `jerryscript-config.h`
271+
* `jerryscript-port-default.c`
272+
* `jerryscript-port-default.h`
273+
* `jerryscript-libm.c`
274+
* `math.h`
275+
276+
**Important**: the `jerryscript-config.h` contains the configurations mentioned above and
277+
should be adapted to the required use-case. See the file contents for more details and for the
278+
default configuration. (Note: This config file is created from the the `jerry-core/config.h` file.)
279+
280+
These files can be directly compiled with an application using the JerryScript API.
281+
For example with the following command:
282+
283+
```sh
284+
$ gcc -Wall -o demo_app demo_app.c gen_src/jerryscript.c gen_src/jerryscript-port-default.c jerryscript-libm.c -Igen_src/
285+
```
286+
287+
Please note that the headers must be available on the include path.
288+
289+
In addition there is a `-DENABLE_ALL_IN_ONE_SOURCE=ON` CMake option to use this kind of sources during the build.

jerry-core/CMakeLists.txt

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -160,48 +160,28 @@ endif()
160160
# * jerryscript.h
161161
# * jerryscript-config.h
162162
if(ENABLE_ALL_IN_ONE_SOURCE)
163-
# Create a default configuration
164-
set(JERRYSCRIPT_CONFIG_H "${CMAKE_BINARY_DIR}/jerryscript-config.h")
165-
set(JERRYSCRIPT_SOURCE_CONFIG_H "${CMAKE_CURRENT_SOURCE_DIR}/config.h")
166-
add_custom_command(OUTPUT ${JERRYSCRIPT_CONFIG_H}
167-
COMMAND ${CMAKE_COMMAND} -E copy ${JERRYSCRIPT_SOURCE_CONFIG_H} ${JERRYSCRIPT_CONFIG_H}
168-
DEPENDS ${JERRYSCRIPT_SOURCE_CONFIG_H})
169-
170-
# Create single C file
163+
164+
# Create single C/H file
171165
file(GLOB HEADER_CORE_FILES *.h)
172-
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/jerryscript.c")
173-
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/jerryscript.h")
174-
add_custom_command(OUTPUT ${ALL_IN_FILE}
175-
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcmerger.py
176-
--base-dir ${CMAKE_CURRENT_SOURCE_DIR}
177-
--input ${CMAKE_CURRENT_SOURCE_DIR}/api/jerry.c
178-
--output ${ALL_IN_FILE}
179-
--append-c-files
180-
--remove-include jerryscript.h
181-
--remove-include jerryscript-port.h
182-
--remove-include jerryscript-compiler.h
183-
--remove-include jerryscript-core.h
184-
--remove-include jerryscript-debugger.h
185-
--remove-include jerryscript-debugger-transport.h
186-
--remove-include jerryscript-port.h
187-
--remove-include jerryscript-snapshot.h
188-
--remove-include config.h
189-
--push-include jerryscript.h
190-
DEPENDS ${SOURCE_CORE_FILES} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H}
191-
)
192-
add_custom_command(OUTPUT ${ALL_IN_FILE_H}
193-
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcmerger.py
194-
--base-dir ${CMAKE_CURRENT_SOURCE_DIR}
195-
--input ${CMAKE_CURRENT_SOURCE_DIR}/include/jerryscript.h
196-
--output ${ALL_IN_FILE_H}
197-
--remove-include config.h
198-
--push-include jerryscript-config.h
199-
DEPENDS ${HEADER_CORE_FILES} ${JERRYSCRIPT_CONFIG_H}
166+
167+
# Generated files
168+
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/src/jerryscript.c")
169+
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/src/jerryscript.h")
170+
set(JERRYSCRIPT_CONFIG_H "${CMAKE_BINARY_DIR}/src/jerryscript-config.h")
171+
172+
add_custom_command(OUTPUT ${ALL_IN_FILE} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H}
173+
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
174+
--jerry-core
175+
--output-dir ${CMAKE_BINARY_DIR}/src
176+
DEPENDS ${SOURCE_CORE_FILES}
177+
${HEADER_CORE_FILES}
178+
${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
179+
${CMAKE_SOURCE_DIR}/tools/srcmerger.py
200180
)
201181
add_custom_target(generate-single-source-jerry DEPENDS ${ALL_IN_FILE} ${ALL_IN_FILE_H})
202-
add_custom_target(generate-single-source DEPENDS generate-single-source-jerry)
182+
add_dependencies(generate-single-source generate-single-source-jerry)
203183

204-
set(SOURCE_CORE_FILES ${ALL_IN_FILE} ${ALL_IN_FILE_H})
184+
set(SOURCE_CORE_FILES ${ALL_IN_FILE} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H})
205185
endif()
206186

207187
# Third-party

jerry-libm/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,30 @@ set(INCLUDE_LIBM "${CMAKE_CURRENT_SOURCE_DIR}/include")
3030
# Source directories
3131
file(GLOB SOURCE_LIBM *.c)
3232

33+
# "Single" JerryScript libm source/header build.
34+
# The process will create the following files:
35+
# * jerryscript-libm.c
36+
# * math.h
37+
if(ENABLE_ALL_IN_ONE_SOURCE)
38+
file(GLOB HEADER_LIBM *.h)
39+
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/src/jerryscript-libm.c")
40+
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/src/math.h")
41+
42+
add_custom_command(OUTPUT ${ALL_IN_FILE} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H}
43+
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
44+
--jerry-libm
45+
--output-dir ${CMAKE_BINARY_DIR}/src
46+
DEPENDS ${SOURCE_LIBM}
47+
${HEADER_LIBM}
48+
${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
49+
${CMAKE_SOURCE_DIR}/tools/srcmerger.py
50+
)
51+
add_custom_target(generate-single-source-libm DEPENDS ${ALL_IN_FILE} ${ALL_IN_FILE_H})
52+
add_dependencies(generate-single-source generate-single-source-libm)
53+
54+
set(SOURCE_LIBM ${ALL_IN_FILE} ${ALL_IN_FILE_H})
55+
endif()
56+
3357
add_library(${JERRY_LIBM_NAME} ${SOURCE_LIBM})
3458
set_property(TARGET ${JERRY_LIBM_NAME}
3559
PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_LIBM}")

jerry-port/default/CMakeLists.txt

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,17 @@ file(GLOB SOURCE_PORT_DEFAULT *.c)
2828
# * jerryscript-port-default.h
2929
if(ENABLE_ALL_IN_ONE_SOURCE)
3030
file(GLOB HEADER_PORT_DEFAULT *.h)
31-
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/jerryscript-port-default.c")
32-
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/jerryscript-port-default.h")
33-
add_custom_command(OUTPUT ${ALL_IN_FILE}
34-
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcmerger.py
35-
--base-dir ${CMAKE_CURRENT_SOURCE_DIR}
36-
--output ${ALL_IN_FILE}
37-
--append-c-files
38-
--remove-include jerryscript-port.h
39-
--remove-include jerryscript-port-default.h
40-
--remove-include jerryscript-debugger.h
41-
--push-include jerryscript.h
42-
--push-include jerryscript-port-default.h
43-
DEPENDS ${SOURCE_PORT_DEFAULT} ${ALL_IN_FILE_H}
44-
)
31+
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/src/jerryscript-port-default.c")
32+
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/src/jerryscript-port-default.h")
4533

46-
add_custom_command(OUTPUT ${ALL_IN_FILE_H}
47-
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcmerger.py
48-
--base-dir ${CMAKE_CURRENT_SOURCE_DIR}/
49-
--input ${CMAKE_CURRENT_SOURCE_DIR}/include/jerryscript-port-default.h
50-
--output ${ALL_IN_FILE_H}
51-
--remove-include jerryscript-port.h
52-
--remove-include jerryscript.h
53-
--push-include jerryscript.h
54-
DEPENDS ${HEADER_PORT_DEFAULT}
34+
add_custom_command(OUTPUT ${ALL_IN_FILE} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H}
35+
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
36+
--jerry-port-default
37+
--output-dir ${CMAKE_BINARY_DIR}/src
38+
DEPENDS ${SOURCE_PORT_DEFAULT}
39+
${HEADER_PORT_DEFAULT}
40+
${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
41+
${CMAKE_SOURCE_DIR}/tools/srcmerger.py
5542
)
5643
add_custom_target(generate-single-source-port DEPENDS ${ALL_IN_FILE} ${ALL_IN_FILE_H})
5744
add_dependencies(generate-single-source generate-single-source-port)

tools/srcgenerator.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright JS Foundation and other contributors, http://js.foundation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
from __future__ import print_function
17+
18+
import argparse
19+
import logging
20+
import os
21+
import subprocess
22+
import shutil
23+
24+
25+
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
26+
ROOT_DIR = os.path.dirname(TOOLS_DIR)
27+
SRCMERGER = os.path.join(TOOLS_DIR, 'srcmerger.py')
28+
JERRY_CORE = os.path.join(ROOT_DIR, 'jerry-core')
29+
JERRY_PORT = os.path.join(ROOT_DIR, 'jerry-port', 'default')
30+
JERRY_LIBM = os.path.join(ROOT_DIR, 'jerry-libm')
31+
32+
33+
def run_commands(*cmds, **kwargs):
34+
log = logging.getLogger('sourcegenerator')
35+
verbose = kwargs.get('verbose', False)
36+
37+
for cmd in cmds:
38+
if verbose:
39+
cmd.append('--verbose')
40+
log.debug('Run command: %s', cmd)
41+
subprocess.call(cmd)
42+
43+
44+
def generate_jerry_core(output_dir, verbose=False):
45+
cmd_jerry_c_gen = [
46+
'python', SRCMERGER,
47+
'--base-dir', JERRY_CORE,
48+
'--input={}/api/jerry.c'.format(JERRY_CORE),
49+
'--output={}/jerryscript.c'.format(output_dir),
50+
'--append-c-files',
51+
'--remove-include=jerryscript.h',
52+
'--remove-include=jerryscript-port.h',
53+
'--remove-include=jerryscript-compiler.h',
54+
'--remove-include=jerryscript-core.h',
55+
'--remove-include=jerryscript-debugger.h',
56+
'--remove-include=jerryscript-debugger-transport.h',
57+
'--remove-include=jerryscript-port.h',
58+
'--remove-include=jerryscript-snapshot.h'
59+
'--remove-include=config.h',
60+
'--push-include=jerryscript.h',
61+
]
62+
63+
cmd_jerry_h_gen = [
64+
'python', SRCMERGER,
65+
'--base-dir', JERRY_CORE,
66+
'--input={}/include/jerryscript.h'.format(JERRY_CORE),
67+
'--output={}/jerryscript.h'.format(output_dir),
68+
'--remove-include=config.h',
69+
'--push-include=jerryscript-config.h',
70+
]
71+
72+
run_commands(cmd_jerry_c_gen, cmd_jerry_h_gen, verbose=verbose)
73+
74+
shutil.copyfile('{}/config.h'.format(JERRY_CORE),
75+
'{}/jerryscript-config.h'.format(output_dir))
76+
77+
78+
def generate_jerry_port_default(output_dir, verbose=False):
79+
cmd_port_c_gen = [
80+
'python', SRCMERGER,
81+
'--base-dir', JERRY_PORT,
82+
'--output={}/jerryscript-port-default.c'.format(output_dir),
83+
'--append-c-files',
84+
'--remove-include=jerryscript-port.h',
85+
'--remove-include=jerryscript-port-default.h',
86+
'--remove-include=jerryscript-debugger.h',
87+
'--push-include=jerryscript.h',
88+
'--push-include=jerryscript-port-default.h',
89+
]
90+
91+
cmd_port_h_gen = [
92+
'python', SRCMERGER,
93+
'--base-dir', JERRY_PORT,
94+
'--input={}/include/jerryscript-port-default.h'.format(JERRY_PORT),
95+
'--output={}/jerryscript-port-default.h'.format(output_dir),
96+
'--remove-include=jerryscript-port.h',
97+
'--remove-include=jerryscript.h',
98+
'--push-include=jerryscript.h',
99+
]
100+
101+
run_commands(cmd_port_c_gen, cmd_port_h_gen, verbose=verbose)
102+
103+
104+
def generate_jerry_libm(output_dir, verbose=False):
105+
cmd_libm_c_gen = [
106+
'python', SRCMERGER,
107+
'--base-dir', JERRY_LIBM,
108+
'--output={}/jerryscript-libm.c'.format(output_dir),
109+
'--append-c-files',
110+
]
111+
112+
run_commands(cmd_libm_c_gen, verbose=verbose)
113+
114+
shutil.copyfile('{}/include/math.h'.format(JERRY_LIBM),
115+
'{}/math.h'.format(output_dir))
116+
117+
def main():
118+
parser = argparse.ArgumentParser(description='Generate single sources.')
119+
parser.add_argument('--jerry-core', action='store_true', dest='jerry_core',
120+
help='Generate jerry-core files', default=False)
121+
parser.add_argument('--jerry-port-default', action='store_true', dest='jerry_port_default',
122+
help='Generate jerry-port-default files', default=False)
123+
parser.add_argument('--jerry-libm', action='store_true', dest='jerry_libm',
124+
help='Generate jerry-libm files', default=False)
125+
parser.add_argument('--output-dir', metavar='DIR', type=str, dest='output_dir',
126+
default='gen_src', help='Output dir')
127+
parser.add_argument('--verbose', '-v', action='store_true', default=False)
128+
129+
args = parser.parse_args()
130+
131+
if args.verbose:
132+
logging.basicConfig(level=logging.DEBUG)
133+
134+
try:
135+
os.makedirs(args.output_dir)
136+
except os.error:
137+
pass
138+
139+
if args.jerry_core:
140+
generate_jerry_core(args.output_dir, args.verbose)
141+
142+
if args.jerry_port_default:
143+
generate_jerry_port_default(args.output_dir, args.verbose)
144+
145+
if args.jerry_libm:
146+
generate_jerry_libm(args.output_dir, args.verbose)
147+
148+
149+
if __name__ == '__main__':
150+
main()

0 commit comments

Comments
 (0)