Скрипт Gradle, который выбирает вариант сборки библиотеки Android - PullRequest
0 голосов
/ 25 февраля 2019

Я использую Eclipse и работаю с проектами Android.Я не могу использовать Android Studio по многим причинам.К сожалению, Eclipse не способен работать с архивами AAR.После долгой борьбы мы решили сделать проекты Eclipse НЕГРЕЙДНЫМИ (исключить характер gradle из всех проектов Eclipse) и подготовить список зависимостей с помощью специального скрипта gradle.Чтобы сделать возможной работу с Android, я написал следующий скрипт gradle, который выполняет следующее:

  1. поиск всех зависимостей во всех проектах
  2. copyзависимости от кэша gradle до специального проекта Eclipse "jars-from-gradle"

  3. составляют ".classpath" для всех проектов, чтобы использовать только найденные библиотеки

Вот скрипт gradle:

apply plugin: "eclipse"

configurations {
    eclipseOnly {
        description = 'this is used only to build eclipse classpath'
    }
}

afterEvaluate{

  project.tasks['eclipseProject'].dependsOn(project.tasks['cleanEclipseProject'])
  project.tasks['eclipseClasspath'].dependsOn(project.tasks['cleanEclipseClasspath'])

  eclipse{

    File f = rootProject.ext.find("explodedAarsDir");
    if(f == null) {
        f = new File("${rootProject.projectDir}/jars-from-gradle/explodedAars/");
        rootProject.ext.set("explodedAarsDir", f)
        f.mkdirs();
    }
    f = rootProject.ext.find("globalDependenciesRepo");
    if(f == null) {
        f = new File("${rootProject.projectDir}/jars-from-gradle/libs");
        rootProject.ext.set("globalDependenciesRepo", f)
        f.mkdirs();
    }
    org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory frf = rootProject.ext.find("fileReferenceFactory");
    if(frf == null) {
        frf = new org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory();
        rootProject.ext.set("fileReferenceFactory", frf)
    }

    if(!rootProject.ext.has("eclipseFileMapping")) {
        rootProject.ext.set("eclipseFileMapping", new HashMap<File, File>())
    }
    Map<File, File> eclipseFileMapping = rootProject.ext.get("eclipseFileMapping")
    eclipseFileMapping.put(new File("bin/main"), new File("bin"))
    eclipseFileMapping.put(new File("bin/test"), new File("bin"))
    eclipseFileMapping.put(new File("${buildDir}/classes/java/main"), new File("${projectDir.parentFile}/${project.name}/bin"))
    eclipseFileMapping.put(new File("${buildDir}/classes/java/test"), new File("${projectDir.parentFile}/${project.name}/bin"))
    eclipseFileMapping.put(new File("${buildDir}/resources/main"), new File("${projectDir.parentFile}/${project.name}/bin"))
    eclipseFileMapping.put(new File("${buildDir}/resources/test"), new File("${projectDir.parentFile}/${project.name}/bin"))

    configurations {
      eclipsePlusConfig {
        description = "files to include into eclipse classpath"
        transitive = false
      }
      eclipseMinusConfig {
        description = "files to exclude from eclipse classpath"
        transitive = false
      }
    }

    project{
      setupEclipseProject()
    }

    classpath{
      defaultOutputDir = new File("${projectDir}/bin")
      plusConfigurations += [project.configurations.eclipseOnly]
      if(project.extensions.findByName("android") != null) {
          plusConfigurations += [project.configurations.compile]
          plusConfigurations += [project.configurations.runtime]
          project.eclipse.project{
              natures 'org.eclipse.andmore.AndroidNature'
              buildCommands.clear()
              buildCommand "org.eclipse.andmore.ResourceManagerBuilder"
              buildCommand "org.eclipse.andmore.PreCompilerBuilder"
              buildCommand "org.eclipse.jdt.core.javabuilder"
              buildCommand "org.eclipse.andmore.ApkBuilder"
              containers 'org.eclipse.andmore.DEPENDENCIES', 'org.eclipse.andmore.LIBRARIES', 'org.eclipse.andmore.ANDROID_FRAMEWORK'
          }
      } else {
          plusConfigurations += [project.configurations.compile]
          plusConfigurations += [project.configurations.runtime]
      }

      file {
        beforeMerged { classpath ->
           eclipse.classpath.sourceSets.each {
               println "    source set "+ it.getName()
           }
           eclipse.classpath.plusConfigurations.each{ processConf(it, "    ", "plus conf: ") }
           eclipse.classpath.minusConfigurations.each{ processConf(it, "    ", "minus conf: ") }

           eclipse.classpath.plusConfigurations.add(project.configurations['eclipsePlusConfig'])
           eclipse.classpath.minusConfigurations.add(project.configurations['eclipseMinusConfig'])
        }
        whenMerged { classpath ->
           List<org.gradle.plugins.ide.eclipse.model.ClasspathEntry> replacementEclipseClasspath = createEclipseReplacementClasspath(classpath);
           classpath.setEntries(replacementEclipseClasspath)
        }
        withXml { n ->
            Set<File> existingPaths = new HashSet<File>();
            def rootNode = n.asNode();
            for(int nodeIndex = 0; nodeIndex<rootNode.children().size(); nodeIndex++) {
               def chld = rootNode.children().get(nodeIndex);
               if("classpathentry".equals(chld.name())) {
                  removeGradleAttributes(chld);
                  chld.attributes().remove("output");
                  String kind = chld.attributes().get("kind");
                  for(Map.Entry entry : chld.attributes().entrySet()) {
                      if("path".equals(entry.key) || "sourcepath".equals(entry.key)) {
                        f = new File(entry.value);
                        if(f.toPath().isAbsolute()) {
                            String relativeName = rootProject.projectDir.toPath().relativize(f.toPath()).toString();
                            entry.value = "/"+ relativeName.replace('\\', '/');
                        }
                        if("path".equals(entry.key) && existingPaths.contains(f)) {
                            rootNode.children().remove(nodeIndex--);
                            break;
                        }
                        if(entry.value.startsWith("/")) {
                            if("src".equals(kind)) {
                                chld.attributes().put("combineaccessrules", "false");
                            }
                        }
                        existingPaths.add(f);
                      }
                  }
                  if("lib".equals(kind)) {
                      chld.attributes().put("exported", "true");
                  }
               }
            }
        }
      }
    }

    task prepareEclipse{
      doFirst{
        mkDirIfNotExists(new File("${projectDir}/src/main/java"))
        mkDirIfNotExists(new File("${projectDir}/src/main/resources"))
        mkDirIfNotExists(new File("${projectDir}/src/test/java"))
        mkDirIfNotExists(new File("${projectDir}/src/test/resources"))
      }
    }

    tasks['eclipseClasspath'].dependsOn(prepareEclipse)
  }
}

List<org.gradle.plugins.ide.eclipse.model.ClasspathEntry> createEclipseReplacementClasspath(org.gradle.plugins.ide.eclipse.model.Classpath eclipseClasspath) {
    Map<String, org.gradle.plugins.ide.eclipse.model.ClasspathEntry> replacementEclipseClasspathAsMap = new HashMap<String, org.gradle.plugins.ide.eclipse.model.ClasspathEntry>(); 
    eclipseClasspath.entries.each{ clspthentry ->
        dumpClassPathEntry(clspthentry)
        if (clspthentry instanceof org.gradle.plugins.ide.eclipse.model.Library) {
            org.gradle.plugins.ide.eclipse.model.Library library = clspthentry;
            String moduleId = library.getModuleVersion().toString();
            String groupId = null;
            String artifactId = null;
            String artifactVersion = null;
            int index = moduleId.indexOf(":");
            if(index >= 0) {
                groupId = moduleId.substring(0, index);
                String tmp = moduleId.substring(++index);
                index = tmp.indexOf(":")
                if(index >= 0) {
                    artifactId = tmp.substring(0, index);
                    artifactVersion = tmp.substring(++index);
                }
            }
            moduleId = moduleId.replaceAll(":", "-");
            println("    classpath entry found: moduleId="+ moduleId);
            if (library.getPath().endsWith(".aar")) {
                explodeAarJarFiles(moduleId, groupId, artifactId, artifactVersion, library, replacementEclipseClasspathAsMap);
            } else {
                copyLibraryFromGradleCache(moduleId, groupId, artifactId, artifactVersion, library, replacementEclipseClasspathAsMap)
            }
        } else {
            replacementEclipseClasspathAsMap.put(clspthentry.kind+ "_"+ clspthentry.path, clspthentry);
        }
    }
    List<org.gradle.plugins.ide.eclipse.model.ClasspathEntry> replacementEclipseClasspath = new ArrayList<org.gradle.plugins.ide.eclipse.model.ClasspathEntry>();
    replacementEclipseClasspath.addAll(replacementEclipseClasspathAsMap.values());
    List<String> KINDS = new ArrayList<String>();
    KINDS.add('src');
    KINDS.add('con');
    KINDS.add('lib');
    KINDS.add('output');
    Collections.sort(replacementEclipseClasspath, new Comparator<org.gradle.plugins.ide.eclipse.model.ClasspathEntry>() {

        private int detectKindIndex(String entryKind) {
            for(int i = 0; i<KINDS.size(); i++) {
                if(KINDS[i].equals(entryKind)) {
                    return i;
                }
            }
            return KINDS.size();
        }

        public int compare(org.gradle.plugins.ide.eclipse.model.ClasspathEntry entry1, org.gradle.plugins.ide.eclipse.model.ClasspathEntry entry2) {
            int kindDiff = detectKindIndex(entry1.getKind()) - detectKindIndex(entry2.getKind());
            if(kindDiff != 0) {
                return kindDiff;
            }
            if(entry1 instanceof org.gradle.plugins.ide.eclipse.model.ProjectDependency) {
                if(!(entry2 instanceof org.gradle.plugins.ide.eclipse.model.ProjectDependency)) {
                    return 11;
                }
            } else if(entry2 instanceof org.gradle.plugins.ide.eclipse.model.ProjectDependency) {
                return -1;
            }
            return entry1.path.compareTo(entry2.path);
        }
    });
    return replacementEclipseClasspath;
}

void copyLibraryFromGradleCache(String moduleId, String groupId, String artifactId, String artifactVersion, org.gradle.plugins.ide.eclipse.model.Library library, Map<String, org.gradle.plugins.ide.eclipse.model.Library> replacementEclipseClasspathAsMap) {
    String artifactIdAndVersion = artifactId + "-"+ artifactVersion;
    int fileSuffixIndex = -1;
    if(artifactId != null) {
        fileSuffixIndex = library.getPath().lastIndexOf(artifactIdAndVersion);
    }
    if(fileSuffixIndex >= 0) {
        fileSuffixIndex += artifactIdAndVersion.length();
    } else {
        fileSuffixIndex = library.getPath().lastIndexOf(".");
    }
    if(moduleId == null || fileSuffixIndex <= 0) {
        println("      non-movable library found: "+ library.getPath())
        replacementEclipseClasspathAsMap.put(moduleId, library);
    } else {
        File targetGroupFolder = null; 
        if (groupId==null || groupId.trim().length()==0) {
            targetGroupFolder = new File(globalDependenciesRepo.getAbsolutePath());
        } else {
            targetGroupFolder = new File(globalDependenciesRepo.getAbsolutePath(), groupId);
            if(!targetGroupFolder.exists()){
                targetGroupFolder.mkdirs()
            }
        }
        String fileSuffix = library.getPath().substring(fileSuffixIndex);
        String targetFileName = artifactIdAndVersion;
        println("      target filename: "+ targetGroupFolder+ " -> "+ targetFileName)
        java.nio.file.Path targetFile = java.nio.file.Paths.get(targetGroupFolder.getAbsolutePath(), targetFileName + fileSuffix);
        java.nio.file.Path sourceFile = java.nio.file.Paths.get(library.getPath());
        if(sourceFile.toFile().exists() && !sourceFile.toFile().isDirectory()) {
            java.nio.file.Files.copy(sourceFile, targetFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING, java.nio.file.StandardCopyOption.COPY_ATTRIBUTES);
            library.setPath(targetFile.toString());
        }
        if(library.getSourcePath() != null) {
            java.nio.file.Path sourceSourceFile = java.nio.file.Paths.get(library.getSourcePath().getPath());
            if(sourceFile.toFile().exists() && !sourceFile.toFile().isDirectory()) {
                java.nio.file.Path sourceTargetFile = java.nio.file.Paths.get(targetGroupFolder.getAbsolutePath(), targetFileName + "_source"+ fileSuffix);
                println("      copying source file: "+ sourceSourceFile + " into "+ sourceTargetFile);
                java.nio.file.Files.copy(sourceSourceFile, sourceTargetFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING, java.nio.file.StandardCopyOption.COPY_ATTRIBUTES);
                //println( "          TROLOLO "+ rootProject.projectDir.toPath().relativize(sourceTargetFile) );
                library.setSourcePath(fileReferenceFactory.fromFile(sourceTargetFile.toFile()));
            }
        }
        replacementEclipseClasspathAsMap.put(moduleId + "_"+ targetFileName + fileSuffix, library);
    }
}

