initial buildroot for linux 5.15
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# Impersonate a Linux system. Afterall, that's what we are...
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM ${CMAKE_SYSTEM_NAME})
|
||||
include(Platform/Linux)
|
||||
|
||||
# Override problematic settings, to avoid RPATH against host lib directories.
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS FALSE)
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
################################################################################
|
||||
#
|
||||
# Vagrantfile
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Buildroot version to use
|
||||
RELEASE='2021.11'
|
||||
|
||||
### Change here for more memory/cores ###
|
||||
VM_MEMORY=2048
|
||||
VM_CORES=1
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
config.vm.box = 'ubuntu/bionic64'
|
||||
|
||||
config.vm.provider :vmware_fusion do |v, override|
|
||||
v.vmx['memsize'] = VM_MEMORY
|
||||
v.vmx['numvcpus'] = VM_CORES
|
||||
end
|
||||
|
||||
config.vm.provider :virtualbox do |v, override|
|
||||
v.memory = VM_MEMORY
|
||||
v.cpus = VM_CORES
|
||||
|
||||
required_plugins = %w( vagrant-vbguest )
|
||||
required_plugins.each do |plugin|
|
||||
system "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.provision 'shell' do |s|
|
||||
s.inline = 'echo Setting up machine name'
|
||||
|
||||
config.vm.provider :vmware_fusion do |v, override|
|
||||
v.vmx['displayname'] = "Buildroot #{RELEASE}"
|
||||
end
|
||||
|
||||
config.vm.provider :virtualbox do |v, override|
|
||||
v.name = "Buildroot #{RELEASE}"
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.provision 'shell', privileged: true, inline:
|
||||
"sed -i 's|deb http://us.archive.ubuntu.com/ubuntu/|deb mirror://mirrors.ubuntu.com/mirrors.txt|g' /etc/apt/sources.list
|
||||
dpkg --add-architecture i386
|
||||
apt-get -q update
|
||||
apt-get purge -q -y snapd lxcfs lxd ubuntu-core-launcher snap-confine
|
||||
apt-get -q -y install build-essential libncurses5-dev \
|
||||
git bzr cvs mercurial subversion libc6:i386 unzip bc
|
||||
apt-get -q -y autoremove
|
||||
apt-get -q -y clean
|
||||
update-locale LC_ALL=C"
|
||||
|
||||
config.vm.provision 'shell', privileged: false, inline:
|
||||
"echo 'Downloading and extracting buildroot #{RELEASE}'
|
||||
wget -q -c http://buildroot.org/downloads/buildroot-#{RELEASE}.tar.gz
|
||||
tar axf buildroot-#{RELEASE}.tar.gz"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
# Generates glibc locale data for target.
|
||||
|
||||
inputfile = $(firstword $(subst ., ,$(1)))
|
||||
charmap = $(or $(word 2,$(subst ., ,$(1))),UTF-8)
|
||||
|
||||
# Packages all the generated locale data into the final archive.
|
||||
#
|
||||
# We sort the file names to produce consistent output regardless of
|
||||
# the `find` outputs order.
|
||||
$(TARGET_DIR)/usr/lib/locale/locale-archive: $(LOCALES)
|
||||
$(Q)rm -f $(@)
|
||||
$(Q)find $(TARGET_DIR)/usr/lib/locale/ -maxdepth 1 -mindepth 1 -type d -print0 \
|
||||
| sort -z \
|
||||
| xargs -0 \
|
||||
$(HOST_DIR)/bin/localedef \
|
||||
--prefix=$(TARGET_DIR) \
|
||||
--$(ENDIAN)-endian \
|
||||
--add-to-archive
|
||||
|
||||
# Generates locale data for each locale.
|
||||
#
|
||||
# The input data comes preferably from the toolchain, or if the toolchain
|
||||
# does not have them (Linaro toolchains), we use the ones available on the
|
||||
# host machine.
|
||||
#
|
||||
# Uses `localedef`, which is built by the `host-localedef` package.
|
||||
$(LOCALES): | $(TARGET_DIR)/usr/lib/locale/
|
||||
$(Q)echo "Generating locale $(@)"
|
||||
$(Q)I18NPATH=$(STAGING_DIR)/usr/share/i18n:/usr/share/i18n \
|
||||
$(HOST_DIR)/bin/localedef \
|
||||
--prefix=$(TARGET_DIR) \
|
||||
--$(ENDIAN)-endian \
|
||||
--no-archive \
|
||||
-i $(call inputfile,$(@)) \
|
||||
-f $(call charmap,$(@)) \
|
||||
$(@)
|
||||
|
||||
.PHONY: $(LOCALES)
|
||||
|
||||
$(TARGET_DIR)/usr/lib/locale/:
|
||||
$(Q)mkdir -p $(TARGET_DIR)/usr/lib/locale/
|
||||
@@ -0,0 +1,104 @@
|
||||
.check-DEVELOPERS_base:
|
||||
# get-developers should print just "No action specified"; if it prints
|
||||
# anything else, it's a parse error.
|
||||
# The initial ! is removed by YAML so we need to quote it.
|
||||
script:
|
||||
- "! utils/get-developers | grep -v 'No action specified'"
|
||||
|
||||
.check-flake8_base:
|
||||
script:
|
||||
- make check-flake8
|
||||
|
||||
.check-package_base:
|
||||
script:
|
||||
- make check-package
|
||||
|
||||
.defconfig_check:
|
||||
before_script:
|
||||
- DEFCONFIG_NAME=$(echo ${CI_JOB_NAME} | sed -e 's,_check$,,g')
|
||||
script:
|
||||
- echo "Configure Buildroot for ${DEFCONFIG_NAME}"
|
||||
- make ${DEFCONFIG_NAME}
|
||||
- support/scripts/check-dotconfig.py .config configs/${DEFCONFIG_NAME}
|
||||
artifacts:
|
||||
when: on_failure
|
||||
expire_in: 2 weeks
|
||||
paths:
|
||||
- .config
|
||||
|
||||
.run_make: &run_make
|
||||
|
|
||||
make O=${OUTPUT_DIR} > >(tee build.log |grep '>>>') 2>&1 || {
|
||||
echo 'Failed build last output'
|
||||
tail -200 build.log
|
||||
exit 1
|
||||
}
|
||||
|
||||
.defconfig_base:
|
||||
before_script:
|
||||
- DEFCONFIG_NAME=${CI_JOB_NAME}
|
||||
- OUTPUT_DIR=output
|
||||
script:
|
||||
- echo "Configure Buildroot for ${DEFCONFIG_NAME}"
|
||||
- make ${DEFCONFIG_NAME}
|
||||
- ./support/scripts/check-dotconfig.py .config ./configs/${DEFCONFIG_NAME}
|
||||
- echo 'Build buildroot'
|
||||
- *run_make
|
||||
- |
|
||||
./support/scripts/boot-qemu-image.py "${DEFCONFIG_NAME}" > >(tee runtime-test.log) 2>&1 || {
|
||||
echo 'Failed runtime test last output'
|
||||
tail -200 runtime-test.log
|
||||
exit 1
|
||||
}
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 2 weeks
|
||||
paths:
|
||||
- .config
|
||||
- build.log
|
||||
- output/images/
|
||||
- output/build/build-time.log
|
||||
- output/build/packages-file-list.txt
|
||||
- output/build/*/.config
|
||||
- runtime-test.log
|
||||
|
||||
.runtime_test_base:
|
||||
before_script:
|
||||
- TEST_CASE_NAME=${CI_JOB_NAME}
|
||||
# Keep build directories so the rootfs can be an artifact of the job. The
|
||||
# runner will clean up those files for us.
|
||||
# Multiply every emulator timeout by 10 to avoid sporadic failures in
|
||||
# elastic runners.
|
||||
script:
|
||||
- echo "Starting runtime test ${TEST_CASE_NAME}"
|
||||
- ./support/testing/run-tests -o test-output/ -d test-dl/ -k --timeout-multiplier 10 ${TEST_CASE_NAME}
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 2 weeks
|
||||
paths:
|
||||
- test-output/*.log
|
||||
- test-output/*/.config
|
||||
- test-output/*/images/*
|
||||
|
||||
.test_pkg:
|
||||
stage: build
|
||||
before_script:
|
||||
- OUTPUT_DIR=${CI_JOB_NAME}
|
||||
script:
|
||||
- echo "Configure Buildroot for ${OUTPUT_DIR}"
|
||||
- make O=${OUTPUT_DIR} syncconfig
|
||||
- make O=${OUTPUT_DIR} savedefconfig
|
||||
- echo 'Build buildroot'
|
||||
- *run_make
|
||||
needs:
|
||||
- pipeline: $PARENT_PIPELINE_ID
|
||||
job: generate-gitlab-ci-yml
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 2 weeks
|
||||
paths:
|
||||
- build.log
|
||||
- br-test-pkg/*/.config
|
||||
- br-test-pkg/*/defconfig
|
||||
- br-test-pkg/*/build/build-time.log
|
||||
- br-test-pkg/*/build/packages-file-list*.txt
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
if [ "$#" -ne 0 ]; then
|
||||
echo "Run this script to relocate the buildroot SDK at that location"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOCFILE="share/buildroot/sdk-location"
|
||||
FILEPATH="$(readlink -f "$0")"
|
||||
NEWPATH="$(dirname "${FILEPATH}")"
|
||||
|
||||
cd "${NEWPATH}"
|
||||
if [ ! -r "${LOCFILE}" ]; then
|
||||
echo "Previous location of the buildroot SDK not found!"
|
||||
exit 1
|
||||
fi
|
||||
OLDPATH="$(cat "${LOCFILE}")"
|
||||
|
||||
if [ "${NEWPATH}" = "${OLDPATH}" ]; then
|
||||
echo "This buildroot SDK has already been relocated!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if the path substitution does work properly, e.g. a tree
|
||||
# "/a/b/c" copied into "/a/b/c/a/b/c/" would not be allowed.
|
||||
newpath="$(sed -e "s|${OLDPATH}|${NEWPATH}|g" "${LOCFILE}")"
|
||||
if [ "${NEWPATH}" != "${newpath}" ]; then
|
||||
echo "Something went wrong with substituting the path!"
|
||||
echo "Please choose another location for your SDK!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Relocating the buildroot SDK from ${OLDPATH} to ${NEWPATH} ..."
|
||||
|
||||
# Make sure file uses the right language
|
||||
export LC_ALL=C
|
||||
# Replace the old path with the new one in all text files
|
||||
grep -lr "${OLDPATH}" . | while read -r FILE ; do
|
||||
if file -b --mime-type "${FILE}" | grep -q '^text/' && [ "${FILE}" != "${LOCFILE}" ]
|
||||
then
|
||||
sed -i "s|${OLDPATH}|${NEWPATH}|g" "${FILE}"
|
||||
fi
|
||||
done
|
||||
|
||||
# At the very end, we update the location file to not break the
|
||||
# SDK if this script gets interruted.
|
||||
sed -i "s|${OLDPATH}|${NEWPATH}|g" ${LOCFILE}
|
||||
@@ -0,0 +1,29 @@
|
||||
Warning!
|
||||
========
|
||||
|
||||
This directory does *not* contain the root filesystem that you can use
|
||||
on your embedded system. Since Buildroot does not run as root, it
|
||||
cannot create device files and set the permissions and ownership of
|
||||
files correctly in this directory to make it usable as a root
|
||||
filesystem.
|
||||
|
||||
For that reason, do *not* use the contents of this directory to mount
|
||||
your root filesystem over NFS or copy the contents of this directory
|
||||
to a SD card or USB key, thinking it will work as the root filesystem
|
||||
for your embedded system. It will simply *not* work.
|
||||
|
||||
Instead, if you need a usable root filesystem, please select one of
|
||||
the filesystem image formats available in the Buildroot configuration
|
||||
interface (make menuconfig or others) in the "Filesystem images"
|
||||
sub-menu. If you want to get a filesystem image that you can easily
|
||||
extract to your SD card or to some directory exposed through NFS,
|
||||
please use the "tar the root filesystem" option. It will generate a
|
||||
images/rootfs.tar image in your Buildroot output directory, which you
|
||||
can extract as root:
|
||||
|
||||
sudo tar -C /destination/of/extraction -xf images/rootfs.tar
|
||||
|
||||
Those image files are created using the contents of the target/
|
||||
directory, but there is a post-processing step to create device files
|
||||
and set ownership/permissions properly even if Buildroot does not run
|
||||
as root.
|
||||
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# CMake toolchain file for Buildroot
|
||||
#
|
||||
|
||||
# In order to allow the toolchain to be relocated, we calculate the
|
||||
# HOST_DIR based on this file's location: $(HOST_DIR)/share/buildroot
|
||||
# and store it in RELOCATED_HOST_DIR.
|
||||
# All the other variables that need to refer to HOST_DIR will use the
|
||||
# RELOCATED_HOST_DIR variable.
|
||||
string(REPLACE "/share/buildroot" "" RELOCATED_HOST_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Point cmake to the location where we have our custom modules,
|
||||
# so that it can find our custom platform description.
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Buildroot)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
set(CMAKE_SYSTEM_PROCESSOR @@CMAKE_SYSTEM_PROCESSOR@@)
|
||||
|
||||
# Set the {C,CXX}FLAGS appended by CMake depending on the build type
|
||||
# defined by Buildroot. CMake defaults these variables with -g and/or
|
||||
# -O options, and they are appended at the end of the argument list,
|
||||
# so the Buildroot options are overridden. Therefore these variables
|
||||
# have to be cleared, so that the options passed in CMAKE_C_FLAGS do
|
||||
# apply.
|
||||
#
|
||||
# Note:
|
||||
# if the project forces some of these flag variables, Buildroot is
|
||||
# screwed up and there is nothing Buildroot can do about that :(
|
||||
set(CMAKE_C_FLAGS_DEBUG "" CACHE STRING "Debug CFLAGS")
|
||||
set(CMAKE_C_FLAGS_RELEASE " -DNDEBUG" CACHE STRING "Release CFLAGS")
|
||||
|
||||
# Build type from the Buildroot configuration
|
||||
set(CMAKE_BUILD_TYPE @@CMAKE_BUILD_TYPE@@ CACHE STRING "Buildroot build configuration")
|
||||
|
||||
# Buildroot defaults flags.
|
||||
# If you are using this toolchainfile.cmake file outside of Buildroot and
|
||||
# want to customize the compiler/linker flags, then:
|
||||
# * set them all on the cmake command line, e.g.:
|
||||
# cmake -DCMAKE_C_FLAGS="@@TARGET_CFLAGS@@ -Dsome_custom_flag" ...
|
||||
# * and make sure the project's CMake code extends them like this if needed:
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dsome_definitions")
|
||||
set(CMAKE_C_FLAGS "@@TARGET_CFLAGS@@" CACHE STRING "Buildroot CFLAGS")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "@@TARGET_LDFLAGS@@" CACHE STRING "Buildroot LDFLAGS for executables")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "@@TARGET_LDFLAGS@@" CACHE STRING "Buildroot LDFLAGS for shared libraries")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "@@TARGET_LDFLAGS@@" CACHE STRING "Buildroot LDFLAGS for module libraries")
|
||||
|
||||
set(CMAKE_INSTALL_SO_NO_EXE 0)
|
||||
|
||||
set(CMAKE_PROGRAM_PATH "${RELOCATED_HOST_DIR}/bin")
|
||||
set(CMAKE_SYSROOT "${RELOCATED_HOST_DIR}/@@STAGING_SUBDIR@@")
|
||||
set(CMAKE_FIND_ROOT_PATH "${RELOCATED_HOST_DIR}/@@STAGING_SUBDIR@@")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${RELOCATED_HOST_DIR}/@@STAGING_SUBDIR@@")
|
||||
|
||||
# This toolchain file can be used both inside and outside Buildroot.
|
||||
set(CMAKE_C_COMPILER "${RELOCATED_HOST_DIR}/@@TARGET_CC@@")
|
||||
if(@@TOOLCHAIN_HAS_CXX@@)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "" CACHE STRING "Debug CXXFLAGS")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG" CACHE STRING "Release CXXFLAGS")
|
||||
set(CMAKE_CXX_FLAGS "@@TARGET_CXXFLAGS@@" CACHE STRING "Buildroot CXXFLAGS")
|
||||
set(CMAKE_CXX_COMPILER "${RELOCATED_HOST_DIR}/@@TARGET_CXX@@")
|
||||
endif()
|
||||
if(@@TOOLCHAIN_HAS_FORTRAN@@)
|
||||
set(CMAKE_Fortran_FLAGS_DEBUG "" CACHE STRING "Debug Fortran FLAGS")
|
||||
set(CMAKE_Fortran_FLAGS_RELEASE " -DNDEBUG" CACHE STRING "Release Fortran FLAGS")
|
||||
set(CMAKE_Fortran_FLAGS "@@TARGET_FCFLAGS@@" CACHE STRING "Buildroot FCFLAGS")
|
||||
set(CMAKE_Fortran_COMPILER "${RELOCATED_HOST_DIR}/@@TARGET_FC@@")
|
||||
endif()
|
||||
@@ -0,0 +1,137 @@
|
||||
################################################################################
|
||||
#
|
||||
# This file contains various utility macros and variables used about
|
||||
# everywhere in make constructs.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Strip quotes and then whitespaces
|
||||
qstrip = $(strip $(subst ",,$(1)))
|
||||
#"))
|
||||
|
||||
# Variables for use in Make constructs
|
||||
comma := ,
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
|
||||
# make 4.3:
|
||||
# https://lwn.net/Articles/810071/
|
||||
# Number signs (#) appearing inside a macro reference or function invocation
|
||||
# no longer introduce comments and should not be escaped with backslashes:
|
||||
# thus a call such as:
|
||||
# foo := $(shell echo '#')
|
||||
# is legal. Previously the number sign needed to be escaped, for example:
|
||||
# foo := $(shell echo '\#')
|
||||
# Now this latter will resolve to "\#". If you want to write makefiles
|
||||
# portable to both versions, assign the number sign to a variable:
|
||||
# H := \#
|
||||
# foo := $(shell echo '$H')
|
||||
SHARP_SIGN := \#
|
||||
|
||||
# Case conversion macros. This is inspired by the 'up' macro from gmsl
|
||||
# (http://gmsl.sf.net). It is optimised very heavily because these macros
|
||||
# are used a lot. It is about 5 times faster than forking a shell and tr.
|
||||
#
|
||||
# The caseconvert-helper creates a definition of the case conversion macro.
|
||||
# After expansion by the outer $(eval ), the UPPERCASE macro is defined as:
|
||||
# $(strip $(eval __tmp := $(1)) $(eval __tmp := $(subst a,A,$(__tmp))) ... )
|
||||
# In other words, every letter is substituted one by one.
|
||||
#
|
||||
# The caseconvert-helper allows us to create this definition out of the
|
||||
# [FROM] and [TO] lists, so we don't need to write down every substition
|
||||
# manually. The uses of $ and $$ quoting are chosen in order to do as
|
||||
# much expansion as possible up-front.
|
||||
#
|
||||
# Note that it would be possible to conceive a slightly more optimal
|
||||
# implementation that avoids the use of __tmp, but that would be even
|
||||
# more unreadable and is not worth the effort.
|
||||
|
||||
[FROM] := a b c d e f g h i j k l m n o p q r s t u v w x y z - .
|
||||
[TO] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ _
|
||||
|
||||
define caseconvert-helper
|
||||
$(1) = $$(strip \
|
||||
$$(eval __tmp := $$(1))\
|
||||
$(foreach c, $(2),\
|
||||
$$(eval __tmp := $$(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),$$(__tmp))))\
|
||||
$$(__tmp))
|
||||
endef
|
||||
|
||||
$(eval $(call caseconvert-helper,UPPERCASE,$(join $(addsuffix :,$([FROM])),$([TO]))))
|
||||
$(eval $(call caseconvert-helper,LOWERCASE,$(join $(addsuffix :,$([TO])),$([FROM]))))
|
||||
|
||||
# Reverse the orders of words in a list. Again, inspired by the gmsl
|
||||
# 'reverse' macro.
|
||||
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1))) $(firstword $(1)))
|
||||
|
||||
# Sanitize macro cleans up generic strings so it can be used as a filename
|
||||
# and in rules. Particularly useful for VCS version strings, that can contain
|
||||
# slashes, colons (OK in filenames but not in rules), and spaces.
|
||||
sanitize = $(subst $(space),_,$(subst :,_,$(subst /,_,$(strip $(1)))))
|
||||
|
||||
# MESSAGE Macro -- display a message in bold type
|
||||
MESSAGE = echo "$(TERM_BOLD)>>> $($(PKG)_NAME) $($(PKG)_VERSION) $(call qstrip,$(1))$(TERM_RESET)"
|
||||
TERM_BOLD := $(shell tput smso 2>/dev/null)
|
||||
TERM_RESET := $(shell tput rmso 2>/dev/null)
|
||||
|
||||
# Utility functions for 'find'
|
||||
# findfileclauses(filelist) => -name 'X' -o -name 'Y'
|
||||
findfileclauses = $(call notfirstword,$(patsubst %,-o -name '%',$(1)))
|
||||
# finddirclauses(base, dirlist) => -path 'base/dirX' -o -path 'base/dirY'
|
||||
finddirclauses = $(call notfirstword,$(patsubst %,-o -path '$(1)/%',$(2)))
|
||||
|
||||
# Miscellaneous utility functions
|
||||
# notfirstword(wordlist): returns all but the first word in wordlist
|
||||
notfirstword = $(wordlist 2,$(words $(1)),$(1))
|
||||
|
||||
# build a comma-separated list of quoted items, from a space-separated
|
||||
# list of unquoted items: a b c d --> "a", "b", "c", "d"
|
||||
make-comma-list = $(subst $(space),$(comma)$(space),$(patsubst %,"%",$(strip $(1))))
|
||||
|
||||
# build a comma-separated list of single quoted items, from a space-separated
|
||||
# list of unquoted items: a b c d --> 'a', 'b', 'c', 'd'
|
||||
make-sq-comma-list = $(subst $(space),$(comma)$(space),$(patsubst %,'%',$(strip $(1))))
|
||||
|
||||
# Needed for the foreach loops to loop over the list of hooks, so that
|
||||
# each hook call is properly separated by a newline.
|
||||
define sep
|
||||
|
||||
|
||||
endef
|
||||
|
||||
PERCENT = %
|
||||
QUOTE = '
|
||||
# ' # Meh... syntax-highlighting
|
||||
|
||||
# This macro properly escapes a command string, then prints it with printf:
|
||||
#
|
||||
# - first, backslash '\' are self-escaped, so that they do not escape
|
||||
# the following char and so that printf properly outputs a backslash;
|
||||
#
|
||||
# - next, single quotes are escaped by closing an existing one, adding
|
||||
# an escaped one, and re-openning a new one (see below for the reason);
|
||||
#
|
||||
# - then '%' signs are self-escaped so that the printf does not interpret
|
||||
# them as a format specifier, in case the variable contains an actual
|
||||
# printf with a format;
|
||||
#
|
||||
# - finally, $(sep) is replaced with the literal '\n' so that make does
|
||||
# not break on the so-expanded variable, but so that the printf does
|
||||
# correctly output an LF.
|
||||
#
|
||||
# Note: this must be escaped in this order to avoid over-escaping the
|
||||
# previously escaped elements.
|
||||
#
|
||||
# Once everything has been escaped, it is passed between single quotes
|
||||
# (that's why the single-quotes are escaped they way they are, above,
|
||||
# and why the dollar sign is not escaped) to printf(1). A trailing
|
||||
# newline is apended, too.
|
||||
#
|
||||
# Note: leading or trailing spaces are *not* stripped.
|
||||
#
|
||||
define PRINTF
|
||||
printf '$(subst $(sep),\n,\
|
||||
$(subst $(PERCENT),$(PERCENT)$(PERCENT),\
|
||||
$(subst $(QUOTE),$(QUOTE)\$(QUOTE)$(QUOTE),\
|
||||
$(subst \,\\,$(1)))))\n'
|
||||
endef
|
||||
Reference in New Issue
Block a user