web-dev-qa-db-ja.com

Androidサブプロジェクトを使用したGradleビルド

現在、プロジェクトの1つをMavenからGradleに変換しています。フォルダ構造は次のとおりです。

gitRoot
    settings.gradle
    build.gradle
    ProjectA
        build.gradle
        src/main/Java
    Libraries
        SomeLib (git submodule)
        ProjectBRoot (git submodule)
            settings.gradle
            build.gradle
            ProjectB
                build.gradle
                src/main/Java
            Libraries
                FacebookSDK/facebook
                    build.gradle
                    src

すでに複雑に見えます。しかし、アイデアはProjectBがライブラリプロジェクトであり、個別にビルドおよびパッケージ化できる必要があるため、独自のsettings.gradleがあり、うまくいくように見える限り、ビルドしていますその発見のfacebookはうまくいきます。

ProjectB/build.gradleにはこの行が含まれています

compile project(':libraries:facebook-Android-sdk:facebook')

ProjectBRoot/settings.gradleにはこの行が含まれています

include ':ProjectB', ':libraries:facebook-Android-sdk:facebook'

GitRoot/settings.gradleにはこの行が含まれています

include ':ProjectA', ':Libraries:ProjectBRoot:ProjectB'

ProjectA/build.gradleにはこの行が含まれています

compile project(':Libraries:ProjectBRoot:ProjectB')

ビルドを実行すると、このエラーが発生します

The TaskContainer.add() method has been deprecated and is scheduled to be removed in Gradle 2.0. Please use the create() method instead.

FAILURE: Build failed with an exception.

* Where:
Build file '/gitRoot/Libraries/ProjectBRoot/ProjectB/build.gradle' line: 17

* What went wrong:
A problem occurred evaluating project ':Libraries:ProjectBRoot:ProjectB'.
> Project with path ':libraries:facebook-Android-sdk:facebook' could not be found in project ':Libraries:ProjectBRoot:ProjectB'.

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

BUILD FAILED

Total time: 4.652 secs

何が間違っているのかは、facebookはProjectBの直接のサブフォルダーにないということですが、ProjectBRoot内でビルドする場合は問題になりません。これはおそらく、ProjectBRoot/gradle.buildではなく、ProjectBを直接参照しているためかもしれませんが、試してみましたが、うまくいきませんでした。誰かが私を助けてくれますか、ドキュメントを調べましたが、独自のsettings.gradleファイルを持つ複数のプロジェクトについては話していないので、それが私を混乱させていると思います。

更新:

だから私はXavの答えに従い、コマンドラインでビルドすることができますが、Android studio。私は問題がfacebookプロジェクトにまだあることを知っています。エラー。 ProjectBを構成できなかったということです。

 Gradle: A problem occurred configuring project ':ProjectA'.
   > Failed to notify project evaluation listener.
     > A problem occurred configuring project ':Libraries:ProjectBRoot:ProjectB'.
       > Failed to notify project evaluation listener.
         > Configuration with name 'default' not found.

エラーの原因は次のとおりです。

 compile project(':facebook-sdk')

projectB/build.gradle内

54
Stoyan

settings.gradleはすべてのモジュールを定義する必要があります。ツリーにある他のsettings.gradleをロードして、さらにモジュールをロードすることはありません。

どちらかをする必要があります

  1. 最上位のsettings.gradleでfacebook SDKのモジュールを定義します。はい、他のsettings.gradleでは冗長です。

  2. 何らかの方法でプロジェクトB(およびこの場合はfacebook SDKライブラリ)をどこか(たとえば企業のアーティファクトリポジトリ)に公開し、プロジェクトAからアクセスします。

#1の方が優れていますが、使用するsettings.gradleによってパスが異なるため、ProjectB-> Facebookの依存関係が複雑になります。これを修正する1つの方法は、モジュール名/パスをディスク上の実際の場所から分割することです。これはsettings.gradleファイル内で行われます。

最上位のsettings.gradleファイルで、

include 'facebook-sdk'
project(':facebook-sdk').projectDir = new File('Libraries/ProjectBRoot/Libraries/FacebookSDK/facebook')

プロジェクトB内のsetting.gradleファイルで、異なる相対パスで同じ操作を行います。

include 'facebook-sdk'
project(':facebook-sdk').projectDir = new File('Libraries/FacebookSDK/facebook')

これにより、両方のプロジェクトのセットアップで、ディスク上の同じ絶対位置にある同じ「facebook-sdk」モジュールが定義されます。

このモジュールに依存するすべてのプロジェクトは、依存関係を次のように宣言するだけです。

compile project(':facebook-sdk') 
94
Xavier Ducrohet

これはあなたが探している答えではありませんが、...

複雑なプロジェクト構造(実際のプロジェクトとほぼ同じ)をgradleに移行しようとして約4日間を費やしました。最終的に、サブプロジェクトのコンセプト全体を捨てました(私の場合、それは機能しなかったため)。この記事で説明されているように、ローカルのMavenリポジトリのアプローチを使用することを選択しました: http:/ /www.flexlabs.org/2013/06/using-local-aar-Android-library-packages-in-gradle-builds

そのため、サブプロジェクトを持つライブラリプロジェクトでは、基本的にそれぞれの完全なライブラリプロジェクトを作成し、上記のリンクを使用してそれらをMavenローカルリポジトリに公開しました。次に、親プロジェクトでサブプロジェクトへの参照を削除し、依存関係で公開されたライブラリを参照しました。そして、メインプロジェクトで、サブプロジェクトへのすべての参照を削除し、公開されたライブラリのMavenローカルバージョンを参照しました。

最終的には、すべてが非常にうまく機能しますが、すべてを変換するには時間がかかりました。サブプロジェクトを含む約6つのライブラリプロジェクト、そのサブプロジェクトなどがありましたが、現在はすべて正常に動作します。

GradleやMavenのようなシステムについて私が嫌いなのは、コード/プロジェクトをどのように構造化するかを変更することを本当に期待しているということです。そのため、Gradleから移行する場合とGradleから移行する場合、プロセスは非常にイライラする可能性があります。あなたがそれを理解したら、次回ははるかに簡単です;)

5
stuckless

私はちょうど同じレベルのライブラリを備えたアプリを持っているでしょう。 build.gradleファイルに基づいて各ライブラリをビルドおよびパッケージ化できます。何かが足りないかもしれませんが、構造はbuild.gradleファイルにあるものほど重要ではありません。同じフォルダーレベルにいる場合でも、projectBをFacebookに依存させることができます。

4
GrkEngineer

私の場合、同じ問題を抱えていたので、settings.gradleにプロジェクトを追加するのを忘れていました。その後、それは働いた

2
Weslor

最終的にプロジェクトをビルドできました(gradleエラーなし)。 Xavierからの回答はとても役に立ちました。

私は自分のプロジェクトをセットアップしようとしてほぼ3日間を費やし、完成に近づいていることは知っていますが、gradleビルドプロセス(dexDebug)の最後のステップで予期しないトップレベルの例外があります。

私のプロジェクトのセットアップはStoyanのものと非常に似ていますが、Androidサポートライブラリを参照しているAndroidライブラリプロジェクトが複数あります。最上位のルートプロジェクトのコンパイルに問題がある場合(support Androidが既に追加されているというエラー)が発生した場合は、jarを別のAndroidライブラリプロジェクト(スタンドアロンインスタンスに分解/分離)。

--| ProjectARoot
--| ProjectA (where main/Java etc are)
  --| build.gradle
--| settings.gradle
--| libraries
  --| ProjectBRoot
    --| settings.gradle
    --| ProjectB
    --| libraries
       --| Android-supports (Android lib project)
         --| libs
           --| Android-support-v4.jar
           --| Android-support-v13.jar
         --| build.gradle
       --| libA
         --| build.gradle (referencing Android-supports)'

AndroidプロジェクトをサポートするlibAを参照するlibAのビルドスクリプトの例

buildscript {
  repositories {
      maven { url 'http://repo1.maven.org/maven2' }
  }
  dependencies {
      classpath 'com.Android.tools.build:gradle:0.4'
  }
}
apply plugin: 'Android-library'

dependencies {
  compile project(':Android-support')
}

Android {
  compileSdkVersion 17
  buildToolsVersion "17.0.0"

  defaultConfig {
      minSdkVersion 7
      targetSdkVersion 17
  }
}

//トップルートsettings.gradle

include 'ProjectB', 'Android-support', ':ProjectA' (notice Project B is first than Android-support and lastly Project A)

project(':Android-support').projectDir = new File('libraries/ProjectBRoot/libraries/Android-support')
project(':ProjectB').projectDir = new File('libraries/ProjectBRoot/ProjectB')

現在、gradleビルドを実行するとこのエラーが発生します

:ProjectA:dexDebug

UNEXPECTED TOP-LEVEL EXCEPTION:
Java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
at com.Android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.Java:123)
at com.Android.dx.dex.file.DexFile.add(DexFile.Java:163)
at com.Android.dx.command.dexer.Main.processClass(Main.Java:490)
at com.Android.dx.command.dexer.Main.processFileBytes(Main.Java:459)
at com.Android.dx.command.dexer.Main.access$400(Main.Java:67)
at com.Android.dx.command.dexer.Main$1.processFileBytes(Main.Java:398)
at com.Android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.Java:245)
at com.Android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.Java:131)
at com.Android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.Java:109)
at com.Android.dx.command.dexer.Main.processOne(Main.Java:422)
at com.Android.dx.command.dexer.Main.processAllFiles(Main.Java:333)
at com.Android.dx.command.dexer.Main.run(Main.Java:209)
at com.Android.dx.command.dexer.Main.main(Main.Java:174)
at com.Android.dx.command.Main.main(Main.Java:91)
1 error; aborting
:ProjectA:dexDebug FAILED
1
Mike Kuasinski