void explodeAarJarFiles(String moduleId, String groupId, String artifactId, String artifactVersion, org.gradle.plugins.ide.eclipse.model.Library aarLibrary, Map<String, org.gradle.plugins.ide.eclipse.model.Library> replacementEclipseClasspathAsMap) {
    File aarFile = new File(aarLibrary.getPath());
    println("    exploding AAR dependency: "+ aarFile.getAbsolutePath());
    File targetFolder = new File(explodedAarsDir, moduleId);
    println("      target folder: "+ targetFolder.getAbsolutePath());
    if (targetFolder.exists()) {
        println("        target folder exists. deleting ");
        project.delete(files(targetFolder))
    }
    if (!targetFolder.mkdirs()) {
        throw new RuntimeException("Cannot create folder: ${targetFolder.getAbsolutePath()}");
    }
    try {
        if(aarLibrary.getSourcePath() != null) {
            java.nio.file.Path sourceSourceFile = java.nio.file.Paths.get(aarLibrary.getSourcePath().getPath());
            if(sourceSourceFile.toFile().exists() && !sourceSourceFile.toFile().isDirectory()) {
                String sourceFileExt = sourceSourceFile.toString();
                int extensionIndex = sourceFileExt.lastIndexOf(".");
                if(extensionIndex >= 0) {
                    sourceFileExt = sourceFileExt.substring(extensionIndex);
                } else {
                    sourceFileExt = ".jar";
                }
                java.nio.file.Path sourceTargetFile = java.nio.file.Paths.get(targetFolder.toString(), moduleId+ "_source"+ sourceFileExt);
                println("      copying source file: "+ sourceSourceFile + " into "+ sourceTargetFile);
                java.nio.file.Files.copy(sourceSourceFile, sourceTargetFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING, java.nio.file.StandardCopyOption.COPY_ATTRIBUTES);
                aarLibrary.setSourcePath(fileReferenceFactory.fromFile(sourceTargetFile.toFile()));
            }
        }
        java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(aarFile);
        zipFile.entries().each{ fileInsideAar -> 
            if (fileInsideAar.getName().endsWith(".jar")) {
                String targetName = moduleId+ "_"+ fileInsideAar.getName().replace('/', '_').replace('\\', '_');
                println("          jar inside aar: "+ fileInsideAar.getName());
                println("          copying to: "+ targetName);
                File targetFile = new File(targetFolder, targetName);
                int index = 1;
                while (targetFile.exists()) {
                    targetFile = new File(targetFolder, format("${targetName}_${++index}"));
                }
                try {
                    InputStream inputStream = zipFile.getInputStream(fileInsideAar);
                    java.nio.file.Files.copy(inputStream, targetFile.toPath());
                    org.gradle.plugins.ide.eclipse.model.Library library = new org.gradle.plugins.ide.eclipse.model.Library(fileReferenceFactory.fromFile(targetFile));
                    library.setSourcePath(aarLibrary.getSourcePath())
                    replacementEclipseClasspathAsMap.put(targetFile.getName(), library);
                } catch (IOException e) {
                    throw new RuntimeException(
                            "Cannot write entry to file: ${e.getMessage()}: ${targetFile.getAbsolutePath()}", e);
                }
            }
        };
    } catch (IOException e) {
        throw new RuntimeException(
               "Cannot explode aar: ${e.getMessage()}: ${aarFile.getAbsolutePath()}", e);
    }
}

void removeGradleAttributes(Node node) {
    for(int i = 0; i<node.children().size(); i++) {
        Node attrs = node.children().get(i);
        if("attributes".equals(attrs.name())) {
            for(int j = 0; j<attrs.children().size(); j++) {
                Node attr = attrs.children().get(j);
                boolean isGradleAttr = false;
                for(Map.Entry entry : attr.attributes().entrySet()) {
                    if(entry.key.toLowerCase().contains("gradle") || entry.value.toLowerCase().contains("gradle")) {
                        isGradleAttr = true;
                    }
                }
                if(isGradleAttr) {
                    attrs.remove(attr);
                    j--;
                }
            }
            if(attrs.children().size()==0) {
                node.remove(attrs);
            }
        }
    }
}

