解决方案 1
我认为 OP 使用 $(branch) 的方式很酷。但是无法使用Visual Studio 中分支名称的动态值创建用户宏。如果我们在VS启动后将pre-build事件添加到pre-build事件中,Visual Studio要么不可能重新加载环境变量,除非它重新启动。似乎最直接的方法就是在git 存储库中的post-checkout 中挂钩,就像@ConfusedSushi 提到的那样。
我刚刚测试了解决方案,它运行良好。详情如下。
创建git hookpost-checkout(文件名就是post-checkout,放入GIT_DIR/.git/hooks,会调用一个批处理文件set-branch.bat。
#!/bin/bash
if [ "$3" -eq "1" ]; then
cmd.exe /c "`pwd`/.git/hooks/set-branch.bat"
fi
批处理文件set-branch.bat如下。并将其放入GIT_DIR/.git/hooks。
@echo off
for /f %%i in ('git rev-parse --abbrev-ref HEAD') do setx branch %%i
然后像 OP 一样设置Output directory:
..\bin\$(branch)\$(Configuration)$(Platform)\
现在,每次通过git check 更改分支时,都会设置一个环境变量branch。而你需要重启Visual Studio才能获取环境变量值。它只是根据您的需要工作。
解决方案 2
由于 OP 的评论,另一种解决方案是让 Visual Studio 使用相同的文件夹,但在结帐后挂钩中移动 Output/intermediate 目录。
只需使用以下脚本创建一个 git hook post-checkout。并且用您自己的真实文件夹替换Test/Test/Debug 下面的我的测试文件夹。可以是绝对目录,也可以是与git仓库相关的目录。构建文件夹如果不是当前分支,会添加branch name作为后缀。
#!/bin/bash
build_folder=Test/Test/Debug
if [ "$3" -eq "1" ]; then
oldref=$(git reflog | awk 'NR==1{ print $6; exit }')
newref=$(git rev-parse --abbrev-ref HEAD)
if [ "$oldref" != "$newref" ]; then
if [ -d "$build_folder-$oldref" ]; then
rm -rf "$build_folder-$oldref"
echo "Deleted $build_folder-$oldref"
fi
if [ -d "$build_folder" ]; then
mv "$build_folder" "$build_folder-$oldref"
echo "Moved $build_folder to $build_folder-$oldref"
fi
if [ -d "$build_folder-$newref" ]; then
mv "$build_folder-$newref" "$build_folder"
echo "Moved $build_folder-$newref to $build_folder"
fi
fi
fi
[已更新] 对于已编辑的问题,由于切换分支时预编译的头文件总是会发生变化,因此项目总是会重新编译。其实有解决办法,但是有点危险。
VS 检测源文件的modified time 来决定是否需要重新编译。所以我们能做的就是把modified time改成作弊VS。我们可以使用命令touch 来完成。
但很难决定哪个时间合适。为了实用,我们可以选择一个不会因为切换分支而改变的文件,而且也比较稳定,将预编译头文件的modified time设置为和选择的文件一样。我们也可以在post-checkout 钩子中实现。
touch -r some_stable_chosen_file precompiled_header
但我们应该记住它是不安全的,因为它也可能忽略对预编译头文件的实际更改。我们必须手动处理它。