[gradle] Gradle에서 현재 OS를 감지하는 방법

Groovy로 수행하는 방법에 대한 답변을 찾았습니다.

Groovy / Grails로 플랫폼 (Window 또는 Linux) 감지 :

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

더 좋은 방법이 있습니까?



답변

사실 저는 Gradle 프로젝트를 살펴 봤는데 Ant의 기존 구조를 사용하기 때문에 좀 더 깔끔해 보입니다 .

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

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

다음 Gradle 브랜치에서 이것을 발견했으며 잘 작동하는 것 같습니다. gradle / gradle-core / branches / RB-0.3 / build.gradle


답변

2020 년 중반 업데이트 : 아직 인큐베이팅 중 :

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

2019 년 초반 업데이트 : current()제거되었습니다.

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

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

그래도 여전히 배양 중이라는 것을 명심하십시오 .

2018 년 중반 업데이트 : 댓글에서 언급 한 것처럼 이제이 클래스가 다른 패키지로 옮겨 졌으므로org.gradle.nativeplatform.platform.OperatingSystem.current()


2015 년 중반 현재 Peter Kahn의 답변은 여전히 ​​유효합니다. 환경 기반 프로필 활성화는 여전히 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_UNIXMacOS 모두에서 true를 반환합니다 . 일반적으로 빌드 스크립트에 필요한 것은 아닙니다.

Gradle 2+ API를 사용하여이를 달성하는 또 다른 방법이 있습니다.

import org.gradle.internal.os.OperatingSystem;

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

org.gradle.nativeplatform.platform.OperatingSystem 인터페이스에 대한 문서를 확인하십시오 . 이 인터페이스에는 인큐베이팅 주석 이 표시되어 있습니다 . 즉, “이 기능은 현재 작업 중이며 언제든지 변경 될 수 있습니다.”라는 점을 언급 할 가치 가 있습니다. 구현의 “내부”네임 스페이스는 변경 될 수 있음을 알고이를 사용해야한다는 힌트를 제공합니다.

하지만 개인적으로이 솔루션을 사용하겠습니다. 미래에 무언가가 바뀔 경우에 엉망이되지 않도록 래퍼 클래스를 작성하는 것이 더 낫다는 것입니다.


답변

Linux, Unix, Windows 및 OS X간에 빌드 환경을 구분할 수 있으며 Gradle nativeplatform.platform.OperatingSystem대상 환경 ( FreeBSDSolaris 포함 )을 구분합니다.

import org.gradle.internal.os.OperatingSystem

String osName = OperatingSystem.current().getName();
String osVersion = OperatingSystem.current().getVersion();
println "*** $osName $osVersion was detected."

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

Ant 태스크 ( source )를 사용할 수도 있습니다 .

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

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


답변

Gradle은 운영 체제를 감지하기위한 공개 API를 제공하지 않습니다. 따라서 os.시스템 속성이 최선의 선택입니다.


답변

또는 osName을 문자열로 정의 할 수 있습니다.

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;
    }
}

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

편집하다:

아키텍처에 대해 동일한 작업을 수행 할 수 있습니다.

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

과:

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에서 OS를 감지하는 것을 좋아하지 않으며 OperatingSystem클래스에 더 이상 current()메서드 가 포함되어 있지 않습니다 .

따라서 제 생각에는 OS를 감지하는 가장 깨끗한 방법은 다음과 같습니다.

DefaultNativePlatform 가져 오기 :

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

그런 다음 DefaultNativePlatform작업에 사용 하십시오.

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

이 방법은 Gradle 내부 API를 사용하므로 이상적이지 않습니다.

Gradle 4.10으로 테스트되었습니다.


답변