void mkDirIfNotExists(File file) {
    if(!file.exists()) {
        file.mkdir()
    }
}

void processConf(org.gradle.api.internal.artifacts.configurations.DefaultConfiguration cnf, String startIndent, String prefix) {
    println(startIndent + prefix + cnf.name+ ", path: "+ cnf.path)
    StringBuilder indent = new StringBuilder();
    for(int i = 0; i<startIndent.length(); i++) {
        indent.append(" ");
    }
    indent.append("  ");

    cnf.dependencies.each{ dep ->
        maskDependencyIfNeeded(indent.toString(), dep)
    }
    cnf.allDependencies.each{ dep ->
        maskDependencyIfNeeded(indent.toString(), dep)
    }
}

void maskDependencyIfNeeded(String indent, org.gradle.api.internal.artifacts.dependencies.AbstractDependency dep) {
    if(dep instanceof org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency) {
        boolean needToExcludeDep = false;
        Set<File> maskedDepFiles = new HashSet<File>();
        dep.files.each{ depFile ->
            File f = findMaskedFile(depFile, null, true);
            if(f != null) {
              maskedDepFiles.add(f)
              needToExcludeDep = true;
              println(indent.toString()+ "  mask dep file "+ depFile+ " -> "+ f)
            }
        }
        if(needToExcludeDep) {
            project.configurations['eclipseMinusConfig'].dependencies.add(dep)
            if(!maskedDepFiles.isEmpty()) {
                org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency newDep = new org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency(dep.targetComponentId, project.files(maskedDepFiles))
                project.configurations['eclipsePlusConfig'].dependencies.add(newDep)
            }
        }
    }
}

File findMaskedFile(File f, String postfix, boolean initiallyUnmasked) {
  if(f != null) {
      for(Map.Entry<File, File> efm : eclipseFileMapping) {
           boolean masked = false;
           if(initiallyUnmasked) {
               if(efm.key.equals(f)) {
                   masked = true;
               }
           } else {
               if(efm.value.equals(f)) {
                   masked = true;
               }
           }
           if(masked) {
               if(postfix != null) {
                   return new File(efm.value, postfix)
               } else {
                   return efm.value;
               }
           }
      }
      return findMaskedFile(f.parentFile, postfix==null ? f.name : f.name + File.pathSeparator+ postfix, initiallyUnmasked);
  }
  return null;
}

void dumpClassPathEntry(org.gradle.plugins.ide.eclipse.model.ClasspathEntry clspthentry) {
    if("output".equals(clspthentry.kind)) {
        // the clspthentry is instance of org.gradle.plugins.ide.eclipse.model.Output
        println("  output: "+ clspthentry.path)
    } else if("src".equals(clspthentry.kind)) {
        if(clspthentry instanceof org.gradle.plugins.ide.eclipse.model.ProjectDependency) {
             // the clspthentry is instance of org.gradle.plugins.ide.eclipse.model.ProjectDependency
             println("  project: exported="+ clspthentry.exported+ "; path="+ clspthentry.path)
        } else {
             // the clspthentry is instance of org.gradle.plugins.ide.eclipse.model.SourceFolder
             println("  src folder: "+ clspthentry.name+ " ("+ clspthentry.dir+ ") -> output: "+ clspthentry.output)
             if(clspthentry.excludes != null && clspthentry.excludes.size()>0) {
                 println("    excludes:")
                 clspthentry.excludes.each{ excl ->
                     println("      "+ excl)
                 }
             }
             if(clspthentry.includes != null && clspthentry.includes.size()>0) {
                 println("    includes:")
                 clspthentry.includes.each{ incl ->
                     println("      "+ incl)
                 }
             }
         }
    } else if("con".equals(clspthentry.kind)) {
        //the clspthentry is instance of org.gradle.plugins.ide.eclipse.model.Container
        println("  con: exported="+ clspthentry.exported+ "; path="+ clspthentry.path)
    } else if("lib".equals(clspthentry.kind)) {
        //the clspthentry is instance of org.gradle.plugins.ide.eclipse.model.Library
        println("  lib: file="+ clspthentry.library.path)
    } else {
        println("  UNKNOWN "+ clspthentry.kind+ " -> "+ clspthentry.getClass().getName())
    }
}

