使用Maven构建和部署本机代码

使用Maven构建和部署本机代码,maven,maven-release-plugin,Maven,Maven Release Plugin,我花了数年时间试图将使用本机代码的库部署到Maven Central。我遇到了以下问题: 没有任何好的插件可以使用Maven构建本机代码。这是一个非常严格的构建系统,除其他外,使得调试生成的二进制文件变得非常困难。您必须手动将本机maven插件构建系统与用于调试的本机IDE同步 Maven没有替换部署的pom.xml文件中的变量:。这意味着库必须为每个Maven概要文件声明一次特定于平台的依赖项(而不是声明一次依赖项并为每个概要文件设置不同的分类器);否则,依赖于您的库的任何人都必须在其项目文件

我花了数年时间试图将使用本机代码的库部署到Maven Central。我遇到了以下问题:

  • 没有任何好的插件可以使用Maven构建本机代码。这是一个非常严格的构建系统,除其他外,使得调试生成的二进制文件变得非常困难。您必须手动将本机maven插件构建系统与用于调试的本机IDE同步
  • Maven没有替换部署的pom.xml文件中的变量:。这意味着库必须为每个Maven概要文件声明一次特定于平台的依赖项(而不是声明一次依赖项并为每个概要文件设置不同的分类器);否则,依赖于您的库的任何人都必须在其项目文件中重新定义这些相同的属性,以解决可传递的依赖关系。看
  • Jenkins对跨不同平台运行类似逻辑的支持非常差(例如,“shell”与“批处理”任务,以及跨多台机器协调构建)
  • 在虚拟机中运行Windows、Linux和Mac太慢,太脆弱。即使你让它工作,尝试将虚拟机配置为Jenkins奴隶也是一个挫折的教训(你会经常遇到间歇性的构建错误)
  • Maven Central需要一个用于特定于平台的工件的主jar:
  • 假设可以从一台机器上以原子方式发布一个项目,但我需要在不同的机器上构建特定于操作系统的位

  • 我将用这个Stackoverflow问题来记录我是如何克服这些限制的。

    以下是我是如何克服上述问题的:

  • 我用来构建本机代码。该系统的优点在于,它为您喜爱的(本机)IDE生成项目文件。使用相同的项目文件编译和调试代码。您不再需要手动同步这两个系统。
    • Maven不支持CMake,所以我构建了自己的插件:
  • 我手动将特定于平台的依赖项硬编码到每个Maven概要文件中,而不是使用每个概要文件的不同分类器定义一次依赖项。这是更多的工作,但看起来他们不会很快在Maven中修复这个bug。
    • 我计划在不久的将来进行调查并作为替代方案
  • 在跨多台计算机协调构建方面做得很好
  • 在虚拟机上运行Jenkins奴隶仍然非常容易出错,但我已经设法解决了大部分问题。我已经上传了我的和,以帮助其他人开始
  • 现在,为了抑制Sonatype错误,我对特定于平台的工件进行了分析。这实际上是Sonatype的支持人员推荐的
  • maven release插件可能会委托给引擎盖下的其他插件。我不调用它,而是执行以下操作:
  • 使用
    mvn versions:set
    将版本号从快照更改为发行版,然后再更改
  • 自己标记并提交发布
  • 使用
    nexus staging:rc open
    nexus staging:deploy-DstagingProfileId=${stagingProfileId}-DstagingRepositoryId=${stagingpositoryid}
    nexus staging:rc close
    将不同平台的工件上载到同一存储库中。这称为“分段工作流”(参见下文)
  • 审查后,将存储库发布到Maven Central
  • 重要提示:不要启用
    ,不可能以原子方式释放快照工件(没有解决方法)。发布快照时,需要跳过
    rc open
    rc close
    并调用
    nexus staging:deploy
    ,而不使用
    -DstagingProfileId=${stagingProfileId}-DstagingRepositoryId=${stagingpositoryid}
    。每个工件都将上载到一个单独的存储库中
  • 请参阅my,以了解一个实际可行的示例

    其他需要注意的怪癖:

    • skipNexusStagingDeployMojo
      在最后一个反应堆模块中必须为false(否则不会部署任何工件):。最好的解决方法是使用Maven概要文件在部署时省略任何您想要的模块(根本不要使用
      skipNexusStagingDeployMojo
    • skipLocalStaging
      防止将多个工件部署到同一存储库中: