<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>小李贼 &#187; scons</title>
	<atom:link href="http://dipplum.com/tag/scons/feed/" rel="self" type="application/rss+xml" />
	<link>http://dipplum.com</link>
	<description>Be  the change you wanna see in the world</description>
	<lastBuildDate>Wed, 08 Sep 2010 16:45:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Visual C++编译环境免安装命令行版</title>
		<link>http://dipplum.com/2009/11/13/visualc-compiler-portable/</link>
		<comments>http://dipplum.com/2009/11/13/visualc-compiler-portable/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 12:05:12 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[scons]]></category>
		<category><![CDATA[side-by-side]]></category>
		<category><![CDATA[visualc]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/13/visual-c%e7%bc%96%e8%af%91%e7%8e%af%e5%a2%83%e5%85%8d%e5%ae%89%e8%a3%85%e5%91%bd%e4%bb%a4%e8%a1%8c%e7%89%88/</guid>
		<description><![CDATA[VC的IDE开发环境很好，但太大了，经常是2005/2008/2010装一大堆，占用几十G的空间。用惯了Linux的命令行方式，觉得小巧精致。于是想把VC的基本命令提取出来，也做一个绿色版本。 保留基本的编译命令，cl、lib、link、ml之类的。编译工程只能用nmake了。vcproj工程文件怎么办？用scons重写一个吧。(其实命令行也有个vcbuild)。 制作绿色版之前，首先要安装一个VC，再把其中用到的文件提取出来。或者直接快进到后面找下载链接。 Visual C++ 2008制作要领 VC 2008的最大问题是Visual Studio采用Side-by-Side方式发布，不能简单的把依赖的DLL着全就行了。 1. 复制C:\Program Files\Microsoft Visual Studio&#160; 9.0\VC\bin及其子目录1033，到新的vc9\bin目录 2. 在复制VC目录下的lib和include目录，到新的vc9目录下 3. 复制C:\Program Files\Microsoft Visual Studio 2008\Common7\IDE目录下的：msobj80.dll，mspdb80.dll, mspdbcore.dll, mspdbsrv.exe到vc9\bin 4. 在vc\bin生成manifest文件，名为Micrisoft.VC90.CRT.manifest，内容如下 &#60;?xml version=&#34;2.0&#34; encoding=&#34;UTF-8&#34; standalone=&#34;yes&#34;?&#62; &#60;assembly xmlns=&#34;urn:schemas-microsoft-com:asm.v1&#34; manifestversion=&#34;1.0&#34;&#62; &#60;noinheritable&#62;&#60;/noinheritable&#62; &#60;assemblyidentity name=&#34;Microsoft.VC90.CRT&#34; publickeytoken=&#34;1fc8b3b9a1e18e3b&#34; processorarchitecture=&#34;x86&#34; version=&#34;9.0.21022.8&#34; type=&#34;win32&#34;&#62;&#60;/assemblyidentity&#62; &#60;file name=&#34;msvcr90.dll&#34;&#62;&#60;/file&#62; &#60;file name=&#34;msvcp90.dll&#34;&#62;&#60;/file&#62; &#60;/assembly&#62; 5. 找到Windows\WinSxS目录下的x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_&#8230;目录，复制其中的msvcr90.dll和msvcp90.dll到bin目录 Visual C++ 2010制作要领 VC 2010还在Beta阶段，不过据说已经决定不用SxS，直接用DLL发布了，所以制作简单点。 1-3和2008类似，复制bin, include, [...]]]></description>
			<content:encoded><![CDATA[<p>VC的IDE开发环境很好，但太大了，经常是2005/2008/2010装一大堆，占用几十G的空间。用惯了Linux的命令行方式，觉得小巧精致。于是想把VC的基本命令提取出来，也做一个绿色版本。</p>
<p>保留基本的编译命令，cl、lib、link、ml之类的。编译工程只能用nmake了。vcproj工程文件怎么办？用scons重写一个吧。(其实命令行也有个vcbuild)。</p>
<p>制作绿色版之前，首先要安装一个VC，再把其中用到的文件提取出来。或者直接快进到后面找下载链接。</p>
<h4></h4>
<p>  <span id="more-448"></span><br />
<h4>Visual C++ 2008制作要领</h4>
<p>VC 2008的最大问题是Visual Studio采用Side-by-Side方式发布，不能简单的把依赖的DLL着全就行了。</p>
<p>1. 复制C:\Program Files\Microsoft Visual Studio&#160; 9.0\VC\bin及其子目录1033，到新的vc9\bin目录</p>
<p>2. 在复制VC目录下的lib和include目录，到新的vc9目录下</p>
<p>3. 复制C:\Program Files\Microsoft Visual Studio 2008\Common7\IDE目录下的：msobj80.dll，mspdb80.dll, mspdbcore.dll, mspdbsrv.exe到vc9\bin</p>
<p>4. 在vc\bin生成manifest文件，名为Micrisoft.VC90.CRT.manifest，内容如下</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000066;">standalone</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assembly</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;urn:schemas-microsoft-com:asm.v1&quot;</span> <span style="color: #000066;">manifestversion</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;noinheritable<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/noinheritable<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assemblyidentity</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Microsoft.VC90.CRT&quot;</span> <span style="color: #000066;">publickeytoken</span>=<span style="color: #ff0000;">&quot;1fc8b3b9a1e18e3b&quot;</span> <span style="color: #000066;">processorarchitecture</span>=<span style="color: #ff0000;">&quot;x86&quot;</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;9.0.21022.8&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;win32&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/assemblyidentity<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;file</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;msvcr90.dll&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/file<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;file</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;msvcp90.dll&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/file<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assembly<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>5. 找到Windows\WinSxS目录下的x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_&#8230;目录，复制其中的msvcr90.dll和msvcp90.dll到bin目录</p>
<h4>Visual C++ 2010制作要领</h4>
<p>VC 2010还在Beta阶段，不过据说已经决定不用SxS，直接用DLL发布了，所以制作简单点。</p>
<p>1-3和2008类似，复制bin, include, lib，复制Common7\IDE目录下的几个dll和exe</p>
<p>4. 到Windows\System32目录下找msvcr100.dll, msvcp100.dll，复制到bin</p>
<h4>Windows SDK</h4>
<p>VC的lib和include里面不带Windows的头文件和库，所以还需要把Windows SDK摘取出来。Windows SDK在安装的时候一般装在C:\Program Files\Microsoft SDKs\Windows\XX目录下，同样把其中的bin, lib, include目录复制出来，到一个新目录，比如win6sdk。</p>
<h4></h4>
<h4>环境设置</h4>
<p>影响C编译器的环境变量就三个，INCLUDE、LIB和PATH。设置好就可以编译了。假定上面我把VC 2008和Windows SDK分别复制到了vc9和win6sdk目录下，在与这两个目录的上级目录中，创建一个BAT脚本，假设叫vc9.bat，包含下面内容：</p>

<div class="wp_syntax"><div class="code"><pre class="bat" style="font-family:monospace;">@echo off
echo Setting environment Visual C++ 2010
&nbsp;
set VCINSTALLDIR=%~dp0vc9
set WindowsSdkDir=%~dp0win6sdk
&nbsp;
set INCLUDE=%WindowsSdkDir%\include;%VCINSTALLDIR%\include
set LIB=%WindowsSdkDir%\lib;%VCINSTALLDIR%\lib
set PATH=%FrameworkDir%\%FrameworkVersion%;%WindowsSdkDir%\bin;%VCINSTALLDIR%\bin;%PATH%</pre></div></div>

<p>再创建一个BAT脚本，叫start-vc9.bat，包含下面一行：</p>

<div class="wp_syntax"><div class="code"><pre class="bat" style="font-family:monospace;">start cmd /K %~dp0vc10.bat</pre></div></div>

<p>在Windows资源管理器中双击start-vc9.bat就可以配置好环境变量，进入VC 2008的编译环境了。</p>
<h4>下载</h4>
<p>1. vc10.rar 21M 2010的命令行工具和include/lib打包 <a href="http://www.uploadground.com/files/EPIKIHXP/vc10.rar" target="_blank">下载</a></p>
<p>需要和3解压到到一起用。双击start-vc10.bat打开一个命令行窗口，就可以用cl, nmake, link等命令了。VC需要的基本环境变量会自动设置。</p>
<p>2. vc9.rar 15M 2008的命令行工具和include/lib打包 <a href="http://www.uploadground.com/files/PY34KVNT/vc9.rar" target="_blank">下载</a></p>
<p>需要和3解压到一起用。双击start-vc9.bat打开命令行窗口，VC需要的环境变量会自动设置。</p>
<p>3. win7.rar 16M Windows 7.0 SDK的include/lib打包 <a href="http://www.uploadground.com/files/1FX250AB/win7.rar" target="_blank">下载</a></p>
<p>注意：命令行编译环境没有包含Debug版的CRT，所有的MFC、ATL的DLL。所以可能存在编译好的程序缺少DLL不能运行的问题。对于2008，可以下载一个VC相关SxS打包。缺DLL就到里面找(参见我的<a href="/2009/11/09/side-by-side-assembly/" target="_blank">Side-by-Side笔记</a>)。对于2010，由于已经废弃了SxS的发布方式，可以直接到网上下载缺的DLL。</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/13/visualc-compiler-portable/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>最近用scons的收获</title>
		<link>http://dipplum.com/2009/11/13/scons-tips/</link>
		<comments>http://dipplum.com/2009/11/13/scons-tips/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 07:59:28 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scons]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/13/scons-tips/</guid>
		<description><![CDATA[背景 Windows平台上的编译工程工具很多，Visual C++ 6的dsp文件，2003以后用的vcproj，以及最近2010支持的用msbuild编译的vcxproj，加上古老的nmake，cygwin、msys移植的make，等等很多。 make的问题是扩展性比较差，尤其是在Windows平台上，nmake的功能更弱，导致写一个工程文件很费劲，管理多个工程有大量的重复工作要做。make最大的问题是不能automake那种简洁的工程写法（automake同样存在扩展问题，m4语言不懂）. 最新的msbuild 4.0试用了一下，感觉不是很好，很费劲。因为最近迷恋上了命令行，一直不愿意安装完整的Visual Studio 2010 Beta 2，直接把2010的命令行拷贝出来用cl.exe之类的。想只装.Net Framework 4.0就试试msbuild，发现不行，把2010里的msbuild相关资源拷贝出来也不行。而且用XML手写工程文件很麻烦。 猛然想起之前听说过，鼎鼎大名，但之前简单了解后放弃了的scons。再次使用之后，才发现scons的妙处。 简介Scons Scons首页赫然是Eric Raymond的推荐，很是唬人的样子。Scons是python写的，这不重要。Scons脚本用语言是python，这是Scons最吸引人的地方。用python写工程文件无疑对我这种熟悉python的人有很大的吸引力。 实际上，Scons最大的优势，就是描述语言本身沿用python。这种设计极大的提升的Scons的扩展能力。Scons本身功能是否强大不重要，对于熟悉python的人来说，扩展Scons达到他的要求，变得比以前简单的多。下面是我用Scons写的一个zlib的工程文件，其中WinLib和WinDLL是我自己扩展的在Windows平台上编译静态库和动态库的方法（cl的宏定义和link的参数有所不同）。 target = 'libz' defs = 'ASMV ASMINF' incs = '.' &#160; Import&#40;'env'&#41; lib_src = Split&#40;'contrib/masmx86/inffas32.asm contrib/masmx86/gvmat32.asm adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c contrib/masmx86/gvmat32c.c'&#41; lib_src += env.RES&#40;'win32/zlib1.rc'&#41; dll_src = lib_src + Split&#40;'win32/zlib.def'&#41; [...]]]></description>
			<content:encoded><![CDATA[<h4>背景</h4>
<p>Windows平台上的编译工程工具很多，Visual C++ 6的dsp文件，2003以后用的vcproj，以及最近2010支持的用msbuild编译的vcxproj，加上古老的nmake，cygwin、msys移植的make，等等很多。</p>
<p>make的问题是扩展性比较差，尤其是在Windows平台上，nmake的功能更弱，导致写一个工程文件很费劲，管理多个工程有大量的重复工作要做。make最大的问题是不能automake那种简洁的工程写法（automake同样存在扩展问题，m4语言不懂）.</p>
<p>最新的msbuild 4.0试用了一下，感觉不是很好，很费劲。因为最近迷恋上了命令行，一直不愿意安装完整的Visual Studio 2010 Beta 2，直接把2010的命令行拷贝出来用cl.exe之类的。想只装.Net Framework 4.0就试试msbuild，发现不行，把2010里的msbuild相关资源拷贝出来也不行。而且用XML手写工程文件很麻烦。</p>
<p>猛然想起之前听说过，鼎鼎大名，但之前简单了解后放弃了的scons。再次使用之后，才发现scons的妙处。</p>
<h4></h4>
<p> <span id="more-432"></span><br />
<h4>简介Scons</h4>
<p>Scons首页赫然是Eric Raymond的推荐，很是唬人的样子。Scons是python写的，这不重要。Scons脚本用语言是python，这是Scons最吸引人的地方。用python写工程文件无疑对我这种熟悉python的人有很大的吸引力。</p>
<p>实际上，Scons最大的优势，就是描述语言本身沿用python。这种设计极大的提升的Scons的扩展能力。Scons本身功能是否强大不重要，对于熟悉python的人来说，扩展Scons达到他的要求，变得比以前简单的多。下面是我用Scons写的一个zlib的工程文件，其中WinLib和WinDLL是我自己扩展的在Windows平台上编译静态库和动态库的方法（cl的宏定义和link的参数有所不同）。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">target = <span style="color: #483d8b;">'libz'</span>
defs = <span style="color: #483d8b;">'ASMV ASMINF'</span>
incs = <span style="color: #483d8b;">'.'</span>
&nbsp;
Import<span style="color: black;">&#40;</span><span style="color: #483d8b;">'env'</span><span style="color: black;">&#41;</span>
lib_src = Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'contrib/masmx86/inffas32.asm contrib/masmx86/gvmat32.asm adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c contrib/masmx86/gvmat32c.c'</span><span style="color: black;">&#41;</span>
lib_src += env.<span style="color: black;">RES</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32/zlib1.rc'</span><span style="color: black;">&#41;</span>
dll_src = lib_src + Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32/zlib.def'</span><span style="color: black;">&#41;</span>
&nbsp;
Import<span style="color: black;">&#40;</span><span style="color: #483d8b;">'WinLib WinDLL'</span><span style="color: black;">&#41;</span>
lib = WinLib<span style="color: black;">&#40;</span>target, lib_src, CPPDEFINES=defs, CPPPATH=incs<span style="color: black;">&#41;</span>
dll = WinDLL<span style="color: black;">&#40;</span>target, dll_src, CPPDEFINES=defs, CPPPATH=incs<span style="color: black;">&#41;</span>
&nbsp;
Alias<span style="color: black;">&#40;</span>target, <span style="color: black;">&#91;</span>lib, dll<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>实际上Scons本身的功能比较有限，为了写成这个简洁的模式，还费了不少劲。</p>
<h4>Scons的特点</h4>
<p>简单列举下最近有体会的Scons的特点，权当备忘录了。</p>
<p>1. Variables的设计很好。</p>
<p>通过Variables可以扩展scons支持的命令行参数，限制参数种类（Bool，枚举，多选），可以把上次的参数保存到文件，下次编译不需要命令行输入过多的参数。下面摘下我的Variable定义：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">vars</span> = Variables<span style="color: black;">&#40;</span><span style="color: #483d8b;">'options.ini'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">vars</span>.<span style="color: black;">AddVariables</span><span style="color: black;">&#40;</span>
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'verbose'</span>, <span style="color: #483d8b;">'Show verbose messages'</span>, <span style="color: #483d8b;">'no'</span><span style="color: black;">&#41;</span>,
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'unicode'</span>, <span style="color: #483d8b;">'Use unicode API'</span>, <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#41;</span>,
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'debug'</span>, <span style="color: #483d8b;">'Generate debug code'</span>, <span style="color: #483d8b;">'no'</span><span style="color: black;">&#41;</span>,
    EnumVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'warn'</span>, <span style="color: #483d8b;">'Show warning level'</span>, <span style="color: #483d8b;">'no'</span>, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'no'</span>, <span style="color: #483d8b;">'low'</span>, <span style="color: #483d8b;">'all'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
    EnumVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'optimize'</span>, <span style="color: #483d8b;">'Set optimization mode'</span>, <span style="color: #483d8b;">'normal'</span>, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'normal'</span>, <span style="color: #483d8b;">'max'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'repos_root'</span>, <span style="color: #483d8b;">'Path to root of source repository'</span>, <span style="color: #483d8b;">'..'</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_root'</span>, <span style="color: #483d8b;">'Path to root of build directory'</span>, <span style="color: #483d8b;">'build'</span>,
        PathVariable.<span style="color: black;">PathIsDirCreate</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'output_root'</span>, <span style="color: #483d8b;">'Path to output directory'</span>, <span style="color: #483d8b;">'.'</span>,
        PathVariable.<span style="color: black;">PathIsDirCreate</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span>
env = Environment<span style="color: black;">&#40;</span>ENV = <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span>, variables = <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span></pre></div></div>

<p>2. Environment的设计也很好。</p>
<p>Environment可以保存全套的编译命令，参数配置，用Clone操作可以从一个基本编译环境作出很多变种，支持不同项目类型，不同配置的编译。Clone实在是太方便了。下面是前面提到的Windows平台下编译DLL和静态库、命令行程序的不同参数配置，用Clone操作可以在基本编译环境上，生成多个用于编译静态库、DLL等不同的编译环境，使用不同的参数编译。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">libEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
libEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'_WINDOWS _WINDLL'</span><span style="color: black;">&#41;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:WINDOWS'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
dllEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
dllEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_WINDOWS'</span><span style="color: black;">&#93;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:WINDOWS'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
conEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
conEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_CONSOLE'</span><span style="color: black;">&#93;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:CONSOLE'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>题外话，关于Windows下编译不同工程的参数，<a href="http://binglongx.spaces.live.com/blog/cns!142CBF6D49079DE8!276.entry" target="_blank">这篇文章</a>总结的很全。</p>
<p>3. Builder的设计问题。</p>
<p>Scons可以用env.Library(&#8216;liba&#8217;, &#8216;a.c&#8217;)的方法用环境的定义编译静态库，或者用Program定义可执行程序。并且支持输入和环境定义不同的参数，如</p>
<p>env.Library(&#8216;liba&#8217;, &#8216;a.c&#8217;, CPPDEFINES = ['NEWMACRO'], CCFLAGS=['/Ox'])。</p>
<p>不过，很可惜，Builder默认是覆盖环境中现有参数，而不是追加。所以，要用多个编译参数稍有不同的程序和库编译只能用Clone后Append。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">tempEnv = libEnv.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
tempEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'NEWMACRO'</span><span style="color: black;">&#93;</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'/Ox'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
tempEnv.<span style="color: black;">Library</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'liba'</span>, <span style="color: #483d8b;">'a.c'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>或许我要求太高，不过这样写看起来实在太傻了。实际使用中，不同的程序用的编译参数就没有完全一样的，尤其是Include目录、宏定义、库路径、库这四个参数肯定有或多或少的不一样。不能追加的话，就只能Clone出很多个Env，甚至是一个Program或Library一个Env，这就失去了Env封装编译环境的通用意义了。</p>
<p>4. Sconscript与源码的位置问题</p>
<p>Scons设计时更多是支持将Sconscript放在源码同一目录下，甚至每个源码目录一个Soncscript。如果不习惯或者不能用这种方式，比如为别的项目写工程文件，遇到一些困扰。</p>
<p>Scons好在有类似make的VPATH功能，叫Repository，用着还行。</p>
<p>5. 源码和编译目录分开的问题</p>
<p>这个问题和上面类似，但更严重。Scons支持用VariantDir设定与源码目录不同的编译目录，但必须所有的文件都用编译目录的路径，如下</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">VariantDir<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_dir'</span>, <span style="color: #483d8b;">'src_dir'</span><span style="color: black;">&#41;</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_dir/prog'</span>, <span style="color: #483d8b;">'build_src/main.c'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>这就很傻了，明明源码在src_dir目录，一定要写成build_src。不这么写也行，那就写两个Sconcript文件，一个引用另外一个</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#SConscriptA</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'prog'</span>, <span style="color: #483d8b;">'src/main.c'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#SConscriptB</span>
SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'build'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>要用好VariantDir，就必须写多个脚本。尤其是要支持编译同一程序的多个版本，还只能用两个脚本。SconscriptB可以按如下方式写，就能编译两个版本的prog，分别在debug和release目录下。用一个Sconscript完成同样功能实在是很费劲的。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'debug'</span><span style="color: black;">&#41;</span>
SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'release'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>6. 同一个源码编译多份的问题</p>
<p>这个问题和上面类似，但不同。例如编译静态库和动态库都用一批源码，但编译参数不一样，Scons就会报错。但这个问题用variant_dir解决不方便。如下例：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'hello1'</span>, <span style="color: #483d8b;">'hello.c'</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'-Od'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'hello2'</span>, <span style="color: #483d8b;">'hello.c'</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'-Ox'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Scons报错如下：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">scons: <span style="color: #000000; font-weight: bold;">***</span> Two environments with different actions were specified <span style="color: #000000; font-weight: bold;">for</span> the same target:</pre></div></div>

<p>经过我多方论证，发现这个问题目前看来最佳、最简单的解决方法是给OBJ文件设置前缀。</p>
<pre>Program('hello1', 'hello.c', OBJPREFIX='dbg-', CCFLAGS=['-Od'])
Program('hello2', 'hello.c', OBJPREFIX='opt-', CCFLAGS=['-Ox'])</pre>
<p>7. 简化编译输出的问题</p>
<p>Scons支持自定义的编译输出。但有些命令不能替换，例如msvc工具集中的链接过程的输出。</p>
<p>暂时这么多吧&#8230;想到再补充。</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/13/scons-tips/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
