| 개요

 

keystore 정보는 ProjectSettings.asset 파일에 아래와 같이 저장된다. 

  AndroidKeystoreName: '{inproject}: Keystore/name.keystore'
  AndroidKeyaliasName: name
...중략...
  androidUseCustomKeystore: 1


하지만 비밀번호와 같은 정보는 별도로 저장되다보니
체크아웃을 새로 받을 때마다, keystore 세팅을 다시 해줘야했다.

 

 

| 현상

 

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':launcher:packageRelease'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > com.android.ide.common.signing.KeytoolException: Failed to read key creature from store "/Users/${USER}/.jenkins/workspace/${PROJECT_NAME}/Keystore/user.keystore": Keystore was tampered with, or password was incorrect

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.1.1/userguide/command_line_interface.html#sec:command_line_warnings

ProjectSettings.asset 파일에는 androidUseCustomKeystore값은 1로 남아있는데,

alias나 비밀번호 같은 값이 날아가 버려서 위와 같은 에러가 발생한다.

 

 

| 해결

 

using UnityEditor;
using UnityEngine;

namespace Tools.Settings
{
    [FilePath("UserSettings/BuildConfigs.asset", FilePathAttribute.Location.ProjectFolder)]
    public class BuildConfigs : ScriptableSingleton<BuildConfigs>
    {
        public string __ks_pass;
        public string __ks_key_alias;
        public string __key_pass;

        public string KeyStorePassword => Base64.Decode(__ks_pass);
        public string KeyAlias => Base64.Decode(__ks_key_alias);
        public string KeyPass => Base64.Decode(__key_pass);

        public void Save()
        { 
            Save(true); 
        }
    }

    sealed class BuildConfigsProvider : SettingsProvider
    {
        public const string Url = "{url}/manage/configure";

        public BuildConfigsProvider()
          : base("Preferences/Build Configs", SettingsScope.User) 
        {

        }

        public override void OnGUI(string search)
        {
            var settings = BuildConfigs.instance;

            var __ks_pass = settings.KeyStorePassword;
            var __ks_key_alias = settings.KeyAlias;
            var __key_pass = settings.KeyPass;

            EditorGUI.BeginChangeCheck();

            __ks_pass = EditorGUILayout.PasswordField("--ks-pass", __ks_pass);
            __ks_key_alias = EditorGUILayout.PasswordField("--ks-key-alias", __ks_key_alias);
            __key_pass = EditorGUILayout.PasswordField("--key-pass", __key_pass);

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Overview"))
            {
                Application.OpenURL(Url);
            }
            GUILayout.EndHorizontal();

            if (EditorGUI.EndChangeCheck())
            {
                settings.__ks_pass = Base64.Encode(__ks_pass);
                settings.__ks_key_alias = Base64.Encode(__ks_key_alias);
                settings.__key_pass = Base64.Encode(__key_pass);
                settings.Save();
            }
        }
    }

    static class BuildConfigsRegister
    {
        [SettingsProvider]
        public static SettingsProvider CreateCustomSettingsProvider()
          => new BuildConfigsProvider();
    }
}

CI 툴에서 파라미터로 전달해도 되지만, 

버전 관리 툴에서 관리되었으면 해서 UserSettings에 값을 저장할 수 있도록 하였다.

 

 

 

| 참고

 

 

Unity - Scripting API: SettingsProvider

In order to add new Project settings or preference pages, define a SettingsProvider. The SettingsProvider class provides the hooks to display any UI (using either IMGUI or UIElements to draw it). It also provides an API that allows you to specify keywords

docs.unity3d.com

 

반응형

| 현상

 

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/<user>/.jenkins/workspace/<job>/GradleProject/unityLibrary/build.gradle' line: 176

* What went wrong:
Execution failed for task ':unityLibrary:BuildIl2CppTask'.
> NDK is not installed

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/7.2/userguide/command_line_interface.html#sec:command_line_warnings

Gradle 빌드 중 설치된 NDK를 인식하지 못하는 현상

UnityHub가 도입되고 고도화되면서 Unity 설치 시에 각 플랫폼 별 빌드 지원하는 툴들을 설치하게 되었다.

그 후로는 유사한 이슈가 발생하지 않았는데 2021.3.22f1버전에서 2022.3.6f1버전으로 업그레이드 하면서 발생했다.

 

 

| 해결

 

using System.IO;
using UnityEditor.Android;

namespace Tools
{
#if UNITY_2022_3_OR_NEWER
    public class AndroidPostBuildProcessor : IPostGenerateGradleAndroidProject
    {
        public int callbackOrder => 1;

        public void OnPostGenerateGradleAndroidProject(string path)
        {
            Debug.Log("OnPostGenerateGradleAndroidProject: " + path);

            var di = new DirectoryInfo(path);
            var localPropertiesFile = Path.Combine(di.Parent.FullName, "local.properties");
            if (File.Exists(localPropertiesFile))
            {
                var hasNdkProp = HasNdkProp(localPropertiesFile);
                if (false == hasNdkProp)
                {
                    var ndkDir = $"{System.Environment.NewLine}ndk.dir={AndroidExternalToolsSettings.ndkRootPath}";
                    File.AppendAllText(localPropertiesFile, ndkDir);
                }
            }
        }

        private bool HasNdkProp(string path)
        {
            using (var streamReader = new StreamReader(path, System.Text.Encoding.UTF8))
            {
                string line = string.Empty;
                while ((line = streamReader.ReadLine()) != null)
                {
                    if (line.StartsWith("ndk.dir="))
                        return true;                    
                }
            }
            return false;
        }
    }
#endif
}

근본적인 해결책은 아니지만 
Android Project를 생성할 때, local.properties 파일에 NDK 정보를 입력하는 식으로 해결하였다.

| 참고

 

 

빌드 구성  |  Android 개발자  |  Android Developers

Android 빌드 시스템은 앱 리소스 및 소스 코드를 컴파일하고 개발자가 테스트, 구축, 서명 및 배포할 수 있는 APK로 패키징합니다.

developer.android.com

 

Unity - Scripting API: LocalPropertiesFile

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

※ 2023.1버전대부터 Ndk, LocalPropertiesFile 등 Gradle 관련 세팅을 제어하는 클래스들이 Unity.Android.Gradle 네임스페이스에 추가된다.

 

 

Unity - Scripting API: AndroidExternalToolsSettings

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

※ Preferences > External Toos > Android에서 설정한 값들을 위 클래스를 통해 제어할 수 있다.

반응형

| 현상

 

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':unityLibrary:parseReleaseLocalResources'.
> Could not resolve all dependencies for configuration ':unityLibrary:androidApis'.
   > Using insecure protocols with repositories, without explicit opt-in, is unsupported. Switch Maven repository 'maven4(http://maven.singular.net)' to redirect to a secure protocol (like HTTPS) or allow insecure protocols. See https://docs.gradle.org/7.2/dsl/org.gradle.api.artifacts.repositories.UrlArtifactRepository.html#org.gradle.api.artifacts.repositories.UrlArtifactRepository:allowInsecureProtocol for more details. 

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/7.2/userguide/command_line_interface.html#sec:command_line_warnings

Unity3d를 2021.3.22f1버전에서 2022.3.6f1버전으로 업그레이드 하면서 
그래들 버전이 달라져서 그런지 http 리포지터리를 허용하지 않았다.

 

 

| 해결

 

1. 사용하고 있는 Plugin을 최신화

Plugin이 업데이트 되면서 repository가 변경되었을 수 있기 때문

 

2. Plugin내부 Dependencies.xml 파일 수정

<dependencies>
  <androidPackages>
    <repositories>
      <repository>https://repo.maven.apache.org/maven2</repository>
... 중략...
    </repositories>
  </androidPackages>
</dependencies>

임시방편으로 해당 repository를 secure protocol로 변경한다.

 

3. allowInsecureProtocol 설정

repositories {
    maven {
        url "http://..."
        allowInsecureProtocol true
    }
    mavenCentral()
}

 

 

| 참고

 

 

MavenArtifactRepository - Gradle DSL Version 8.3

An artifact repository which uses a Maven format to store artifacts and meta-data. Repositories of this type are created by the RepositoryHandler.maven(org.gradle.api.Action) group of methods. PropertyDescriptionallowInsecureProtocolSpecifies whether it is

docs.gradle.org

 

반응형

| 현상

 

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':unityLibrary:hive.androidlib:compileReleaseAidl'.
> Failed to install the following Android SDK packages as some licences have not been accepted.
     build-tools;30.0.3 Android SDK Build-Tools 30.0.3
  To build this project, accept the SDK license agreements and install the missing components using the Android Studio SDK Manager.
  Alternatively, to transfer the license agreements from one workstation to another, see http://d.android.com/r/studio-ui/export-licenses.html
  
  Using Android SDK: /Applications/Unity/Hub/Editor/2021.3.22f1/PlaybackEngines/AndroidPlayer/SDK

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 24s

 

| 해결방법

 

  • Android Studio > Tools > SDK Manager

  • Android SDK > SDK Tools > Goolgle Play Licensing Library > Apply

반응형

| 현상

 

FAILURE: Build failed with an exception.
 
* What went wrong:
Execution failed for task ':stripReleaseDebugSymbols'.
> No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
 
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
 
* Get more help at https://help.gradle.org
 
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.5/userguide/command_line_interface.html#sec:command_line_warnings
 
BUILD FAILED in 36s

위 에러가 발생하며 빌드에 실패하는 현상

 

 

| 원인

 

그래들 버전에 맞는 NDK가 설치되어 있지 않아 발생

 

 

| 해결방법

 

구분 버전
Gradle 5.5
NDK android-ndk-r16b

 

 

반응형

| 현상

 

Gradle 빌드 시, 아래와 같은 에러가 나며 빌드에 실패하는 현상이 발생

WARN: Unable to load JNA library (OS: Mac OS X 11.5.2)
java.lang.UnsatisfiedLinkError: /Users/<user>/Library/Caches/JNA/temp/jna13372397078913963777.tmp: dlopen(/Users/<user>/Library/Caches/JNA/temp/jna13372397078913963777.tmp, 1): no suitable image found.  Did find:
	/Users/<user>/Library/Caches/JNA/temp/jna13372397078913963777.tmp: no matching architecture in universal wrapper
	/Users/<user>/Library/Caches/JNA/temp/jna13372397078913963777.tmp: no matching architecture in universal wrapper
	at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
	at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)

리서치 결과 JNA, M1칩셋 관련 이슈인듯 하다.

 

 

 

https://seanking.dev/blog/2021/01/31/Apple-Silicon/

Apple Silicon It has been about a month since I purchased a new Apple MacBook Air with an M1 processor. The machine was purchased for personal use, so I don’t use it for a lot of development, but I have used it as a trial run for future professional purc

seanking.dev

 

| 해결방법

 

  • Jenkins > Manage Jenkins > Configure System > Global properties > Environment variables로 이동
  • JAVA_HOME에서 1.8.0버전의 OpenJDK로 변경

 

- JAVA_HOME=/opt/homebrew/Cellar/openjdk@11/11.0.12/libexec/openjdk.jdk/Contents/Home
+ JAVA_HOME=/Applications/Unity/Hub/Editor/2019.4.15f1/PlaybackEngines/AndroidPlayer/OpenJDK

기존에는 OpenJDK 11버전으로 빌드를 진행했었는데, 

유니티 설치 시 같이 설치해뒀던, OpenJDK 1.8.0버전으로 JAVA_HOME을 설정하였더니 해결되었다.

반응형

| 현상

Manifest merger failed: Attribute application@allowBackup value=(false) from [:unityLibrary:sdk] AndroidManifest.xml:line
  is also present at [plugin:version] AndroidManifest.xml:line value=(true).
  Suggestion: add 'tools:replace="android:allowBackup"' to <application element at AndroidManifest.xml:line to override.

Third Party 플러그인들을 프로젝트에 통합하는 과정에서

AndroidManifest.xml 병합이 실패하는 현상이 발생하곤 한다.

원인은 AndroidManifest.xml에서 병합규칙 마커없이 동일한 속성에 대해 각각 다른 값을 설정하고 있기 때문이다.
(위 상황에선 android:allowBackup 속성이 문제가 되었다)

보통의 경우엔 우선순위나 값의 유무에 따라서 휴리스틱하게 처리되지만, 같은 속성에 대해서 다른 값을 지정하면 병합 과정에서 충돌 오류가 발생한다.


​| 해결방법

// launcher/src/main/AndroidManifest.xml
<?xml ...
...
  <application tools:replace="android:allowBackup" android:allowBackup="false" />
...

위의 에러로그에의 제안처럼 AndroidManifest.xml에 tools:replace=”android:allowBackup” 병합규칙을 추가하면 문제가 해결된다.

 

| 참고

 

다중 manifest 파일 병합  |  Android 개발자  |  Android Developers

manifest 병합 및 manifest 병합 도구에 관해 자세히 알아보세요.

developer.android.com

 

 

자동 백업으로 사용자 데이터 백업  |  Android 개발자  |  Android Developers

앱의 자동 백업은 Android 6.0(API 수준 23) 이상에서 타겟팅하거나 실행되는 앱의 사용자 데이터를 자동으로 백업합니다. Android는 앱 데이터를 사용자의 Google Drive에 업로드하여 보존하며, 이곳의 앱

developer.android.google.cn

 

반응형

아이스팩 수거함: o

- 건물 외에 위치

 

반응형

+ Recent posts