summaryrefslogtreecommitdiff
path: root/util/ide-config.sh
diff options
context:
space:
mode:
Diffstat (limited to 'util/ide-config.sh')
-rwxr-xr-xutil/ide-config.sh475
1 files changed, 0 insertions, 475 deletions
diff --git a/util/ide-config.sh b/util/ide-config.sh
deleted file mode 100755
index 25edca2407..0000000000
--- a/util/ide-config.sh
+++ /dev/null
@@ -1,475 +0,0 @@
-#!/bin/bash
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Usage: ./util/ide-config.sh vscode all all:RO | tee .vscode/c_cpp_properties.json
-# This tool needs to be run from the base ec directory.
-#
-# Future works should be put towards adding new IDE generators and adding
-# mechanism for passing IDE specific parameters to the IDE generator.
-
-DEFAULT_IMAGE=RW
-INDENT_WIDTH=${INDENT_WIDTH:-1}
-INDENT_CHAR=${INDENT_CHAR:-$'\t'}
-INCLUDES_DROP_ROOT=${INCLUDES_DROP_ROOT:-false}
-PARALLEL_CACHE_FILL=${PARALLEL_CACHE_FILL:-true}
-FORCE_INCLUDE_CONFIG_H=${FORCE_INCLUDE_CONFIG_H:-false}
-# JOB_BATCH_SIZE is the number of jobs allowed to spawn at any given point.
-# This is an inefficient manner of resource management, but at least it
-# throttles process creation. Due to the low utilization or each job,
-# multiply the number of real processors by 2.
-JOB_BATCH_SIZE=${JOB_BATCH_SIZE:-$(($(nproc) * 2))}
-
-MAKE_CACHE_DIR=""
-
-init() {
- MAKE_CACHE_DIR=$(mktemp -t -d ide-config.XXXX)
- mkdir -p "${MAKE_CACHE_DIR}/defines"
- mkdir -p "${MAKE_CACHE_DIR}/includes"
- trap deinit EXIT
-}
-
-deinit() {
- rm -rf "${MAKE_CACHE_DIR}"
-}
-
-usage() {
- cat <<-HEREDOC
- Usage: ide-config.sh <vscode|eclipse> [BOARD:IMAGE] [BOARD:IMAGE...]
- Generate a C language configuration for a given IDE and EC board.
-
- Examples:
- ide-config.sh vscode all:RW all:RO | tee .vscode/c_cpp_properties.json
- ide-config.sh vscode nocturne # implicitly :RW
- ide-config.sh vscode nocturne_fp:RO
- ide-config.sh vscode nocturne:RO hatch:RW
- ide-config.sh vscode all # implicitly :RW
- ide-config.sh eclipse nocturne_fp > ~/Downloads/nocturne_fp-RW.xml
- HEREDOC
-}
-
-# Usage: iprintf <indent-level> <printf-fmt> [printf-args...]
-iprintf() {
- local level=$1
- shift
-
- local n=$((INDENT_WIDTH*level))
- if [[ $n -ne 0 ]]; then
- eval printf '"${INDENT_CHAR}%.0s"' "{1..$n}"
- fi
- # shellcheck disable=SC2059
- printf "$@"
- return $?
-}
-
-# Usage: parse-cfg-board <cfg-string>
-#
-# Example: parse-cfg-board nocturne:RW
-parse-cfg-board() {
- local cfg=$1
- # Remove possible :RW or :RO
- local board=${cfg%%:*}
- if [[ -z ${board} ]]; then
- return 1
- fi
- echo "${board}"
-}
-
-# Usage: parse-cfg-image <cfg-string>
-#
-# Example: parse-cfg-image nocturne:RW
-# Example: parse-cfg-image nocturne
-parse-cfg-image() {
- local cfg=$1
-
- local board
- if ! board=$(parse-cfg-board "${cfg}"); then
- return 1
- fi
- # Remove known board part
- cfg=${cfg#${board}}
- cfg=${cfg#":"}
- # Use default image if none set
- cfg=${cfg:-${DEFAULT_IMAGE}}
-
- case ${cfg} in
- RW|RO)
- echo "${cfg}"
- return 0
- ;;
- *)
- return 1
- ;;
- esac
-}
-
-# Usage: make-defines <board> <RO|RW>
-make-defines() {
- local board=$1
- local image=$2
-
- local cache="${MAKE_CACHE_DIR}/defines/${board}-${image}"
-
- if [[ ! -f "${cache}" ]]; then
- make print-defines BOARD="${board}" BLD="${image}" >"${cache}"
- fi
-
- cat "${cache}"
-}
-
-# Usage: make-includes <board> <RO|RW>
-#
-# Rerun a newline separated list of include directories relative to the ec's
-# root directory.
-make-includes() {
- local board=$1
- local image=$2
-
- local cache="${MAKE_CACHE_DIR}/includes/${board}-${image}"
-
- if [[ ! -f "${cache}" ]]; then
- make print-includes BOARD="${board}" BLD="${image}" \
- | xargs realpath --relative-to=. \
- | {
- if [[ "${INCLUDES_DROP_ROOT}" == true ]]; then
- grep -v "^\.$"
- else
- cat
- fi
- } >"${cache}"
- fi
-
- cat "${cache}"
-}
-
-# Usage: make-boards
-make-boards() {
- local cache="${MAKE_CACHE_DIR}/boards"
-
- if [[ ! -f "${cache}" ]]; then
- make print-boards >"${cache}"
- fi
-
- cat "${cache}"
-}
-
-# Usage: <newline-list> | join <left> <right> <separator>
-#
-# JSON: includes nocturne_fp RW | join '"' '"' ',\n'
-# C: includes nocturne_fp RW | join '"' '",' '\n'
-join() {
- local left=$1
- local right=$2
- local sep=$3
-
- local first=true
- while read -r line; do
- # JSON is ridiculous for not allowing a trailing ,
- if [[ "${first}" == true ]]; then
- first=false
- else
- printf "%b" "${sep}"
- fi
- printf "%b%s%b" "${left}" "${line}" "${right}"
- done
- echo
-}
-
-# Usage: <content> | encap <header> <footer> [indent]
-#
-# Encapsulate the content from stdin with a header, footer, and indentation.
-encap() {
- local header=$1
- local footer=$2
- local indent=${3:-0}
-
- iprintf "${indent}" "%b" "${header}"
- while IFS="" read -r line; do
- iprintf $((1+indent)) "%s\n" "${line}"
- done
- iprintf "${indent}" "%b" "${footer}"
-}
-
-##########################################################################
-
-# Usage: vscode [cfg...]
-#
-# Generate the content for one c_cpp_properties.json that contains
-# multiple selectable configurations for each board-image pair.
-# In VSCode you can select the config in the bottom right, next to the
-# "Select Language Mode". You will only see this option when a C/C++ file
-# is open. Additionally, you can select a configuration by pressing
-# Ctrl-Shift-P and selecting the "C/C++ Select a Configuration..." option.
-vscode() {
- local first=true
- {
- for cfg; do
- local board image
- if ! board=$(parse-cfg-board "${cfg}"); then
- echo "Failed to parse board from cfg '${cfg}'"
- return 1
- fi
- if ! image=$(parse-cfg-image "${cfg}"); then
- echo "Failed to parse image from cfg '${cfg}'"
- return 1
- fi
- {
- printf '"name": "%s",\n' "${board}:${image}"
- make-includes "${board}" "${image}" \
- | join '"' '"' ',\n' \
- | encap '"includePath": [\n' '],\n'
- make-defines "${board}" "${image}" \
- | join '"' '"' ',\n' \
- | encap '"defines": [\n' '],\n'
-
- if [[ "${FORCE_INCLUDE_CONFIG_H}" == true ]]; then
- echo '"include/config.h"' \
- | encap '"forcedInclude": [\n' '],\n'
- fi
-
- echo '"compilerPath": "/usr/bin/arm-none-eabi-gcc",'
- # echo '"compilerArgs": [],'
- # The macro __STDC_VERSION__ is 201710L, which corresponds to c18.
- # VSCode doesn't have a C18 option, so go with C17. Since we seem
- # to use a lot of GNUC features, let's go with gnu17 instead of c17.
- echo '"cStandard": "gnu17",'
- # echo '"cppStandard": "c++17",'
- echo '"intelliSenseMode": "gcc-x64"'
- } | {
- # A single named configuration
- if [[ "${first}" == true ]]; then
- encap '{\n' '}'
- else
- encap ',\n{\n' '}'
- fi
- }
- first=false
- done
- echo
- } \
- | {
- encap '"configurations": [\n' '],\n'
- echo '"version": 4'
- } \
- | encap '{\n' '}\n'
-}
-
-# Usage: eclipse-cdt-import [cfg...]
-#
-# * Add odd EC "File Types"
-# - *.tasklist *.mocklist *.testlist *.irqlist "C Header File"
-# - *.inc "C Header File"
-# - gpio.wrap "C Header File"
-# * Enable the indexer to follow current build configuration
-# - Enable "Index all header variants"
-# - Enable "Use active build configuration" (ensure this options sticks)
-# - Probably bump up the Cache Limit->"Absolute Limit"
-# * Remove default system includes
-# - Depending on your eclipse toolchain configuration, it may be possible
-# to remove the standard C headers.
-# This helps satisfy the EC's -nostdinc usage.
-eclipse-cdt-import() {
- if [[ $# -gt 1 ]]; then
- echo "Error - eclipse generator can only process one board cfg" >&2
- return 1
- fi
-
- local cfg=$1
- local board image
-
- board=$(parse-cfg-board "${cfg}")
- image=$(parse-cfg-image "${cfg}")
-
- local includes
- # Grab workspace/project local paths
- includes+="$(make-includes "${board}" "${image}" | grep -v "^\.\." \
- | join '<includepath workspace_path="true">' '</includepath>' '\n\t\t\t')"
- # Add separator manually
- includes+="$(printf "\n\t\t\t")"
- # Grab external paths (wil start with .. because forced relative)
- # shellcheck disable=SC2016
- includes+="$(make-includes "${board}" "${image}" | grep "^\.\." \
- | join '<includepath>${ProjDirPath}/' '</includepath>' '\n\t\t\t')"
-
- local macros
- macros="$(
- while read -r name value; do
- {
- join '<name>' '</name>' '' <<<"${name}"
- join '<value>' '</value>' '' <<<"${value}"
- } | encap '<macro>\n' '</macro>\n' 3
- done < <(make-defines "${board}" "${image}" | tr '=' '\t')
- )"
-
- cat <<EOF
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated for ${board}:${image} -->
-<cdtprojectproperties>
- <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths">
- <!-- Start Normal CDT -->
- <language name="holder for library settings"></language>
-
- <language name="Assembly">
- ${includes}
- </language>
-
- <language name="GNU C++">
- ${includes}
- </language>
-
- <language name="GNU C">
- ${includes}
- </language>
- <!-- End Normal CDT -->
-
- <!-- Start CDT Cross/Embedded -->
- <language name="C Source File">
- ${includes}
- </language>
-
- <language name="Object File">
- </language>
-
- <language name="Assembly Source File">
- ${includes}
- </language>
- <!-- End CDT Cross/Embedded -->
- </section>
-
- <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
- <!-- Start Normal CDT -->
- <language name="holder for library settings"></language>
-
- <language name="Assembly">
-${macros}
- </language>
-
- <language name="GNU C++">
-${macros}
- </language>
-
- <language name="GNU C">
-${macros}
- </language>
- <!-- End Normal CDT -->
-
- <!-- Start CDT Cross/Embedded -->
- <language name="C Source File">
-${macros}
- </language>
-
- <language name="Object File">
- </language>
-
- <language name="Assembly Source File">
-${macros}
- </language>
- <!-- End CDT Cross/Embedded -->
- </section>
-</cdtprojectproperties>
-EOF
-}
-
-# Usage: main <ide> [cfgs...]
-main() {
- # Disaply help if no args
- if [[ $# -lt 1 ]]; then
- usage
- exit 1
- fi
- # Search for help flag
- for flag; do
- case ${flag} in
- help|--help|-h)
- usage
- exit 0
- ;;
- esac
- done
-
- local ide=$1
- shift
-
- # Expand possible "all" cfgs
- local board image
- local -a cfgs=( )
- for cfg; do
- # We parse both board and image to pre-sanatize the input
- if ! board=$(parse-cfg-board "${cfg}"); then
- echo "Failed to parse board from cfg '${cfg}'" >&2
- exit 1
- fi
- if ! image=$(parse-cfg-image "${cfg}"); then
- echo "Failed to parse image from cfg '${cfg}'" >&2
- exit 1
- fi
- # Note "all:*" could be specified multiple times for RO and RW
- # Note "all:*" could be specified with other specific board:images
- if [[ "${board}" == all ]]; then
- local -a allboards=( )
- mapfile -t allboards < <(make-boards)
- cfgs+=( "${allboards[@]/%/:${image}}" )
- else
- cfgs+=( "${cfg}" )
- fi
- done
-
- # Technically, we have not sanitized the cfgs generated from
- # "all" expression.
-
- # Make configs unique (and sorted)
- mapfile -t cfgs < <(echo "${cfgs[@]}" | tr ' ' '\n' | sort -u)
- echo "# Generating a config for the following board:images: " >&2
- echo "${cfgs[@]}" | tr ' ' '\n' | sort -u | column >&2
-
- # Prefill the make cache in parallel
- # This is important because each make request take about 700ms.
- # When running on all boards, this could result in (127*2)*700ms = 3mins.
- if [[ "${PARALLEL_CACHE_FILL}" == true ]]; then
- echo "# Fetching make defines and includes. Please wait." >&2
-
- # We run into process limits if we launch all processes at the
- # same time, so we must split them in half.
- # This need some jobserver management.
-
- # Run make for RWs and ROs
- local -i jobs=0
- for cfg in "${cfgs[@]}"; do
- if ! board="$(parse-cfg-board "${cfg}")"; then
- echo "Failed to parse board from cfg '${cfg}'" >&2
- exit 1
- fi
- if ! image="$(parse-cfg-image "${cfg}")"; then
- echo "Failed to parse image from cfg '${cfg}'" >&2
- exit 1
- fi
- make-defines "${board}" "${image}" >/dev/null &
- ((++jobs % JOB_BATCH_SIZE == 0)) && wait
- make-includes "${board}" "${image}" >/dev/null &
- ((++jobs % JOB_BATCH_SIZE == 0)) && wait
- done
- wait
- fi
-
- # Run the IDE's generator
- case "${ide}" in
- vscode)
- vscode "${cfgs[@]}" || exit $?
- ;;
- eclipse)
- eclipse-cdt-import "${cfgs[@]}" || exit $?
- ;;
- *)
- echo "Error - IDE '${ide}' is an unsupported." >&2
- exit 1
- ;;
- esac
-}
-
-init
-
-# Only start if not being sourced
-if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then
- main "$@"
-fi