如何从 Gradle 检测当前的操作系统

我找到了如何使用 Groovy 的答案:

通过 Groovy/Grails 检测平台(窗口或 Linux) :

if (System.properties['os.name'].toLowerCase().contains('windows')) {
println "it's Windows"
} else {
println "it's not Windows"
}

Is there a better way?

63338 次浏览

Gradle 没有提供检测操作系统的公共 API,因此 os.系统属性是最好的选择。

实际上,我看了一下 Gradle 项目,它使用了 Ant's现有的结构,看起来更干净一些:

import org.apache.tools.ant.taskdefs.condition.Os


task checkWin() << {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
println "*** Windows "
}
}

我在下面的 Gradle 分行中发现了这个,它似乎工作得很好

2020年年中更新 仍在酝酿中:

OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem;

Early 2019 Update: current() removed.

org.gradle.nativeplatform.platform.OperatingSystem.getDisplayName()

org.gradle.nativeplatform.platform.OperatingSystem.isLinux()

请记住,它仍然是 正在孵化虽然。

2018年中期更新 : 就像在评论中提到的那样,现在这个类移到了一个不同的包中,所以应该使用 < a href = “ https://docs.gradle.org/current/javadoc/org/gradle/nativePlatform/Platform/OperatingSystem.html”rel = “ noReferrer”> org.gradle.nativeplatform.platform.OperatingSystem.current()


截至2015年年中,彼得•卡恩的回答仍然有效。在 Maven 中,基于环境的概要文件激活仍然相对容易。但是请记住,org.apache.tools.ant.taskdefs.condition.Os.isFamily并不是排他的,因为如果它使用一个特定的参数返回 true,并不一定意味着它使用其他任何参数返回 false。例如:

import org.apache.tools.ant.taskdefs.condition.Os
task detect {
doLast {
println(Os.isFamily(Os.FAMILY_WINDOWS))
println(Os.isFamily(Os.FAMILY_MAC))
println(Os.isFamily(Os.FAMILY_UNIX))
}
}

对于 MacOS 上的 Os.FAMILY_MACOs.FAMILY_UNIX,它都将返回 true。通常它不是构建脚本中需要的东西。

不过,还有另一种方法可以通过 Gradle 2 + API 来实现这一点,即:

import org.gradle.internal.os.OperatingSystem;


task detect {
doLast {
println(OperatingSystem.current().isMacOsX())
println(OperatingSystem.current().isLinux())
}
}

查看 本地平台平台操作系统接口的文档。值得一提的是,这个接口标有 incubating注释,也就是说,“这个特性目前还在进行中,随时可能发生变化”。实现中的“内部”命名空间也给了我们一个提示,即我们应该使用这个命名空间,因为我们知道这个命名空间可能会发生变化。

但就我个人而言,我会选择这个解决方案。只是最好编写一个包装类,以免在将来发生变化时出现问题。

我们可以在 Linux、 Unix、 Windows 和 OS X 之间区分 建造环境,而 Gradle 操作系统区分 目标环境(包括。FreeBSD索拉里斯)。

import org.gradle.internal.os.OperatingSystem
OperatingSystem os = OperatingSystem.current();


println "*** Building on ${os.familyName} / ${os.name} / ${os.version} / ${System.getProperty("os.arch")}."


println "*** Building on ${os.toString()}."


if (os.isLinux()) {
// Consider Linux.
} else if (os.isUnix()) {
// Consider UNIX.
} else if (os.isWindows()) {
// Consider Windows.
} else if (os.isMacOsX()) {
// Consider OS X.
} else {
// Unknown OS.
}

还可以使用 Ant 任务(来源) :

import org.apache.tools.ant.taskdefs.condition.Os


task checkWin() << {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// Consider Windows.
}
}

Or you can define osName as a string...

import org.gradle.internal.os.OperatingSystem


switch (OperatingSystem.current()) {
case OperatingSystem.LINUX:
project.ext.osName = "Linux";
break;
case OperatingSystem.MAC_OS:
project.ext.osName = "macOS";
break;
case OperatingSystem.WINDOWS:
project.ext.osName = "Windows";
break;
}

... 并在以后使用它-包括一个本地图书馆,例如:

