Last active
December 29, 2020 22:30
-
-
Save roberthartung/164788137759fea98868 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import sys | |
import os | |
import glob | |
import subprocess | |
import getopt | |
def parse_project_option(keys, value, target): | |
key = keys.pop(0) | |
if(len(keys) >= 1): # still more than one element in list | |
if(not target.has_key(key)): | |
target[key] = {} | |
parse_project_option(keys, value, target[key]) | |
else: | |
target[key] = value | |
def print_help(): | |
print("Usage: " + sys.argv[0] + " [--cpp] [-d|--debug] [-r|--relative] Project_Directory") | |
sys.exit() | |
def make_path(path): | |
if use_relative_paths: | |
return path[len(project_directory)+1:] | |
else: | |
return path | |
has_cpp = False | |
has_debug = False | |
use_relative_paths = False | |
use_11 = False | |
opts, args = getopt.getopt(sys.argv[1:],"hp:dr",["cpp", "debug", "relative", "use11"]) | |
if len(args) < 1: | |
print_help(); | |
for opt, arg in opts: | |
if opt == "-h": | |
print_help() | |
elif opt == "--cpp": | |
has_cpp = True | |
elif opt == "--debug" or opt == "-d": | |
has_debug = True | |
elif opt == "--relative" or opt == "-r": | |
use_relative_paths = True | |
elif opt == "use11": | |
use_11 = True | |
else: | |
print opt, "=", arg | |
project_directory = os.path.abspath(args[0]) | |
if (not os.path.exists(project_directory)): | |
sys.exit("Project directory " + project_directory + " does not exist!") | |
eoc_file = glob.glob(os.path.join(project_directory, "*.ioc")) | |
if(len(eoc_file) == 0): | |
sys.exit("Unable to find project file (*.ioc)") | |
eoc_file = eoc_file[0] | |
project_settings = {} | |
with open(eoc_file, 'r') as fh: | |
for line in fh: | |
data = line.strip().split("=") | |
if(len(data) != 2): | |
continue | |
[key, value] = data | |
parse_project_option(key.split('.'), value, project_settings) | |
fh.close() | |
processor = project_settings['Mcu']['UserName'] | |
processor_line = processor[:7] # STM32FX | |
processor_family = processor[:9] # STM32FXXX | |
print "Generating Makefile for Project Directory", project_directory, " Processor: ", processor, "(", processor_line, "/", processor_family, ")" | |
process = subprocess.Popen(['arm-none-eabi-gcc', '--print-sysroot'], stdout=subprocess.PIPE) | |
process.wait() | |
if (not process.returncode == 0): | |
sys.exit("arm-none-eabi-gcc not found! Please add it to your PATH.") | |
compiler_root = os.path.abspath(process.communicate()[0].strip()) | |
print("arm-none-eabi-gcc sysroot at " + compiler_root) | |
# Buffer for targets to write to Makefile | |
targets = "" | |
filename = os.path.join(project_directory, "Makefile") | |
#""" + ('g++' if has_cpp else 'gcc') +""" | |
with open(filename, 'w+') as fh: | |
# write header | |
fh.write("""# | |
# Automatically generated - Do not change! | |
# | |
CC=arm-none-eabi-gcc | |
CXX=arm-none-eabi-g++ | |
LD=arm-none-eabi-lc | |
AS=arm-none-eabi-as | |
OBJ=arm-none-eabi-objcopy | |
COMPILER_SYSROOT=$(shell $(CC) -print-sysroot) | |
SEP="""+("\\\\" if os.sep == "\\" else os.sep)+""" | |
# -g3 | |
CFLAGS="""+('-g ' if has_debug else '')+('-std=c11 ' if use_11 else '')+"""-mcpu=cortex-m3 -mthumb -mfloat-abi=soft -DUSE_HAL_DRIVER -D"""+processor_family+"""xx -Wall -fmessage-length=0 -ffunction-sections | |
CXXFLAGS="""+('-g ' if has_debug else '')+('-std=c++11 ' if use_11 else '')+"""-mcpu=cortex-m3 -mthumb -mfloat-abi=soft -DUSE_HAL_DRIVER -D"""+processor_family+"""xx -Wall -fmessage-length=0 -ffunction-sections | |
LFLAGS="""+('-g ' if has_debug else '')+"""-mcpu=cortex-m3 -mthumb -mfloat-abi=soft -specs=nosys.specs -specs=nano.specs -Wl,-Map=output.map -Wl,--gc-sections -lm | |
LIBS= | |
CFLAGS += -I\"$(COMPILER_SYSROOT)$(SEP)include\" | |
CXXFLAGS += -I\"$(COMPILER_SYSROOT)$(SEP)include\" | |
""") | |
# \"""" + os.path.join(compiler_root, "include") + """\" | |
fh.write("BUILD_DIR="+make_path(os.path.join(project_directory, "build"))+"\n") | |
if (os.name == "nt"): | |
fh.write("SHELL=C:/Windows/System32/cmd.exe\n") | |
fh.write("RM=del /S\n") | |
else: | |
fh.write("RM=rm -rf\n") | |
fh.write("""USER_DIR="""+make_path(os.path.join(project_directory, "User"))+""" | |
-include $(USER_DIR)/Makefile | |
"""); | |
path_drivers = os.path.join(project_directory, "Drivers") | |
path_hal = os.path.join(path_drivers, "*HAL_Driver") | |
path_cmsis = os.path.join(path_drivers, "CMSIS") | |
path_cmsis_device = os.path.join(path_cmsis, "Device", "ST", processor_line + "xx") | |
path_src = os.path.join(project_directory, "Src") | |
path_cmsis_src = os.path.join(path_cmsis, "Src") | |
path_hal_src = os.path.join(path_hal, "Src") | |
path_cmsis_device_source = os.path.join(path_cmsis_device, "Source") | |
path_cmsis_device_templates = os.path.join(path_cmsis_device_source, "Templates") | |
path_inc = os.path.join(project_directory, "Inc") | |
path_cmsis_include = os.path.join(path_cmsis, "Include") | |
path_hal_inc = os.path.join(path_hal, "Inc") | |
path_cmsis_device_include = os.path.join(path_cmsis_device, "Include") | |
path_configuration = os.path.join(project_directory, "SW4STM32", "*Configuration") | |
# path_startup = os.path.join() | |
source_files = [] | |
header_files = [] | |
include_paths = set() | |
objects = [] | |
source_files += glob.glob(os.path.join(path_src, "*.c")) # "Src" + os.pathsep + "*.c" | |
source_files += glob.glob(os.path.join(path_hal_src, "*.c")) # project_directory + "Drivers" + os.pathsep + "*HAL_Driver" + os.pathsep + "Src" + os.pathsep + "*.c" | |
source_files += glob.glob(os.path.join(path_cmsis_device_source, "*.c")) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Device" + os.pathsep + "ST" + os.pathsep +processor_family+"xx" + os.pathsep + "Source" + os.pathsep + "*.c" | |
source_files += glob.glob(path_cmsis_src) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Source" + os.pathsep + "*.c" | |
source_files += glob.glob(os.path.join(path_cmsis_device_templates, "*.c")) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Device" + os.pathsep + "ST" + os.pathsep + ""+processor_family+"xx" + os.pathsep + "Source" + os.pathsep + "Templates" + os.pathsep + "system_stm32*.c" | |
for f in glob.glob(os.path.join(path_hal_src, "*_template.c")): | |
source_files.remove(f) | |
header_files += glob.glob(os.path.join(path_inc, "*.h")) # project_directory + "Inc" + os.pathsep + "*.h" | |
header_files += glob.glob(os.path.join(path_hal_inc, "*.h")) # project_directory + "Drivers" + os.pathsep + "*HAL_Driver" + os.pathsep + "Inc" + os.pathsep + "*.h" | |
header_files += glob.glob(os.path.join(path_cmsis_device_include, "*.h")) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Device" + os.pathsep + "ST" + os.pathsep + ""+processor_family+"xx" + os.pathsep + "Include" + os.pathsep + "*.h" | |
header_files += glob.glob(os.path.join(path_cmsis_include, "*.h")) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Include" + os.pathsep + "*.h" | |
header_files += glob.glob(os.path.join(path_cmsis_device_include, "system_stm32*.h")) # project_directory + "Drivers" + os.pathsep + "CMSIS" + os.pathsep + "Device" + os.pathsep + "ST" + os.pathsep + ""+processor_family+"xx" + os.pathsep + "Include" + os.pathsep + "system_stm32*.h" | |
linker_files = glob.glob(os.path.join(path_configuration, "*.ld")) | |
for linker_file in linker_files: | |
fh.write("LFLAGS+= -T\""+make_path(linker_file)+"\"\n") | |
for header_file in header_files: | |
include_paths.add(make_path(os.path.dirname(header_file))) | |
for p in source_files: | |
f = os.path.basename(p) | |
object_name = (f[:-2]) + ".o" | |
objects += ["$(BUILD_DIR)/"+object_name] | |
targets += "$(BUILD_DIR)/"+object_name + ": " + make_path(p) + "\n" + "\t$(CC) $(CFLAGS) -o $@ -c $<" + "\n\n" | |
startup_files = glob.glob(os.path.join(path_cmsis_device_templates, "gcc", "startup_"+processor_family.lower()+"xx.s")) | |
if (not len(startup_files) == 1): | |
print "WARNING: No startup file found!" | |
else: | |
objects += ["$(BUILD_DIR)/startup.o"] | |
targets += "$(BUILD_DIR)/startup.o : " + make_path(startup_files[0]) + "\n" + "\t" + "$(AS) -mcpu=cortex-m3 -mthumb -mfloat-abi=soft -o $@ $<\n\n" | |
targets += "all: $(BUILD_DIR)/project.bin\n\techo \"Making all\"\n\n" | |
targets += "$(BUILD_DIR)/project.elf: $(OBJECTS)\n" + "\t" + "$("+('CXX' if has_cpp else 'CC')+") $(LFLAGS) -o $@ $+\n\n" | |
targets += "$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf\n" + "\t" + "$(OBJ) -O binary $< $@\n\n" | |
targets += "%.upload: %.bin\n" + "\t" + "st-flash --reset write $< 0x08000000\n\n" | |
if (os.name == "nt"): | |
targets += "clean:\n\t$(RM) $(BUILD_DIR)$(SEP)*.o $(BUILD_DIR)$(SEP)*.elf $(BUILD_DIR)$(SEP)*.bin" | |
else: | |
targets += "clean:\n\t$(RM) $(BUILD_DIR)$(SEP)*.o $(BUILD_DIR)$(SEP)*.elf $(BUILD_DIR)$(SEP)*.bin" | |
for path in include_paths: | |
fh.write("CFLAGS+=-I\""+path+"\"\n") | |
fh.write("CXXFLAGS+=-I\""+path+"\"\n") | |
fh.write("OBJECTS+="+" ".join(objects)+"\n") | |
fh.write("""$(OBJECTS) : | $(BUILD_DIR) | |
$(BUILD_DIR): | |
\tmkdir -p $(BUILD_DIR) | |
""") | |
fh.write(targets) | |
fh.close() | |
print("Done.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment