【问题标题】:Builds for different platforms the Maven way以 Maven 方式为不同平台构建
【发布时间】:2011-10-04 15:59:51
【问题描述】:

我有一个带有子模块 a:jar 的项目,它需要一组不同的依赖项,具体取决于它编译的平台。所有平台的代码都是相同的。例如。在 Android 上,httpcomponents 库已经与操作系统捆绑在一起,而我必须将它包含在 J2SE 环境的构建中。我还有另一个子模块,它将几个子模块及其依赖项组合成一个存档。如何可靠地配置程序集子模块,以获取为相应平台编译的所有子模块,以及适合该平台的依赖项?

我尝试使用配置文件创建a:jar:androida:jar:j2se。但是,声明对其中之一的依赖会导致程序集中出现奇怪的依赖关系。即,程序集项目的 dependency:tree 有时会包含对 a:jar:j2se 的依赖项(无论我声明在程序集中使用 a:jar:android 还是 a:jar:j2se 都没有关系),有时是另一个。在我更新本地存储库中a 的 jar 之后,它(经常)发生了变化。在装配项目中切换也使用配置文件。

我可以根据各个子模块配置文件的需要解决by applying the same dependencies to the assembly project's profiles。但由于我必须在 POM 中重复自己,可能有一种更专业的方法来实现这一点。由于我对 Maven 很陌生,我想知道它是什么?我不想复制代码(由于代码保持不变,这甚至会重复更多)并且我不喜欢复制 POM 的某些部分,因为由于版本升级而更改它们可能会变得复杂。

一些具体的材料:来自a:jar的POM的依赖:

  <dependencies>
    .....
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpmime</artifactId>
      <version>4.0.1</version>
      <scope>compile</scope>
      <!-- Exclusion in the common part, they are provided in the profiles from different sources -->
      <exclusions>
        <exclusion>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
        </exclusion>
        ....
      </exclusions>
    </dependency>
  </dependencies>
  <profiles>
    <profile>
      <id>android</id>
      <dependencies>
        <dependency>
          <groupId>com.google.android</groupId>
          <artifactId>android</artifactId>
          <version>1.6_r2</version>
          <scope>provided</scope>
        </dependency>   
      </dependencies>
    </profile>
    <profile>
      <id>java</id>
      <dependencies>
        <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>4.0.1</version>
          <scope>compile</scope>
        </dependency>
        <dependency>
          <groupId>commons-codec</groupId>
          <artifactId>commons-codec</artifactId>
          <version>1.3</version>
          <scope>compile</scope>
        </dependency>
      </dependencies>
    </profile>
  </profiles>

组装项目(使用 Maven 组装插件)配置文件:

  <profiles>
    <profile>
      <id>android</id>     
      <dependencies>
        <dependency>
          <groupId>a</groupId>
          <artifactId>a</artifactId>
          <version>${project.version}</version>
          <classifier>android</classifier>
          <type>jar</type>
        </dependency>
        <!-- Duplicate --> 
        <dependency>
          <groupId>com.google.android</groupId>
          <artifactId>android</artifactId>
          <version>1.6_r2</version>
          <scope>provided</scope>
        </dependency>   
        <!-- Duplicate --> 
      </dependencies>
    </profile>
    <profile>
      <id>java</id>
      <dependencies>
        <!-- Duplicate -->
        <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>4.0.1</version>
          <scope>compile</scope>
        </dependency>
        <dependency>
          <groupId>commons-codec</groupId>
          <artifactId>commons-codec</artifactId>
          <version>1.3</version>
          <scope>compile</scope>
        </dependency>
        <!-- /Duplicate --> 
        <dependency>
          <groupId>a</groupId>
          <artifactId>a</artifactId>
          <version>${project.version}</version>
          <classifier>java</classifier>
         <type>jar</type>
        </dependency>
      </dependencies>
    </profile>
  </profiles>

我想摆脱标记的依赖声明。

【问题讨论】:

    标签: maven maven-assembly-plugin profiles


    【解决方案1】:

    有几种解决方案:

    1. 可以将这些子模块的依赖项声明为“已提供”,在这种情况下,在项目中,您可以包含对子模块的依赖项以及平台没有的显式依赖项。

    2. 对不必要的依赖使用&lt;exclusions&gt;

    3. 使用上面的 (1) 或 (2) 创建另一个“结构”子模块 a-android:pom a-j2se:pom,它只描述依赖关系,并从您的项目中使用这些模块。

    【讨论】:

    • 所以对于 (3),“a-jse:pom”将继承自“a”。在“a”的 pom 中,我没有声明任何(或仅常见的)依赖项。在装配项目中,我将依赖“a-jse:pom”——对吗?这听起来是个好方法……
    • 是的,没错。我认为您必须在“a”中声明一些依赖项,因为它们可能是编译所必需的。这就是为什么你必须做(1)或(2)。另外,不要与“程序集”一词混淆,它与“Maven 程序集插件”无关。
    • 我更新了原始帖子以包含更具体的代码。现在我正试图弄清楚“a”和“a-j2se”必须如何正确地相互继承。
    • 所以,在“a”中你必须删除整个&lt;profiles&gt;块,然后在android项目中使用“a”(它会工作,因为平台提供了jar),添加“httpclient " 和 "codec" 依赖项也提供。并创建“a-java”项目,其中包括“a”、“httpclient”和“codec”。而且您根本不需要组装插件或配置文件。
    【解决方案2】:

    您可以将 maven 配置文件添加到 pom 并根据操作系统激活每个配置文件。配置文件激活确实支持这样的选项。然后在每个特定于操作系统的配置文件中,您可以列出可选的依赖项。这是一篇关于个人资料的文章 -> http://maven.apache.org/guides/introduction/introduction-to-profiles.html

    在你的情况下,它会是这样的:

    <profiles>
      <profile>
        <activation>
          <os>
            <family>Windows</family>
          </os>
        </activation>
        <dependencies>
          ... specific dependencies for Windows
        </dependencies>
        <plugins>
          ... specific build plugins for Windows
        </plugins>
      </profile>
      <profile>
        <activation>
          <os>
            <family>unix</family>
          </os>
        </activation>
        <dependencies>
          ... specific dependencies for unix
        </dependencies>
        <plugins>
          ... specific build plugins for unix
        </plugins>
      </profile>
      <dependencies>
        ... Common dependencies
      <dependencies>
      <plugins>
        ... Common build plugins
      </plugins>
    </profiles>
    

    【讨论】:

    • 操作系统特定的配置文件在这里不合适。它取决于构建服务器操作系统,但不取决于目标操作系统。此外,很有可能需要同时为多个目标平台构建多个项目。
    • @kan。您始终可以生成特定于操作系统的工件(事实上,如果您为不同的操作系统提供不同的组件,则必须这样做)。此外,在构建版本时,您可以按名称激活配置文件,这样您就可以在 CI 服务器上构建所需的所有配置文件,并且只在您的开发机器上构建适合您的开发环境的配置文件。
    • 如果您要为不同的操作系统使用不同的模块,您可以创建一个根 pom.xml,其中包含所有这些作为 &lt;module&gt; 并一次构建所有内容。对于配置文件,您必须多次调用 maven 并激活不同的配置文件。
    • 我知道配置文件(我更新了最初的帖子),但程序集插件没有使用对“a”的正确依赖。
    猜你喜欢
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2016-03-13
    相关资源
    最近更新 更多