// Gradle adds all custom sourceSets to eclipse's linkedResources. We do not need them in eclipse project, but we do not understand how and when the source is linked.
// So, JUST HACK IT: clear the linked resourcces after evaluating the project!
// But gradle is such a misterious thing! just clearing does not help. We need to put something there
// so lets put the existing linked resource, but with relative path :(
void setupEclipseProject() {
  if(project.name.contains("-android")) {
    project.eclipse.project{

        linkedResource name: 'AndroidManifest.xml', type: '1', location: 'PROJECT_LOC/src/main/AndroidManifest.xml'
        linkedResource name: 'android-java', type: '2', location: 'PARENT-1-PROJECT_LOC/assets/build/android/java'
        linkedResource name: 'res', type: '2', location: 'PROJECT_LOC/src/main/res'
    }
  }
}

Я знаю, что это не вершина программирования gradle, но он просто работает.Основная проблема этого скрипта в том, что он ТРЕБУЕТ, чтобы все зависимости были типа 'compile', но для Android это устарело.Новые типы зависимостей - «api» и «реализация».Теперь 'compile' просто устарела, но я боюсь, что он вообще исчезнет.

Существует простое и уродливое решение: дублируйте все нестандартные зависимости с типом зависимости 'eclipseOnly'.Это решение используется в приведенном выше сценарии.Это работает, но действительно ужасно, потому что мы должны модифицировать скрипты gradle во всех проектах.Но моя цель не касаться всех проектов.Теперь сценарий содержится в отдельном файле 'eclipseHelper.gradle' и включен в корневой проект следующим образом:

subprojects{
   apply from: "${rootProject.projectDir}/eclipseHelper.gradle"
}

Я пытаюсь добиться добавления определенных типов зависимостей Android в Eclipse.Во-первых, я исключил все варианты 'release' из зависимостей:

def androidExtension = project.extensions.findByName("android")
  if (androidExtension != null) {
      android.variantFilter { variant ->
          def names = variant.flavors*.name
          def buildTypeName = variant.buildType.name
          // if buildtype is required for filtering use
          // the above field
          if (variant.name.contains("elease")) {
              variant.ignore = true
          }
      }
   }

Во-вторых, я попытался добавить конфигурации вариантов Android в путь к классу Eclipse ('plusConfigurations'):

def androidExtension = project.extensions.findByName("android")
    if (androidExtension != null) {
      boolean applicationBuild = rootProject.hasProperty("applicationBuild")
      if (androidExtension.getClass().getName().contains("LibraryExtension")){
          android.libraryVariants.all { variant ->
              eclipse.classpath.plusConfigurations += variant.compileConfiguration
              eclipse.classpath.plusConfigurations += variant.runtimeConfiguration
          }
      } else {
          android.applicationVariants.all { variant ->
              eclipse.classpath.plusConfigurations += variant.compileConfiguration
              eclipse.classpath.plusConfigurations += variant.runtimeConfiguration
          }
      }
    }

У нас есть несколько библиотек Android среди наших проектов, и эти библиотеки построены с различными вариантами.Поэтому я получил следующее исключение:

org.gradle.internal.component.AmbiguousVariantSelectionException: More than one variant of project :proj1-android matches the consumer a
ttributes:
  - Configuration ':proj1-android:debugApiElements' variant android-aidl:
      - Found artifactType 'android-aidl' but wasn't required.
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
      - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
  - ...
  - ...
  - Configuration ':proj1-android:debugApiElements' variant jar:
      - Found artifactType 'jar' but wasn't required.
      - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
      - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
      - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
      - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.

Может ли кто-нибудь помочь мне принять какое-либо из решений?

  1. выбрать любую конфигурацию («отладку») из набора
  2. полностью пропустить все конфигурации подпроекта и включить его в .classpath в качестве зависимости проекта

Заранее спасибо, Андрей

1 Ответ

0 голосов
/ 30 июля 2019

У меня такая же проблема.Нашел несколько решений, но они не являются окончательными.

https://github.com/greensopinion/gradle-android-eclipse

https://github.com/GinVavilon/gradle-android-eclipse

Google реализовал привязку данных и androidx в android.tools.build 3.4, и япытаясь настроить мой проект на этих условиях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...