Commit ca7a3644 authored by Jason Tran's avatar Jason Tran
Browse files

closes G#10: Add clang format tool

parent 7eda501e
......@@ -11,7 +11,7 @@ Setup and install should be super simple unless you have Windows, which is not s
2. Open up a terminal window or command prompt, and install `scons`:
* Type `pip install scons`
* If any issues on Ubuntu(Linux), try `sudo apt install scons`
3. Install the Board driver from the `drivers` directory
3. Install the Board driver from the `installs/drivers` directory
That is it, you should now be ready to build software for your board.
......
......@@ -2,6 +2,13 @@ import sys
import fsops
import osops
from sources import Sources
"""
CLI
"""
no_format = GetOption("no_format")
"""
Imports
......@@ -45,6 +52,11 @@ Import build environment
SConscript(REPO_ROOT_DIR.File("env_arm"))
Import("env_arm")
""" Add/modify additional parameters """
env_arm = env_arm.Clone(
tools=["clangformat"]
)
if osops.is_windows():
print("-- Using ARM compiler on WINDOWS")
osops.prepend_env_var(env_arm, REPO_ROOT_DIR.Dir("compiler/windows/gcc-arm-none-eabi-8-2019-q3-update/bin"))
......@@ -70,26 +82,27 @@ env_arm["LINKFLAGS"] += [
"""
Search and group files to build
"""
all_sources = Sources()
""" Search and group source files and source directories """
target_source_filenodes = []
for dir in SRC_DIRS_ROOT:
sources = fsops.scan_tree(dir)
target_source_filenodes.extend(sources.source_filenodes)
all_sources += sources
""" Group linker scripts """
for linker_file in LINKER_FILES:
env_arm["LINKFLAGS"].append("-T{}".format(File(linker_file).abspath))
""" Search and group include paths """
env_arm["CPPPATH"].extend(INCLUDE_DIRS)
for dir in INCLUDE_DIRS_ROOT:
sources = fsops.scan_tree(dir)
env_arm["CPPPATH"].extend(sources.include_dirnodes)
all_sources += sources
env_arm["CPPPATH"].extend(INCLUDE_DIRS)
env_arm["CPPPATH"].extend(all_sources.include_dirnodes)
""" Filter build files """
target_source_filenodes = fsops.filter_files(target_source_filenodes, EXCLUDED_SRC_FILES)
target_source_filenodes = fsops.remove_duplicate_filenodes(target_source_filenodes)
all_sources.source_filenodes = fsops.filter_files(all_sources.source_filenodes, EXCLUDED_SRC_FILES)
all_sources.source_filenodes = fsops.remove_duplicate_filenodes(all_sources.source_filenodes)
"""
......@@ -98,9 +111,9 @@ Perform builds
""" Compile all sources -> objects """
obj_filenodes = []
for src_filenode in target_source_filenodes:
dest_filepath = fsops.ch_target_filenode(src_filenode, OBJ_DIR, "o")
new_obj_filenodes = env_arm.Object(target=dest_filepath, source=src_filenode)
for source_filenode in all_sources.source_filenodes:
dest_filepath = fsops.ch_target_filenode(source_filenode, OBJ_DIR, "o")
new_obj_filenodes = env_arm.Object(target=dest_filepath, source=source_filenode)
obj_filenodes.extend(new_obj_filenodes)
elf_filenodes = env_arm.Program(target=VARIANT_DIR.File("{}.elf".format(PROJECT_DIR.name)), source=obj_filenodes)
......@@ -110,3 +123,28 @@ lst_filenodes = env_arm.Objdump(target=VARIANT_DIR.File("{}.lst".format(PROJECT_
size_filenodes = env_arm.Size(target=VARIANT_DIR.File("{}.size".format(PROJECT_DIR.name)), source=elf_filenodes)
Depends(elf_filenodes, LINKER_FILES)
"""
Automatically format all files
"""
FORMAT_EXCLUDED_FILES = [
PROJECT_DIR.File("lpc40xx.h"),
]
FORMAT_EXCLUDED_DIRS = [
PROJECT_DIR.Dir("l0_lowlevel/arm-software"),
PROJECT_DIR.Dir("l1_freertos"),
PROJECT_DIR.Dir("l4_io/fatfs"),
]
format_filenodes = fsops.filter_files(
filenodes=(all_sources.source_filenodes + all_sources.include_filenodes),
exclude_filenodes=FORMAT_EXCLUDED_FILES,
exclude_dirnodes=FORMAT_EXCLUDED_DIRS,
)
# If "--no-format" provided as command line argument, then do not run Clang Format builders
if not no_format:
for filenode in format_filenodes:
env_arm.ClangFormat(filenode=filenode)
......@@ -21,3 +21,11 @@ If you successfully installed using the steps above, then you do not have to fol
1. Extract the zip file
2. `cd` into the zip file and then `python setup.py install`
## Clang Format (Windows only)
Clang Format for Windows may require VC runtime libraries. Install `vc_redistx64.exe` if you encounter the error:
```
The program can't start because MSVCP140.dll is missing from your computer.
```
......@@ -7,3 +7,4 @@ from SCons.Script import *
def cli_init():
AddOption("--verbose", dest="verbose", action="store_true", default=False)
AddOption("--no-format", dest="no_format", action="store_true", default=False)
......@@ -10,7 +10,6 @@ from SCons.Script import *
from sources import Sources
DEFAULT_SOURCE_PATTERNS = ["*.c", "*.cpp"]
DEFAULT_INCLUDE_PATTERNS = ["*.h", "*.hpp"]
DEFAULT_ASSEMBLY_PATTERNS = ["*.s", "*.S"]
......@@ -68,19 +67,21 @@ def scan_tree(
return sources
def filter_files(filenodes, exclude_filenodes=None, exclude_filename_pattern=None):
def filter_files(filenodes, exclude_filenodes=None, exclude_dirnodes=None, exclude_filename_pattern=None):
"""
Filter file nodes
:param filenodes: A list of file nodes (list of File)
:param exclude_filenodes: A list of file nodes to filter out (list of File)
:param exclude_dirnodes: A list of directory nodes to filter out (list of Dir)
:param exclude_filename_pattern: A file name pattern to filter out files with a matching file name pattern (str)
:return: A list of filtered file nodes (list of File)
"""
if exclude_filenodes is None:
exclude_filenodes = []
exclude_filenodes = exclude_filenodes if (exclude_filenodes is not None) else []
exclude_dirnodes = exclude_dirnodes if (exclude_dirnodes is not None) else []
filenodes = list(map(File, filenodes))
exclude_filenodes = list(map(File, exclude_filenodes))
exclude_dirnodes = list(map(Dir, exclude_dirnodes))
filtered_filenodes = []
filtered_filenodes.extend(list(filter(lambda filenode: filenode not in exclude_filenodes, filenodes)))
......@@ -88,6 +89,16 @@ def filter_files(filenodes, exclude_filenodes=None, exclude_filename_pattern=Non
if exclude_filename_pattern is not None:
filtered_filenodes.extend(list(filter(lambda filenode: not fnmatch(filenode.name, exclude_filename_pattern), filtered_filenodes)))
new_filtered_filenodes = []
if exclude_dirnodes is not None:
for filenode in filtered_filenodes:
for dirnode in exclude_dirnodes:
if dirnode.abspath in filenode.abspath:
break
else:
new_filtered_filenodes.append(filenode)
filtered_filenodes = new_filtered_filenodes
return filtered_filenodes
......
......@@ -33,7 +33,7 @@ def is_windows():
def is_linux():
return "linux" in sys.platform
return sys.platform.startswith("linux")
def is_macos():
......
"""
LLVM Clang Format
"""
import os
import subprocess
from SCons.Script import *
import osops
SELF_DIRNODE = Dir(os.path.dirname(__file__))
"""
SCons tools functions
"""
def generate(env):
env.AddMethod(clang_format_method, "ClangFormat")
def exists():
return True
"""
Environment functions
"""
def clang_format_method(self, filenode):
"""
Perform auto formatter against an input file.
Note, this operation will change the contents in the source file.
:param filenode: Source or header file to be formatted (File)
:return: Results
"""
filenode = File(filenode)
clang_format_binary_filenode = get_clang_format_binary_filenode()
# cmd = "{} -i={}".format(clang_format_binary_filenode.abspath, filenode.abspath)
cmd = [
clang_format_binary_filenode.abspath,
"-i",
filenode.abspath,
]
print(" ".join(cmd))
subprocess.call(cmd)
"""
Helper functions
"""
def get_clang_format_binary_filenode():
clang_format_filename = "clang-format"
if osops.is_windows():
ret = SELF_DIRNODE.File("win64/clang-format.exe")
elif osops.is_macos():
ret = SELF_DIRNODE.File("mac/clang-format")
else: # osops.is_linux()
ret = SELF_DIRNODE.File("linux/clang-format")
return ret
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment