在预构建事件中设置环境变量并在编译步骤中使用

22

在Visual Studio 2003中,我试图在预构建事件中设置一个环境变量,然后在编译步骤中使用它,但是该值似乎没有被传播。例如,如果预构建事件包含以下内容(直接或在批处理文件中):

set MY_LIB_VERSION=1.0.0

而 AdditionalIncludeDirectories 具有以下内容:

c:\path\to\library\my_lib_v$(MY_LIB_VERSION)\include
如果my_lib_v1.0.0目录存在,我期望编译能够正常工作。但是实际上,我遇到了如下错误:
c:\path\to\prog\my_prog.c(22) : fatal error C1083: Cannot open include file: 'my_lib.h'
Project : warning PRJ0018 : The following environment variables were not found:
$(MY_LIB_VERSION)
我推测预构建事件中设置的环境变量没有传递到编译步骤,但我可能漏掉了一些细节。 如何在预构建事件中设置环境变量,并在编译步骤中使用它? (或者,任何合理的方法都行,只要能定义库版本并将其用于AdditionalIncludeDirectories和AdditionalLibraryDirectories多次即可。)
更新: 我最终用另一种方式解决了我们的问题。我们使用的是Subversion,并在名为dependencies的项目源子目录上设置了svn:externals属性,以便对项目的检出将额外检出<svn_path>\libraries\my_lib_v1.0.0并将其称为工作副本中的dependencies\my_lib。然后,项目设置可以引用dependencies\my_lib\include等内容。升级到my_lib的1.0.1版本只需要编辑svn:externals属性即可--代码和项目设置不需要更改。

从Windows 7开始(看起来是这样),有一个名为SETX的命令可以持久地存储环境变量。来源:http://ss64.com/nt/setx.html - bassim
4个回答

11

距离这个问题最初提出已经过去了11年。我正在使用VS 2019

如果你想在事件中分配变量,比如...

set ABC = 123

那么你不能使用 $(ABC) 作为 $(ABC) 在传递给命令行运行之前就已被处理。

你必须使用 %ABC%,就像命令行所用的一样。它不知道 $(ABC) 是什么,因为它只能被 Visual Studio 理解。

更进一步复杂化的是,Visual Studio 事件编辑器使用 % 作为转义字符。我注意到以% D 开头的东西很糟糕,而% K、% Z和% K则很好。

显然,你可以使用 %25 作为 % 的转义字符。

%DESTDIR% 不行,因为转义会使其混乱-所以将其更改为%25DESDIR%25 可以修复它。


1
11年后的评论值得点赞。虽然我无法获取预构建事件命令行中的“set”环境变量或调试命令行参数以传递给我的Nunit测试项目。我不得不直接将这些参数传递给测试 - rupweb
请不要在同一问题下发布多个相同的答案。如果这些问题是相同的,请标记它们为重复。如果它们不同,请花时间编写一个新的、特定于所提问的问题的答案。 - Chris

6

我必须承认,我从未尝试在预构建步骤中设置环境变量,我可以理解为什么它不一定起作用(运行批处理文件很可能会触发一个单独的进程,而你想操作父进程的环境)。

我一直在使用的解决方法只适用于在启动Visual Studio之前可以确定必要设置的情况下,即创建一个批处理文件来设置必要的环境变量,然后使用相应的解决方案文件启动Visual Studio。我在下面复制了这个批处理文件的骨架:

REM
REM Set up VS environment with defaults (this is for 2008) - need to do this first
REM
call "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
REM
REM Set the environment variables required by the project
REM
set BOOST_BASE=C:\Boost\include\boost-1_35
REM
REM If you need to manipulate the path, do it here
REM
REM
REM Finally, start VS with the appropriate solution file
REM
devenv MyProjectWithBoost.sln

感谢您提供的解决方法。虽然我们会提前知道版本号,但我真的希望将其集成到标准构建中,这样无论开发人员使用IDE还是命令行,库版本都将是正确的。我没有权力让整个团队使用特殊脚本! - Paul Stephenson

5

谢谢。我已经安装了这个插件,它对我很有效。但我不确定能否说服我们所有的开发人员自己安装它,因为为了在公司内部可靠使用,必须在每台开发机器上都进行安装。 - Paul Stephenson
似乎这样的插件是编辑 Visual Studio 的环境变量的唯一方法,因此尽管它无法应用于我们公司,但我仍会接受这个答案。 - Paul Stephenson
这个插件非常棒,据我所知是唯一可以动态添加环境变量的解决方案。 但请注意,包含环境变量的文件行不能超过2048个字符(插件源代码中有一个丑陋的char[2048])。 - Grokwik

4
使用SET命令设置的环境变量是临时的,只在设置它们的进程生命周期内持续。当进程过期时,它们立即过期,并且其他进程无法看到它们。
Visual Studio预构建事件是一个单独的进程。一旦该进程过期,该环境变量就会停止存在。
您确定环境变量是您想要的吗?您可以通过在中央网络位置上保存的文本文件中设置值来完成此操作。
编辑:如果您真的想在Windows中持久更改环境变量,则可以这样做,但这将涉及调用一些Windows API,而不仅仅是调用SET。例如 http://code.activestate.com/recipes/416087/ 尝试谷歌搜索environment variable windows persisting

我想做的主要事情是拥有一个库版本的文本文件,并且根据文本文件中的值使AdditionalIncludeDirectories依赖于它,而不需要每个开发人员在编译之前记得运行特殊脚本。我不确定环境变量是否是我想要的! - Paul Stephenson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接