假设我有一个软件,我以两个版本销售。
我如何使用Ant构建两个版本?
我的意思是,在代码中,据我所知,我会检查例如:
if(Editions.PRO)
{
// 'Pro' edition code
}
else
{
// 'Normal' edition code
}
和自Editions以来。PRO是"static final boolean" 上面的代码只有一部分会被编译。
我也可以使用不同的源文件,但这听起来很难维护。
我也可以使用接口,但那是......nm。
所以,"条件编译"(上面的)方法对我来说是最好的。
如何在Ant上实现呢?
Ant 可以操作"Editions"的值吗?PRO"在其文件中?
我觉得这听起来不太好。
相反,我在考虑用替换文件(使用Ant命令),或者甚至更好,排除定义"版本"的(真正的,dev)文件。和添加另一个文件夹作为类路径,该文件夹具有相同的文件,但带有"Editions. PRO"。PRO"相应配置(到所需版本)....我希望我讲清楚了。
你会怎么做?
首先,找到一种方法来重构你的代码,其中有"PRO版"类和"Demo版"类共享一个公共接口,然后其余的代码通过接口调用变量功能。
然后创建两个ant目标,一个"pro"目标和一个"demo"目标。然后,每个目标都排除抽象接口的非版本特定实现的编译或打包(取决于您想在哪里进行区分)。
这样你只能得到一个专业产品的专业实现,一个演示产品的演示实现,等等。
试图在if语句中嵌入功能是错误的。如果您这样做,为了编译代码,您需要同时使用专业代码和演示代码来构建专业或演示产品。此外,您(很可能)需要随演示产品一起发布这两组代码。这就留下了一种可能性,即有人会破坏你的pro/demo选择机制并激活演示产品中的pro版本代码。
Java中没有条件编译。你所描述的是条件执行。所有的代码都已编译并可供用户使用。如果您的目标是防止用户执行一个代码路径而不执行另一个,那么这将在基本级别上起作用。但是,如果您的意图是通过某种许可方案来控制功能,则很容易失败。
如果你真的想对用户保留一些特性,你需要将代码重构成两个不同的前端,以一些共同的后端代码。然后,在javac
任务的FileSet中使用Ant的排除属性,为正在构建的版本排除适当的前端。
在Java代码中替换令牌对我来说是有效的。在编译任务之前,我使用这样的内容:
<copy todir="${target.dir}/java" filtering="false">
<fileset dir="${src.dir}/java"/>
</copy>
<replace dir="${target.dir}/java" value="DEMO_MODE = ${demo.mode}">
<replacetoken>DEMO_MODE = true</replacetoken>
</replace>
首先将Java文件复制到一个临时位置,然后替换令牌。Javac这些复制的文件。${演示。Mode}甚至可以在命令行或属性文件中作为参数给出。DEMO_MODE是类中的公共静态final布尔变量。
还有两件对你有用的事:
你可以在target中设置条件属性分配:
<condition property="distribution.postfix" value="-demo" else="">
<equals arg1="${demo.mode}" arg2="true" />
</condition>
可以使用if和,除非条件:
<target name="demotarget" depends="jar" if="demo.mode">
...
</target>
实际上,我更喜欢PRO和DEMO版本的模块化和不同的目标,可能是可切换的功能,但我们在其他地方使用这个技巧,特别是开发与生产版本:开发代码包含更多的调试日志,我们不希望在生产软件中看到logLevel= debug配置。此外,生产代码混淆了,而开发代码没有,因此后者抛出可读的堆栈跟踪,例如