run {
systemProperty "java.library.path", "lib/$osName"
}

但这不会改变任何事情,因为 OperatingSystem 的工作原理和你的代码一模一样:

public static OperatingSystem forName(String os) {
String osName = os.toLowerCase();
if (osName.contains("Windows")) {
return WINDOWS;
} else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
return MAC_OS;
} else if (osName.contains("sunos") || osName.contains("solaris")) {
return SOLARIS;
} else if (osName.contains("linux")) {
return LINUX;
} else if (osName.contains("freebsd")) {
return FREE_BSD;
} else {
// Not strictly true
return UNIX;
}
}

Source: https://github.com/gradle/gradle/blob/master/subprojects/base-services/src/main/java/org/gradle/internal/os/OperatingSystem.java

编辑:

You can do the same for the architecture:

project.ext.osArch = OperatingSystem.current().getArch();
if ("x86".equals(project.ext.osArch)) {
project.ext.osArch = "i386";
}

and:

run {
systemProperty "java.library.path", "lib/$osName/$osArch"
}

请注意,getArch()将返回:

  • 在 PowerPC 上的「 ppc 」
  • 64b 上的“ amd64”
  • 32b 上的“ i386”或“ x86”。

对于任何其他平台,getArch()将在 Solaris 上返回“ x86”或“ i386”。

编辑2:

或者,如果你想避免任何重要性,你可以自己动手:

def getOsName(project) {
final String osName = System.getProperty("os.name").toLowerCase();


if (osName.contains("linux")) {
return ("linux");
} else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
return ("macos");
} else if (osName.contains("windows")) {
return ("windows");
} else if (osName.contains("sunos") || osName.contains("solaris")) {
return ("solaris");
} else if (osName.contains("freebsd")) {
return ("freebsd");
}
return ("unix");
}


def getOsArch(project) {
final String osArch = System.getProperty("os.arch");


if ("x86".equals(osArch)) {
return ("i386");
}
else if ("x86_64".equals(osArch)) {
return ("amd64");
}
else if ("powerpc".equals(osArch)) {
return ("ppc");
}
return (osArch);
}

我不喜欢通过属性或 Ant 任务来检测 Gradle 的操作系统,而且 OperatingSystem类不再包含 current()方法。

因此,在我看来,检测操作系统最干净的方法是:

Import DefaultNativePlatform:

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

然后在你的任务中使用 DefaultNativePlatform:

if (DefaultNativePlatform.getCurrentOperatingSystem().isWindows()) {
println 'Windows'
}

请注意,这种方法并不理想,因为它使用的是 Gradle 内部 API。

它是用4.10级测试的。

在没有任何导入的情况下,我从 System类得到了这些值,如下所示:

def osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH)
def osArch = System.getProperty("os.arch").toLowerCase(Locale.ENGLISH)
def osVersion = System.getProperty("os.version").toLowerCase(Locale.ENGLISH)

根据@shabunc 的回答,你的一些选择是:

  1. org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
  2. org.apache.tools.ant.taskdefs.condition.Os
  3. org.gradle.nativeplatform.platform.OperatingSystem
  4. org.gradle.internal.os.OperatingSystem

数字3和4基本上是相同的接口,其中 OperatingSystem.current()实际上是 OperatingSystem.isCurrent()(因为 Groovy)。所以这对我不起作用。

2号是一个可行的选择,但恕我直言,它并不那么优雅。

这就是您如何使用选项1(因为没有包含示例) :

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform


def os = DefaultNativePlatform.currentOperatingSystem
def arch = DefaultNativePlatform.currentArchitecture
def version = "1.0.0"


switch (true) {
case os.windows && arch.i386:
implementation "com.example:example-win32-x86:${version}"
break
case os.windows && arch.amd64:
implementation "com.example:example-win32-x86-amd64:${version}"
break
case os.macOsX && arch.amd64:
implementation "com.example:example-darwin-x86-amd64:${version}"
break
case os.linux && arch.i386:
implementation "com.example:example-linux-x86:${version}"
break
case os.linux && arch.amd64:
implementation "com.example:example-linux-x86-amd64:${version}"
break
default:
println "No suitable driver found for " +
"current OS (${os.displayName}) and " +
"architecture (${arch.displayName})"
}