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# 17import fnmatch 18import os 19 20def build_soft_links(project_path, jerry_path): 21 """ Creates soft links into the @project_path. """ 22 23 if not os.path.exists(project_path): 24 os.makedirs(project_path) 25 26 links = [ 27 { # arc 28 'src': os.path.join('targets', 'curie_bsp', 'jerry_app', 'arc'), 29 'link_name': 'arc' 30 }, 31 { # include 32 'src': os.path.join('targets', 'curie_bsp', 'jerry_app', 'include'), 33 'link_name': 'include' 34 }, 35 { # quark 36 'src': os.path.join('targets', 'curie_bsp', 'jerry_app', 'quark'), 37 'link_name': 'quark' 38 }, 39 { # quark/jerryscript 40 'src': jerry_path, 41 'link_name': os.path.join('quark', 'jerryscript') 42 } 43 ] 44 45 for link in links: 46 src = os.path.join(jerry_path, link['src']) 47 link_name = os.path.join(project_path, link['link_name']) 48 if not os.path.islink(link_name): 49 os.symlink(src, link_name) 50 print("Created symlink '{link_name}' -> '{src}'".format(src=src, link_name=link_name)) 51 52 53def find_sources(root_dir, sub_dir): 54 """ 55 Find .c and .S files inside the @root_dir/@sub_dir directory. 56 Note: the returned paths will be relative to the @root_dir directory. 57 """ 58 src_dir = os.path.join(root_dir, sub_dir) 59 60 matches = [] 61 for root, dirnames, filenames in os.walk(src_dir): 62 for filename in fnmatch.filter(filenames, '*.[c|S]'): 63 file_path = os.path.join(root, filename) 64 relative_path = os.path.relpath(file_path, root_dir) 65 matches.append(relative_path) 66 67 return matches 68 69 70def build_jerry_data(jerry_path): 71 """ 72 Build up a dictionary which contains the following items: 73 - sources: list of JerryScript sources which should be built. 74 - dirs: list of JerryScript dirs used. 75 - cflags: CFLAGS for the build. 76 """ 77 jerry_sources = [] 78 jerry_dirs = set() 79 for sub_dir in ['jerry-core', 'jerry-libm', os.path.join('targets', 'curie_bsp', 'source')]: 80 for file in find_sources(os.path.normpath(jerry_path), sub_dir): 81 path = os.path.join('jerryscript', file) 82 jerry_sources.append(path) 83 jerry_dirs.add(os.path.split(path)[0]) 84 85 jerry_cflags = [ 86 '-DJERRY_GLOBAL_HEAP_SIZE=10', 87 '-DJERRY_NDEBUG', 88 '-DJERRY_DISABLE_HEAVY_DEBUG', 89 '-DJERRY_BUILTIN_NUMBER=0', 90 '-DJERRY_BUILTIN_STRING=0', 91 '-DJERRY_BUILTIN_BOOLEAN=0', 92 #'-DJERRY_BUILTIN_ERRORS=0', 93 '-DJERRY_BUILTIN_ARRAY=0', 94 '-DJERRY_BUILTIN_MATH=0', 95 '-DJERRY_BUILTIN_JSON=0', 96 '-DJERRY_BUILTIN_DATE=0', 97 '-DJERRY_BUILTIN_REGEXP=0', 98 '-DJERRY_BUILTIN_ANNEXB=0', 99 '-DJERRY_ES2015=0', 100 '-DJERRY_LCACHE=0', 101 '-DJERRY_PROPRETY_HASHMAP=0', 102 ] 103 104 return { 105 'sources': jerry_sources, 106 'dirs': jerry_dirs, 107 'cflags': jerry_cflags, 108 } 109 110 111def write_file(path, content): 112 """ Writes @content into the file at specified by the @path. """ 113 norm_path = os.path.normpath(path) 114 with open(norm_path, "w+") as f: 115 f.write(content) 116 print("Wrote file '{0}'".format(norm_path)) 117 118 119def build_obj_y(source_list): 120 """ 121 Build obj-y additions from the @source_list. 122 Note: the input sources should have their file extensions. 123 """ 124 return '\n'.join(['obj-y += {0}.o'.format(os.path.splitext(fname)[0]) for fname in source_list]) 125 126 127def build_cflags_y(cflags_list): 128 """ 129 Build cflags-y additions from the @cflags_list. 130 Note: the input sources should have their file extensions. 131 """ 132 return '\n'.join(['cflags-y += {0}'.format(cflag) for cflag in cflags_list]) 133 134 135def build_mkdir(dir_list): 136 """ Build mkdir calls for each dir in the @dir_list. """ 137 return '\n'.join(['\t$(AT)mkdir -p {0}'.format(os.path.join('$(OUT_SRC)', path)) for path in dir_list]) 138 139 140def create_root_kbuild(project_path): 141 """ Creates @project_path/Kbuild.mk file. """ 142 143 root_kbuild_path = os.path.join(project_path, 'Kbuild.mk') 144 root_kbuild_content = ''' 145obj-$(CONFIG_QUARK_SE_ARC) += arc/ 146obj-$(CONFIG_QUARK_SE_QUARK) += quark/ 147''' 148 write_file(root_kbuild_path, root_kbuild_content) 149 150 151def create_root_makefile(project_path): 152 """ Creates @project_path/Makefile file. """ 153 154 root_makefile_path = os.path.join(project_path, 'Makefile') 155 root_makefile_content = ''' 156THIS_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) 157T := $(abspath $(THIS_DIR)/../..) 158PROJECT := {project_name} 159BOARD := curie_101 160ifeq ($(filter curie_101, $(BOARD)),) 161$(error The curie jerry sample application can only run on the curie_101 Board) 162endif 163BUILDVARIANT ?= debug 164quark_DEFCONFIG = $(PROJECT_PATH)/quark/defconfig 165arc_DEFCONFIG = $(PROJECT_PATH)/arc/defconfig 166 167# Optional: set the default version 168VERSION_MAJOR := 1 169VERSION_MINOR := 0 170VERSION_PATCH := 0 171include $(T)/build/project.mk 172'''.format(project_name=project_name) 173 174 write_file(root_makefile_path, root_makefile_content) 175 176 177def create_arc_kbuild(project_path): 178 """ Creates @project_path/arc/Kbuild.mk file. """ 179 180 arc_path = os.path.join(project_path, 'arc') 181 arc_kbuild_path = os.path.join(arc_path, 'Kbuild.mk') 182 arc_sources = find_sources(arc_path, '.') 183 arc_kbuild_content = build_obj_y(arc_sources) 184 185 write_file(arc_kbuild_path, arc_kbuild_content) 186 187 188def create_quark_kbuild(project_path, jerry_path): 189 """ Creates @project_path/quark/Kbuild.mk file. """ 190 quark_kbuild_path = os.path.join(project_path, 'quark', 'Kbuild.mk') 191 192 # Extract a few JerryScript related data 193 jerry_data = build_jerry_data(jerry_path) 194 jerry_objects = build_obj_y(jerry_data['sources']) 195 jerry_defines = jerry_data['cflags'] 196 jerry_build_dirs = build_mkdir(jerry_data['dirs']) 197 198 quark_include_paths = [ 199 'include', 200 'jerryscript', 201 os.path.join('jerryscript', 'jerry-libm', 'include'), 202 os.path.join('jerryscript', 'targets' ,'curie_bsp', 'include') 203 ] + list(jerry_data['dirs']) 204 205 quark_includes = [ 206 '-Wno-error', 207 ] + ['-I%s' % os.path.join(project_path, 'quark', path) for path in quark_include_paths] 208 209 quark_cflags = build_cflags_y(jerry_defines + quark_includes) 210 211 quark_kbuild_content = ''' 212{cflags} 213 214obj-y += main.o 215{objects} 216 217build_dirs: 218{dirs} 219 220$(OUT_SRC): build_dirs 221'''.format(objects=jerry_objects, cflags=quark_cflags, dirs=jerry_build_dirs) 222 223 write_file(quark_kbuild_path, quark_kbuild_content) 224 225 226def main(curie_path, project_name, jerry_path): 227 project_path = os.path.join(curie_path, 'wearable_device_sw', 'projects', project_name) 228 229 build_soft_links(project_path, jerry_path) 230 231 create_root_kbuild(project_path) 232 create_root_makefile(project_path) 233 create_arc_kbuild(project_path) 234 create_quark_kbuild(project_path, jerry_path) 235 236 237if __name__ == '__main__': 238 import sys 239 240 if len(sys.argv) != 2: 241 print('Usage:') 242 print('{script_name} [full or relative path of Curie_BSP]'.format(script_name=sys.argv[0])) 243 sys.exit(1) 244 245 project_name = 'curie_bsp_jerry' 246 247 file_dir = os.path.dirname(os.path.abspath(__file__)) 248 jerry_path = os.path.join(file_dir, "..", "..") 249 curie_path = os.path.join(os.getcwd(), sys.argv[1]) 250 251 main(curie_path, project_name, jerry_path) 252