X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=build_common%2Farduino%2FSConscript;h=4c3a01f4354c33774cabd31b8449522074b8d50f;hb=5bfbca271ab1d61323ac61df11df68aba1090ae1;hp=d33cc5597f4a354ed58bfd30e68b764de96b59ad;hpb=b5316392791e499dec3a381349c50602ecdbd69c;p=platform%2Fupstream%2Fiotivity.git diff --git a/build_common/arduino/SConscript b/build_common/arduino/SConscript index d33cc55..4c3a01f 100644 --- a/build_common/arduino/SConscript +++ b/build_common/arduino/SConscript @@ -4,13 +4,190 @@ import os import platform -Import('env', 'RELEASE_BUILD', 'TARGET_CPU_ARCH', 'ARDUINO_HOME') +Import('env') -if not ARDUINO_HOME: +def __parse_config(f): + dict = {} + + if not os.path.isfile(f): + return dict + + file = open(f, 'r') + strs = file.readlines() + for str in strs: + str = str.strip() + if len(str) > 0 and str[0] == '#': + continue + + idx = str.find('=') + if idx > 0: + dict.setdefault(str[0:idx], str[idx + 1:]) + + return dict + +def __get_boards(dict): + boards = [] + keys = dict.keys() + for key in keys: + idx = key.find('.name') + if idx > 0: + if key.endswith('.name'): + boards.append(key[0:idx]) + return boards + +def __get_cpu(dict, board): + cpus = [] + keys = dict.keys() + for key in keys: + idx = key.find(board + '.menu.cpu.') + start = len(board + '.menu.cpu.') + if idx >= 0: + end = key.find('.', start) + if end > 0: + cpu = key[start:end] + exist = False + for c in cpus: + if c == cpu: + exist = True + break + + if not exist: + cpus.append(cpu) + return cpus + +def __get_board_info(board, key): + if cpu: + v = boards_info.get(board + '.menu.cpu.' + cpu + key) + if not v: + v = boards_info.get(board + key) + else: + v = boards_info.get(board + key) + return v + +def __search_files(path, pattern, ondisk=True, source=True, strings=False, recursive=True): + if not recursive: + return Glob(pattern, ondisk, source, strings) + + matches = [] + for root, dirnames, filenames in os.walk(path): + matches.extend(Glob(root + '/' + pattern, ondisk, source, strings)) + + return matches + +# To make sure the src is built in 'BUILD_DIR' (by default it will be built at +# the same directory as the .c .cpp .S) +def __src_to_obj(env, srcs): + objs = [] + prefix = env.get('BOARD') + '_' + if env.get('CPU'): + prefix += env.get('CPU') + '_' + + build_dir = env.get('BUILD_DIR') + '/arduino/' + for src in srcs: + obj = src.path.replace(arduino_home, build_dir) + i = obj.rfind('.') + obj = obj[0:i] + if env.get('OBJSUFFIX'): + obj += env.get('OBJSUFFIX') + objs.extend(env.Object(obj, src, OBJPREFIX=prefix)) + return objs + +def __import_lib(env, lib): + lib_path = arduino_home + '/libraries/' + lib + if not os.path.exists(lib_path): + if target_arch == 'avr': + lib_path = arduino_home + '/hardware/arduino/avr/libraries/' + lib + else: + lib_path = arduino_home + '/hardware/arduino/sam/libraries/' + lib + + if os.path.exists(lib_path + '/src'): + lib_path = lib_path + '/src' + + env.AppendUnique(CPPPATH = [lib_path]) + + if os.path.exists(lib_path + '/utility'): + env.AppendUnique(CPPPATH = [lib_path + '/utility']) + + lib_src = [] + lib_src.extend(__search_files(lib_path, '*.S')) + lib_src.extend(__search_files(lib_path, '*.c')) + lib_src.extend(__search_files(lib_path, '*.cpp')) + + build_dir = env.get('BUILD_DIR') + if build_dir: + lib_a = env.StaticLibrary(build_dir + lib, __src_to_obj(env, lib_src)) + else: + lib_a = env.StaticLibrary(lib, __src_to_obj(env, lib_src)) + env.AppendUnique(LIBS = [File(lib_a[0])]) + +def __build_core(env): + core_src = __search_files(core_folder, '*.S') + core_src.extend(__search_files(core_folder, '*.c')) + core_src.extend(__search_files(core_folder, '*.cpp')) + + core_src.extend(__search_files(variant_folder, '*.S')) + core_src.extend(__search_files(variant_folder, '*.c')) + core_src.extend(__search_files(variant_folder, '*.cpp')) + + core_obj = __src_to_obj(env, core_src) + build_dir = env.get('BUILD_DIR') + if build_dir: + s_core = env.StaticLibrary(build_dir + 'core', core_obj) + else: + s_core = env.StaticLibrary('core', core_obj) + env.AppendUnique(LIBS = [File(s_core[0])]) + + # To avoid compiler issue. Otherewise there may be warnings: + # undefined reference to '_exit' '_close', '_getpid' ... + # Above functions are used in libc.a and implemented in syscalls_sam3.c + if env.get('TARGET_ARCH') == 'arm': + for obj in core_obj: + if obj.name.endswith('syscalls_sam3.o'): + env.AppendUnique(LIBS = [File(obj)]) + +def __create_bin(env, source): + name = source + if env.get('TARGET_ARCH') == 'avr': + eep = env.Command(name + '.eep', source, 'avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $SOURCE $TARGET') + hex = env.Command(name + '.hex', source, 'avr-objcopy -O ihex -R .eeprom $SOURCE $TARGET') + else: + hex = env.Command(name + '.hex', source, 'arm-none-eabi-objcopy -O binary $SOURCE $TARGET') + +# Print the command line that to upload binary to the board +def __upload_help(env): + if target_arch == 'avr': + protocol = __get_board_info(board, '.upload.protocol') + speed = __get_board_info(board, '.upload.speed') + + upload_cmd = arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -p' \ + + mcu + ' -c' + protocol + ' -P' + ' -b' + speed + ' -D -Uflash:w::i' + else: + uu = __get_board_info(board, '.upload.native_usb') + upload_cmd = arduino_home + '/hardware/tools/bossac -i -d --port= -U ' + uu + ' -e -w -v -b -R' + + Help(''' +=============================================================================== +You can upload the bin file with following command line: +''') + Help('\n $ ' + upload_cmd) + Help(''' +\nPlease replace according to the actual situation. +=============================================================================== +''') + +# ARDUINO_HOME build option +help_vars = Variables() +help_vars.Add(PathVariable('ARDUINO_HOME', 'ARDUINO root directory', os.environ.get('ARDUINO_HOME'))) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) + +target_arch = env.get('TARGET_ARCH') +arduino_home = env.get('ARDUINO_HOME') +if not arduino_home: print ''' ************************************* Error *********************************** -* Arduino root directory (ARDUINO_HOME) isn't set, you can set enviornment * -* variable ARDUINO_HOME or add it in command line as: * +* Arduino root directory isn't set, you can set enviornment variable * +* ARDUINO_HOME or add it in command line as: * * # scons ARDUINO_HOME= ... * ******************************************************************************* ''' @@ -32,53 +209,192 @@ elif platform.system().lower() == 'darwin': env['LIBSUFFIXES'] = ['.a', '.so'] env['PROGSUFFIX'] = '' -# Set toolchain -def find_toolchain(dir, tc): - for root, dirs, files in os.walk(dir, True, None, False): - for f in files: - lf = f.lower() - if lf == tc: - return root - return None - -if TARGET_CPU_ARCH == 'arm': - prefix = 'arm-none-eabi-' +# Debug/release relative flags +if env.get('RELEASE'): + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) else: - prefix = 'avr-' + env.AppendUnique(CCFLAGS = ['-g']) + +# BOARD / CPU option -tc_path = find_toolchain(ARDUINO_HOME + '/hardware/tools/', prefix + 'g++') -if not tc_path: +# Get IDE version +if os.path.exists(arduino_home + '/lib/version.txt'): + vf = open(arduino_home + '/lib/version.txt', 'r') + version = vf.readline().replace('.', '') +else: print ''' ************************************* Error *********************************** -* Arduino toolchain isn't detected. Please specify the toolchain prefix and * -* path, you can do it by setting enviornment variable TC_PREFIX and TC_PATH or* -* add it in command line as: * -* # scons TC_PREFIX= TC_PATH= ... * -* e.g. scons TC_PREFIX=avr- TC_PATH=/opt/arduino-1.5.7/hardware/tools/avr/bin * * -* Note: TC_PREFIX shouldn't include path * +* Can't find version file (lib/version.txt), please check if (%s) +* is arduino root directory. * ******************************************************************************* -''' +''' % arduino_home Exit(1) -env.PrependENVPath('PATH', tc_path) -env.Replace(CC = prefix + 'gcc') -env.Replace(CXX = prefix + 'g++') -env.Replace(AR = prefix + 'ar') -env.Replace(AS = prefix + 'as') -env.Replace(LINK = prefix + 'ld') -env.Replace(RANLIB = prefix + 'ranlib') +if version[0:2] == '10': + is_1_0_x = True + boards_info = __parse_config(arduino_home + '/hardware/arduino/boards.txt') + env.PrependENVPath('PATH', arduino_home + '/hardware/tools/avr/bin/') + env.Replace(CC = 'avr-gcc') + env.Replace(CXX = 'avr-g++') + env.Replace(AR = 'avr-ar') + env.Replace(AS = 'avr-as') + env.Replace(LINK = 'avr-gcc') + env.Replace(RANLIB = 'avr-ranlib') + if target_arch != 'avr': + print ''' +************************************* Error *********************************** +* Arduino 1.0.x IDE only support 'avr', to support other arch at least 1.5.x * +* is required. +******************************************************************************* +''' + Exit(1) +else: + is_1_0_x = False + if target_arch == 'avr': + boards_info = __parse_config(arduino_home + '/hardware/arduino/avr/boards.txt') + platform_info = __parse_config(arduino_home + '/hardware/arduino/avr/platform.txt') + elif target_arch == 'arm': + boards_info = __parse_config(arduino_home + '/hardware/arduino/sam/boards.txt') + platform_info = __parse_config(arduino_home + '/hardware/arduino/sam/platform.txt') + else: + print ''' +************************************* Error *********************************** +* CPU arch %s isn't supported currently. +******************************************************************************* +''' % target_arch -sys_root = os.path.abspath(os.path.join(tc_path, '..')) -env.AppendUnique(CFLAGS = ['--sysroot=' + sys_root]) -env.AppendUnique(CXXFLAGS = ['--sysroot=' + sys_root]) -env.AppendUnique(LINKFLAGS = ['--sysroot=' + sys_root]) +#Board option, let user to select the board +boards = __get_boards(boards_info) +help_vars = Variables() +help_vars.Add(EnumVariable('BOARD', 'arduino board', boards[0], boards)) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) -# Debug/release relative flags -if RELEASE_BUILD: - env.AppendUnique(CFLAGS = ['-Os']) - env.AppendUnique(CXXFLAGS = ['-Os']) - env.AppendUnique(CPPDEFINES = ['NDEBUG']) - env.AppendUnique(LINKFLAGS = ['-s']) +#CPU option +board = env.get('BOARD') +cpus = __get_cpu(boards_info, board) +if len(cpus) > 0: + help_vars = Variables() + help_vars.Add(EnumVariable('CPU', 'arduino board cpu', cpus[0], cpus)) + help_vars.Update(env) + Help(help_vars.GenerateHelpText(env)) + +# Arduino commom flags +cpu = env.get('CPU') +board = env.get('BOARD') +mcu = __get_board_info(board, '.build.mcu') +f_cpu = __get_board_info(board, '.build.f_cpu') +usb_vid = __get_board_info(board, '.build.vid') +usb_pid = __get_board_info(board, '.build.pid') +variant = __get_board_info(board, '.build.variant') + +if not usb_vid: + usb_vid = __get_board_info(board, '.vid.0') +if not usb_pid: + usb_pid = __get_board_info(board, '.pid.0') + +if is_1_0_x: + core_base = arduino_home + '/hardware/arduino/' else: - env.AppendUnique(CFLAGS = ['-g']) - env.AppendUnique(CXXFLAGS = ['-g']) \ No newline at end of file + if target_arch == 'avr': + core_base = arduino_home + '/hardware/arduino/avr/' + else: + core_base = arduino_home + '/hardware/arduino/sam/' + +variant_folder = core_base + 'variants/' + variant +env.AppendUnique(CPPPATH = [variant_folder]) + +core = __get_board_info(board, '.build.core') +core_folder = core_base + 'cores/' + core + '/' +env.AppendUnique(CPPPATH = [core_folder]) + +if is_1_0_x: + comm_flags = [] + if mcu: + comm_flags.extend(['-mmcu=' + mcu]) + if f_cpu: + comm_flags.extend(['-DF_CPU=' + f_cpu]) + comm_flags.extend(['-DARDUINO=' + version]) + if usb_vid: + comm_flags.extend(['-DUSB_VID=' + usb_vid]) + if usb_pid: + comm_flags.extend(['-DUSB_PID=' + usb_pid]) + + env.AppendUnique(ASFLAGS = ['-x', 'assembler-with-cpp']) + env.AppendUnique(ASFLAGS = comm_flags) + + env.AppendUnique(CFLAGS = ['-Os', '-ffunction-sections', '-fdata-sections', '-MMD']) + env.AppendUnique(CFLAGS = comm_flags) + + env.AppendUnique(CXXFLAGS = ['-Os', '-fno-exceptions', '-ffunction-sections', '-fdata-sections','-MMD']) + env.AppendUnique(CXXFLAGS = comm_flags) + + env.AppendUnique(LINKFLAGS = ['-Os']) + if mcu == 'atmega2560': + env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections,--relax']) + else: + env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections']) + env.AppendUnique(LINKFLAGS = ['-mmcu=' + mcu]) +else: + if target_arch == 'avr': + cpu_flag = '-mmcu=' + mcu + else: + cpu_flag = '-mcpu=' + mcu + + comm_flag = [cpu_flag, '-DF_CPU=' + f_cpu, '-DARDUINO=' + version, '-DARDUINO_' + __get_board_info(board, '.build.board')] + if target_arch == 'arm': + comm_flag.extend(['-DARDUINO_ARCH_SAM']) + else: + comm_flag.extend(['-DARDUINO_ARCH_AVR']) + + compiler_path = platform_info.get('compiler.path') + compiler_path = compiler_path.replace('{runtime.ide.path}', arduino_home) + env.PrependENVPath('PATH', compiler_path) + env.Replace(CC = platform_info.get('compiler.c.cmd')) + env.Replace(CXX = platform_info.get('compiler.cpp.cmd')) + env.Replace(AR = platform_info.get('compiler.ar.cmd')) + if target_arch == 'arm': + env.AppendUnique(CPPPATH = [arduino_home + '/hardware/arduino/sam/system/libsam', + arduino_home + '/hardware/arduino/sam/system/CMSIS/CMSIS/Include/', + arduino_home + '/hardware/arduino/sam/system//CMSIS/Device/ATMEL']) + env.AppendUnique(ASFLAGS = ['-x', 'assembler-with-cpp']) + env.AppendUnique(ASFLAGS = comm_flag) + env.AppendUnique(CFLAGS = Split(platform_info.get('compiler.c.flags'))) + env.AppendUnique(CXXFLAGS = Split(platform_info.get('compiler.cpp.flags'))) + env.AppendUnique(ARFLAGS = Split(platform_info.get('compiler.ar.flags'))) + env.AppendUnique(CCFLAGS = comm_flag) + + extra_flags = __get_board_info(board, '.build.extra_flags') + if extra_flags: + extra_flags = extra_flags.replace('{build.usb_flags}', '') + env.AppendUnique(CCFLAGS = Split(extra_flags)) + usb_flags = ['-DUSB_VID=' + usb_vid, '-DUSB_PID=' + usb_pid, '-DUSBCON', '-DUSB_MANUFACTURER="Unknown"'] + env.AppendUnique(CCFLAGS = usb_flags) + + if target_arch == 'arm': + env.AppendUnique(LINKFLAGS = ['-Os', '-Wl,--gc-sections', cpu_flag, + '-T' + variant_folder + '/' + __get_board_info(board, '.build.ldscript'), + '-Wl,-Map,' + env.get('BUILD_DIR') + 'arduino_prj.map']) + env.AppendUnique(LINKFLAGS = Split('-lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group')) + + variant_system_lib = __get_board_info(board, '.build.variant_system_lib') + if variant_system_lib: + if variant_folder.find(' ') >= 0: + variant_folder = '"' + variant_folder + '"' + env.Replace(LINKCOM = '$LINK -o $TARGET $_LIBDIRFLAGS $LINKFLAGS $SOURCES $_LIBFLAGS ' + + variant_folder + '/' + variant_system_lib + ' -Wl,--end-group') + else: + env.Replace(LINKCOM = '$LINK -o $TARGET $_LIBDIRFLAGS $LINKFLAGS $SOURCES $_LIBFLAGS -Wl,--end-group') + else: + env.AppendUnique(LINKFLAGS = Split(platform_info.get('compiler.c.elf.flags'))) + env.AppendUnique(LINKFLAGS = [cpu_flag]) + env.AppendUnique(LIBS = 'm') + env.Replace(ARCOM = '$AR ' + platform_info.get('compiler.ar.flags') + ' $TARGET $SOURCES') + +__build_core(env) + +env.AddMethod(__import_lib, "ImportLib") #import arduino library +#env.AddMethod(__build_core, "BuildCore") #build arduino core +env.AddMethod(__create_bin, "CreateBin") #create binary files(.eep and .hex) +env.AddMethod(__upload_help, "UploadHelp") #print the command line that to upload binary to the boardf