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

Building and deploying native code using Maven

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

  1. 没有任何好的插件可以使用 Maven 构建本机代码。 native-maven-plugin 是一个非常严格的构建系统,除其他外,它使得调试生成的二进制文件变得困难。您必须手动将 native-maven-plugin 构建系统与用于调试的本机 IDE 同步。
  2. Maven 没有替换部署的 pom.xml 文件中的变量:MNG-2971, MNG-4223. This meant that libraries had to declare platform-specific dependencies once per Maven profile (as opposed to declaring the dependency once and setting a different classifier per profile); otherwise, anyone who depended on your library had to re-define those same properties in their project file in order to resolve transitive dependencies. See Maven: Using inherited property in dependency classifier causes build failure.
  3. Jenkins 对 运行 跨不同平台的类似逻辑(例如 "shell" 与 "batch" 任务,以及协调跨多台机器的构建)
  4. 虚拟机中的
  5. 运行 Windows、Linux 和 Mac 太慢且脆弱。即使你让它工作,尝试将 VM 配置为 Jenkins 从站也是一个令人沮丧的教训(你会经常出现间歇性构建错误)。
  6. Maven Central 需要一个用于特定于平台的工件的主 jar:OSSRH-975
  7. Sonatype OSS Repository Hosting and maven-release-plugin 假设可以从一台机器上以原子方式发布一个项目,但我需要在不同的机器上构建 OS-specific 位。

我将使用这个 Whosebug 问题来记录我是如何设法克服这些限制的。

以下是我克服上述问题的方法:

  1. 我使用 CMake 构建本机代码。这个系统的美妙之处在于它为你最喜欢的(原生)生成项目文件IDE。您使用相同的项目文件来编译和调试代码。您不再需要手动同步两个系统。
  2. 我手动将特定于平台的依赖项硬编码到每个 Maven 配置文件中,而不是为每个配置文件使用不同的分类器一次定义依赖项。这是更多的工作,但看起来他们不会很快修复 Maven 中的这个错误。
  3. Jenkins pipeline 在跨多台机器编排构建方面做得很好。
  4. 运行 虚拟机上的 Jenkins slaves 仍然很容易出错,但我已经设法解决了大部分问题。我已经上传了我的 VMWare configuration steps and Jenkins job configuration 来帮助其他人开始。
  5. 我现在 create an empty JAR file 用于平台特定的工件以抑制 Sonatype 错误。这实际上是 Sonatype 的支持人员推荐的。
  6. turns out maven-release-plugin 委托给引擎盖下的其他插件。我没有调用它,而是执行以下操作:
    1. 使用 mvn versions:set 将版本号从 SNAPSHOT 更改为发布并返回。
    2. 自己标记并提交发布。
    3. 使用 nexus-staging:rc-opennexus-staging:deploy -DstagingProfileId=${stagingProfileId} -DstagingRepositoryId=${stagingRepositoryId}nexus-staging:rc-close 将来自不同平台的工件上传到同一存储库。这称为 Staging Workflow(在下面引用)。
    4. 审核后,将存储库发布到 Maven Central。
    5. 重要提示:不要在 nexus-staging 插件中启用 <autoReleaseAfterClose>,因为它会在每次部署后关闭暂存存储库,而不是等待所有部署完成。
    6. 根据 https://issues.sonatype.org/browse/NEXUS-18753 不可能以原子方式释放 SNAPSHOT 工件(没有解决方法)。释放快照时,需要跳过rc-openrc-close并调用nexus-staging:deploy而不调用-DstagingProfileId=${stagingProfileId} -DstagingRepositoryId=${stagingRepositoryId}。每个工件都将上传到单独的存储库中。

请参阅我的 Requirements API 以获取有效的真实示例。

其他需要注意的怪癖: