早上好,我正在尝试使用VS2008编译器(msbuild)用Ant编译一个C++项目。这是我的操作顺序:
<target name="setEnv" >
<exec dir="." executable="cmd">
<arg line="/c setEnv.bat" />
</exec>
</target>
其中,setEnv.bat将环境变量设置为使用msbuild
@echo off
REM Load Visual Studio's build tools
call "C:Program Files (x86)Microsoft Visual Studio 9.0VCvcvarsall.bat" x64
并且在它执行这个之后
<target name="msbuildSln" depends="setEnv">
<exec executable="msbuild">
<arg value="${myproj.sln}" />
<arg value="/p:Configuration=Release" />
<arg value="/p:Platform=x64" />
</exec>
</target>
问题是,当我从目标msbuildSln调用msbuild时,环境变量没有设置——事实上,我有这样的消息:
BUILD FAILED
C:UsersworkspaceMyProjmybuild.xml:82: Execute failed: java.io.IOException: Cannot run program "msbuild": CreateProcess error=2, The system cannot find the file specified
我认为这是cmd作用域的问题,因为如果我在setEnv.bat中启动它,它就会运行。我尝试了不同的解决方案:
1) 从其文件夹直接调用msbuild并运行我的目标
2) 设置环境。vcvarsall.bat的全局变量
3) 对Ant脚本进行双重调用,修改mt setEnv.bat:call "C:Program Files (x86)Microsoft Visual Studio 9.0VCvcvarsall.bat" x64 %*
ant -f mybuild.xml msbuildSln
设置为类似projectdefault="setEnv",并从msbuildSln目标中的setEnv中删除dependence。
我采用了最后一种解决方案,但我不知道它是否会影响性能。但最重要的一点是,有一种方法可以同时设置和使用vcvarsall.bat和msbuild,因为我必须执行许多步骤(如从svn签出、构建解决方案等),并且我希望Ant不将所有内容都放在.bat文件中。谢谢
当您执行第一个cmd
:时
- 它生成一个新的shell(继承当前shell的当前环境,即
ant
进程) - 当该命令完成时,shell将被销毁,它可能创建的任何非持久性更改(如设置变量)都将丢失
即使setEnv.bat
使用setx
命令永久设置环境变量,它也不会对以下ant语句/目标可用,因为当前环境(ant
进程)在重新启动并再次从系统中产生之前不会有新的环境变量。
我刚刚注意到您的setEnv.bat
刚刚调用了另一批。。。为什么不直接调用该批呢
您需要在同一个shell中调用setEnv.bat
和msbuild
,即cmd
语句:
<exec dir="." executable="cmd">
<arg line="/c setEnv.bat & msbuild ${myproj.sln} /p:Configuration=Release /p:Platform=x64" />
</exec>
注意写入命令行&
所需的&
可读性的另一种语法:
<exec dir="." executable="cmd">
<arg value="/c" />
<arg value="setEnv.bat" />
<arg value="&" />
<arg value="msbuild" />
<arg value="${myproj.sln}" />
<arg value="/p:Configuration=Release" />
<arg value="/p:Platform=x64" />
</exec>