Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roberthartung/164788137759fea98868 to your computer and use it in GitHub Desktop.
Save roberthartung/164788137759fea98868 to your computer and use it in GitHub Desktop.
#!/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