如何使用 premake 生成 Syntastic 配置文件?
How can I generate a Syntastic config file using premake?
Syntastic 是 Vim 编辑器的源代码 linter 插件。
它使用外部工具进行各种语法和启发式检查。对于 C 和 C++ 代码,这通常涉及 运行 代码编译器。
为了调用编译器,Syntastic 读取一个配置文件,其中包含用于调用编译器的命令行参数。
显然,项目中的“真实”编译由 premake 处理,但这意味着可能有两个真实来源——写入 Syntastic 配置文件的编译器标志, 以及由 premake 写入构建脚本的编译器标志。
我想通过让 premake 在 Syntastic 配置文件中生成编译器标志来解决这个问题。
这似乎是一个相当简单的任务,有多种可能的方法——生成一个伪造的编译器,发明一个预构建任务,等等。但我对 premake 的内部结构知之甚少 这些方法中 是正确的。
如何让 premake 生成我的 syntastic.config
文件?
我查看了 premake5 下的几个不同的 kind
s 项目——最近有几个项目被添加到文档中。 None 他们让我到达那里。
问题是我想要做的是“始终创建文件”或“在 premake5.lua 文件更改时创建文件”。这让事情变得困难,但并非完全不可能。
但是,生成的文件不是任何项目的输入文件,因此显然将它从困难推到了“不可能的 ATM”的边缘。
我尝试执行 premake 调用的操作 Custom Build Commands,但这需要生成的文件是一段源代码,它可以用来构建。如果不是这种情况,显然依赖关系图会中断,生成的 makefile 不依赖于该文件。 :(
为了让它正常工作,我选择始终使用预构建命令重新生成文件:
prebuildcommands {
"$(SILENT) "
..repo_dir.."etc/write-syntastic-config.sh $(ALL_CFLAGS)"
.." > "
..repo_dir.."etc/syntastic.config"
}
这里的关键值是$(ALL_CFLAGS)
,Makefile生成器用来保存我想要的东西的变量。
Syntastic 的配置文件及其对配置文件的使用有点棘手。它不接受 -L
和 -l
选项,或者可能 gcc
在调用它的任何模式下都不接受它们。无论如何,需要进行一些过滤,可以使用 args。
此外,syntastic 处理专门查找 -I
的行,然后以特殊方式处理这些行:包含路径被视为绝对路径或相对于配置文件。
最后,syntastic 似乎不知道 -isystem
,gcc
的另一个包含目录选项。所以必须以不同的方式处理。
如果有人关心,这是我正在使用的脚本:
etc/write-syntastic-config.sh
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
PENDING=""
PENDING_DIR=false
printf '# Generated by %s\n' "$(basename "[=11=]")"
CFG_FILE_DIR="$(dirname "[=11=]")"
for ARG in "$@"
do
#printf >&2 "arg=>%s<\n" "$ARG"
case "$ARG" in
-I| \
-L)
PENDING="$ARG"
PENDING_DIR=true
;;
-isystem)
# -isystem is like -I, except syntastic doesn't know it
printf '%s\n' "$ARG"
PENDING_DIR=true
;;
-I*| \
-L*) PENDING_DIR=true
PENDING="${ARG:0:2}"
ARG="${ARG/#-?/}"
;;& #<-- Resume matching cases (i.e, "goto next case")
*) if $PENDING_DIR
then
ARG="$(realpath -m \
--relative-to "$CFG_FILE_DIR" \
"$ARG")"
fi
case "$PENDING" in
-L) : ignore it ;;
"") printf '%s\n' "$ARG" ;;
*) printf '%s %s\n' "$PENDING" "$ARG" ;;
esac
PENDING=""
PENDING_DIR=false
;;
esac
done
exit 0
Syntastic 是 Vim 编辑器的源代码 linter 插件。
它使用外部工具进行各种语法和启发式检查。对于 C 和 C++ 代码,这通常涉及 运行 代码编译器。
为了调用编译器,Syntastic 读取一个配置文件,其中包含用于调用编译器的命令行参数。
显然,项目中的“真实”编译由 premake 处理,但这意味着可能有两个真实来源——写入 Syntastic 配置文件的编译器标志, 以及由 premake 写入构建脚本的编译器标志。
我想通过让 premake 在 Syntastic 配置文件中生成编译器标志来解决这个问题。
这似乎是一个相当简单的任务,有多种可能的方法——生成一个伪造的编译器,发明一个预构建任务,等等。但我对 premake 的内部结构知之甚少 这些方法中 是正确的。
如何让 premake 生成我的 syntastic.config
文件?
我查看了 premake5 下的几个不同的 kind
s 项目——最近有几个项目被添加到文档中。 None 他们让我到达那里。
问题是我想要做的是“始终创建文件”或“在 premake5.lua 文件更改时创建文件”。这让事情变得困难,但并非完全不可能。
但是,生成的文件不是任何项目的输入文件,因此显然将它从困难推到了“不可能的 ATM”的边缘。
我尝试执行 premake 调用的操作 Custom Build Commands,但这需要生成的文件是一段源代码,它可以用来构建。如果不是这种情况,显然依赖关系图会中断,生成的 makefile 不依赖于该文件。 :(
为了让它正常工作,我选择始终使用预构建命令重新生成文件:
prebuildcommands {
"$(SILENT) "
..repo_dir.."etc/write-syntastic-config.sh $(ALL_CFLAGS)"
.." > "
..repo_dir.."etc/syntastic.config"
}
这里的关键值是$(ALL_CFLAGS)
,Makefile生成器用来保存我想要的东西的变量。
Syntastic 的配置文件及其对配置文件的使用有点棘手。它不接受 -L
和 -l
选项,或者可能 gcc
在调用它的任何模式下都不接受它们。无论如何,需要进行一些过滤,可以使用 args。
此外,syntastic 处理专门查找 -I
的行,然后以特殊方式处理这些行:包含路径被视为绝对路径或相对于配置文件。
最后,syntastic 似乎不知道 -isystem
,gcc
的另一个包含目录选项。所以必须以不同的方式处理。
如果有人关心,这是我正在使用的脚本:
etc/write-syntastic-config.sh
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
PENDING=""
PENDING_DIR=false
printf '# Generated by %s\n' "$(basename "[=11=]")"
CFG_FILE_DIR="$(dirname "[=11=]")"
for ARG in "$@"
do
#printf >&2 "arg=>%s<\n" "$ARG"
case "$ARG" in
-I| \
-L)
PENDING="$ARG"
PENDING_DIR=true
;;
-isystem)
# -isystem is like -I, except syntastic doesn't know it
printf '%s\n' "$ARG"
PENDING_DIR=true
;;
-I*| \
-L*) PENDING_DIR=true
PENDING="${ARG:0:2}"
ARG="${ARG/#-?/}"
;;& #<-- Resume matching cases (i.e, "goto next case")
*) if $PENDING_DIR
then
ARG="$(realpath -m \
--relative-to "$CFG_FILE_DIR" \
"$ARG")"
fi
case "$PENDING" in
-L) : ignore it ;;
"") printf '%s\n' "$ARG" ;;
*) printf '%s %s\n' "$PENDING" "$ARG" ;;
esac
PENDING=""
PENDING_DIR=false
;;
esac
done
exit 0