Repository: baoshi/CubeMX2Makefile Branch: master Commit: e407488b47c2 Files: 6 Total size: 13.9 KB Directory structure: gitextract_b3ufj516/ ├── .gitattributes ├── .gitignore ├── CubeMX2Makefile.py ├── CubeMX2Makefile.tpl ├── history.txt └── readme.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk # ========================= # Operating System Files # ========================= # OSX # ========================= .DS_Store .AppleDouble .LSOverride # Thumbnails ._* # Files that might appear on external disk .Spotlight-V100 .Trashes # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ================================================ FILE: CubeMX2Makefile.py ================================================ #!/usr/bin/env python import sys import re import shutil import os import os.path import string import xml.etree.ElementTree # Return codes C2M_ERR_SUCCESS = 0 C2M_ERR_INVALID_COMMANDLINE = -1 C2M_ERR_LOAD_TEMPLATE = -2 C2M_ERR_NO_PROJECT = -3 C2M_ERR_PROJECT_FILE = -4 C2M_ERR_IO = -5 C2M_ERR_NEED_UPDATE = -6 # Configuration # STM32 MCU to compiler flags. mcu_regex_to_cflags_dict = { 'STM32(F|L)0': '-mthumb -mcpu=cortex-m0', 'STM32(F|L)1': '-mthumb -mcpu=cortex-m3', 'STM32(F|L)2': '-mthumb -mcpu=cortex-m3', 'STM32(F|L)3': '-mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard', 'STM32(F|L)4': '-mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard', 'STM32(F|L)7': '-mthumb -mcpu=cortex-m7 -mfpu=fpv4-sp-d16 -mfloat-abi=hard', } def main(): if len(sys.argv) != 2: sys.stderr.write("\nSTM32CubeMX project to Makefile V2.0\n") sys.stderr.write("-==================================-\n") sys.stderr.write("Initially written by Baoshi on 2015-02-22\n") sys.stderr.write("Updated 2017-04-27 for STM32CubeMX 4.20.1 http://www.st.com/stm32cube\n") sys.stderr.write("Refer to history.txt for contributors, thanks!\n") sys.stderr.write("Apache License 2.0 \n") sys.stderr.write("\nUsage:\n") sys.stderr.write(" CubeMX2Makefile.py \n") sys.exit(C2M_ERR_INVALID_COMMANDLINE) # Load template files app_folder_path = os.path.dirname(os.path.abspath(sys.argv[0])) template_file_path = os.path.join(app_folder_path, 'CubeMX2Makefile.tpl') try: with open(template_file_path, 'r') as f: makefile_template = string.Template(f.read()) except EnvironmentError as e: sys.stderr.write("Unable to read template file: {}. Error: {}".format(template_file_path, str(e))) sys.exit(C2M_ERR_LOAD_TEMPLATE) proj_folder_path = os.path.abspath(sys.argv[1]) if not os.path.isdir(proj_folder_path): sys.stderr.write("STM32CubeMX \"Toolchain Folder Location\" not found: {}\n".format(proj_folder_path)) sys.exit(C2M_ERR_INVALID_COMMANDLINE) proj_name = os.path.splitext(os.path.basename(proj_folder_path))[0] ac6_project_path = os.path.join(proj_folder_path,'.project') ac6_cproject_path = os.path.join(proj_folder_path,'.cproject') if not (os.path.isfile(ac6_project_path) and os.path.isfile(ac6_cproject_path)): sys.stderr.write("SW4STM32 project not found, use STM32CubeMX to generate a SW4STM32 project first\n") sys.exit(C2M_ERR_NO_PROJECT) ctx = [] c_set = {} c_set['source_endswith'] = '.c' c_set['source_subst'] = 'C_SOURCES =' c_set['inc_endswith'] = '.h' c_set['inc_subst'] = 'C_INCLUDES =' c_set['first'] = True c_set['relpath_stored'] = '' ctx.append(c_set) asm_set = {} asm_set['source_endswith'] = '.s' asm_set['source_subst'] = 'ASM_SOURCES =' asm_set['inc_endswith'] = '.inc' asm_set['inc_subst'] = 'AS_INCLUDES =' asm_set['first'] = True asm_set['relpath_stored'] = '' ctx.append(asm_set) for path, dirs, files in os.walk(proj_folder_path): for file in files: for s in ctx: if file.endswith(s['source_endswith']): s['source_subst'] += ' \\\n ' relpath = os.path.relpath(path,proj_folder_path) #Split Windows style paths into tokens #Unix style path emit a single token relpath_split = relpath.split('\\') for path_tok in relpath_split: #Last token does not have a trailing slash if path_tok == relpath_split[0]: s['source_subst'] += path_tok else: s['source_subst'] += '/' + path_tok s['source_subst'] += '/' + file if file.endswith(s['inc_endswith']): relpath = os.path.relpath(path,proj_folder_path) #only include a path once if relpath != s['relpath_stored']: s['relpath_stored'] = relpath #If this is the first include, we already have the 'C_INCLUDES =' if s['first']: s['first'] = False s['inc_subst'] += ' -I' else: s['inc_subst'] += '\nC_INCLUDES += -I' #Split Windows style paths into tokens #Unix style path emit a single token relpath_split = relpath.split('\\') for path_tok in relpath_split: #Last token does not have a trailing slash if path_tok == relpath_split[0]: s['inc_subst'] += path_tok else: s['inc_subst'] += '/' + path_tok # .cproject file try: tree = xml.etree.ElementTree.parse(ac6_cproject_path) except Exception as e: sys.stderr.write("Unable to parse SW4STM32 .cproject file: {}. Error: {}\n".format(ac6_cproject_path, str(e))) sys.exit(C2M_ERR_PROJECT_FILE) conf = tree.find('.//configuration[@name="Debug"]') # MCU try: mcu_node = conf.find('.//option[@name="Mcu"]') mcu_str = mcu_node.attrib.get('value') #sys.stdout.write("For MCU: {}\n".format(mcu_str)) except Exception as e: sys.stderr.write("Unable to find target MCU node. Error: {}\n".format(str(e))) sys.exit(C2M_ERR_PROJECT_FILE) for mcu_regex_pattern, cflags in mcu_regex_to_cflags_dict.items(): if re.match(mcu_regex_pattern, mcu_str): cflags_subst = cflags ld_subst = cflags break else: sys.stderr.write("Unknown MCU: {}\n".format(mcu_str)) sys.stderr.write("Please contact author for an update of this utility.\n") sys.stderr.exit(C2M_ERR_NEED_UPDATE) # AS symbols as_defs_subst = 'AS_DEFS =' # C symbols c_defs_subst = 'C_DEFS =' c_def_node_list = conf.findall('.//tool[@name="MCU GCC Compiler"]/option[@valueType="definedSymbols"]/listOptionValue') for c_def_node in c_def_node_list: c_def_str = c_def_node.attrib.get('value') if c_def_str: c_defs_subst += ' -D{}'.format(re.sub(r'([()])', r'\\\1', c_def_str)) # Link script ld_script_node = conf.find('.//tool[@name="MCU GCC Linker"]/option[@superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.script"]') try: ld_script_path = ld_script_node.attrib.get('value') except Exception as e: sys.stderr.write("Unable to find link script. Error: {}\n".format(str(e))) sys.exit(C2M_ERR_PROJECT_FILE) ld_script_name = os.path.basename(ld_script_path) ld_script_subst = 'LDSCRIPT = {}'.format(ld_script_name) # Specs specs_node = conf.find('.//tool[@name="MCU GCC Linker"]/option[@superClass="gnu.c.link.option.ldflags"]') try: specs = specs_node.attrib.get('value') except Exception as e: sys.stderr.write("Unable to find link specs. Error: {}\n".format(str(e))) sys.exit(C2M_ERR_PROJECT_FILE) specs_subst = specs makefile_str = makefile_template.substitute( TARGET = proj_name, MCU = cflags_subst, LDMCU = ld_subst, C_SOURCES = c_set['source_subst'], ASM_SOURCES = asm_set['source_subst'], AS_DEFS = as_defs_subst, AS_INCLUDES = asm_set['inc_subst'], C_DEFS = c_defs_subst, C_INCLUDES = c_set['inc_subst'], LDSCRIPT = ld_script_subst, SPECS = specs_subst) makefile_path = os.path.join(proj_folder_path, 'Makefile') try: with open(makefile_path, 'wb') as f: f.write(makefile_str) except EnvironmentError as e: sys.stderr.write("Unable to write Makefile: {}. Error: {}\n".format(makefile_path, str(e))) sys.exit(C2M_ERR_IO) sys.stdout.write("Makefile created: {}\n".format(makefile_path)) sys.exit(C2M_ERR_SUCCESS) def fix_path(p): return re.sub(r'^..(\\|/)..(\\|/)..(\\|/)', '', p.replace('\\', os.path.sep)) if __name__ == '__main__': main() ================================================ FILE: CubeMX2Makefile.tpl ================================================ ###################################### # Makefile by CubeMX2Makefile.py ###################################### ###################################### # target ###################################### TARGET = $TARGET ###################################### # building variables ###################################### # debug build? DEBUG = 1 # optimization OPT = -O0 ####################################### # pathes ####################################### # Build path BUILD_DIR = build ###################################### # source ###################################### $C_SOURCES $ASM_SOURCES ####################################### # binaries ####################################### CC = arm-none-eabi-gcc AS = arm-none-eabi-gcc -x assembler-with-cpp CP = arm-none-eabi-objcopy AR = arm-none-eabi-ar SZ = arm-none-eabi-size HEX = $$(CP) -O ihex BIN = $$(CP) -O binary -S ####################################### # CFLAGS ####################################### # macros for gcc $AS_DEFS $C_DEFS # includes for gcc $AS_INCLUDES $C_INCLUDES # compile gcc flags ASFLAGS = $MCU $$(AS_DEFS) $$(AS_INCLUDES) $$(OPT) -Wall -fdata-sections -ffunction-sections CFLAGS = $MCU $$(C_DEFS) $$(C_INCLUDES) $$(OPT) -Wall -fdata-sections -ffunction-sections ifeq ($$(DEBUG), 1) CFLAGS += -g -gdwarf-2 endif # Generate dependency information CFLAGS += -std=c99 -MD -MP -MF $$(BUILD_DIR)/.dep/$$(@F).d ####################################### # LDFLAGS ####################################### # link script $LDSCRIPT # libraries LIBS = LIBDIR = LDFLAGS = $LDMCU $SPECS -T$$(LDSCRIPT) $$(LIBDIR) $$(LIBS) -Wl,-Map=$$(BUILD_DIR)/$$(TARGET).map,--cref -Wl,--gc-sections # default action: build all all: $$(BUILD_DIR)/$$(TARGET).elf $$(BUILD_DIR)/$$(TARGET).hex $$(BUILD_DIR)/$$(TARGET).bin ####################################### # build the application ####################################### # list of objects OBJECTS = $$(addprefix $$(BUILD_DIR)/,$$(notdir $$(C_SOURCES:.c=.o))) vpath %.c $$(sort $$(dir $$(C_SOURCES))) # list of ASM program objects OBJECTS += $$(addprefix $$(BUILD_DIR)/,$$(notdir $$(ASM_SOURCES:.s=.o))) vpath %.s $$(sort $$(dir $$(ASM_SOURCES))) $$(BUILD_DIR)/%.o: %.c Makefile | $$(BUILD_DIR) $$(CC) -c $$(CFLAGS) -Wa,-a,-ad,-alms=$$(BUILD_DIR)/$$(notdir $$(<:.c=.lst)) $$< -o $$@ $$(BUILD_DIR)/%.o: %.s Makefile | $$(BUILD_DIR) $$(AS) -c $$(CFLAGS) $$< -o $$@ $$(BUILD_DIR)/$$(TARGET).elf: $$(OBJECTS) Makefile $$(CC) $$(OBJECTS) $$(LDFLAGS) -o $$@ $$(SZ) $$@ $$(BUILD_DIR)/%.hex: $$(BUILD_DIR)/%.elf | $$(BUILD_DIR) $$(HEX) $$< $$@ $$(BUILD_DIR)/%.bin: $$(BUILD_DIR)/%.elf | $$(BUILD_DIR) $$(BIN) $$< $$@ $$(BUILD_DIR): mkdir -p $$@/.dep ####################################### # clean up ####################################### clean: -rm -fR $$(BUILD_DIR) ####################################### # dependencies ####################################### -include $$(shell mkdir -p $$(BUILD_DIR)/.dep 2>/dev/null) $$(wildcard $$(BUILD_DIR)/.dep/*) .PHONY: clean all # *** EOF *** ================================================ FILE: history.txt ================================================ 2015-02-22: V1.0 Initial release, based on STM32CubeMX 4.6.0 2015-10-03: V1.5 Updated with STM32CubeMX 4.10.1 Use SW4STM32 instead of TrueStudio 2015-10-04: Delete obsolete CubeMX2LD.tpl For Linux users (thanks to xaionaro) CubeMX2Makefile.py now uses UNIX format (so you can execute directly under Linux) Fix link script path issue ST has some upper/lower case issues in their source code which prevent the code to be compiled under Linux. These has to be fixed manually. 2016-02-24: Merge PR from rogerdahl (Better Python and fix stray '\'s) Update for STM32CubeMX 4.13.0 2016-05-13: Update for STM32CubeMX 4.14.0 (ST removed all source reference in project file) Merge PR from mmprestine and madcowswe (Walk the project folder for source files) 2016-07-14: Merged PR from madcowswe (again) for STM32CubeMX 4.15.1 changes. 2017-04-24 Merged PRs Update for STM32CubeMX 4.20.1 ================================================ FILE: readme.md ================================================ # STM32CubeMX to Makefile ## With the release of STM32CubeMX 4.21.0, generating Makefile (which is very similar to my template) is natively supported. I will retire this utility unless ST changes their mind. This program generates a Makefile from STM32CubeMX (http://www.st.com/stm32cube) created project. It is intended to be used along with GNU Make utility (www.gnu.org/software/make) and GNU tools for ARM (https://launchpad.net/gcc-arm-embedded) to compile STM32 firmware. Refer to my blog post http://www.ba0sh1.com/opensource-stm32-development for setup of integrated development environment. Copyright (c) 2016, Baoshi Zhu. All rights reserved. Source code in this project is governed by Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)