法一:
https://docs.gradle.org/current/userguide/troubleshooting.html
./gradlew taskname -Dorg.gradle.debug=true --no-daemon

法二:
找到GradleRunConfiguration类

这样可以方便gradle源码调试
参考:https://medium.com/dan-on-coding/debugging-gradle-source-code-in-intellij-e1224bec9b6e
DefaultGradleLauncher
public GradleInternal executeTasks() {
doBuildStages(Stage.RunTasks);
return gradle;
}
private void doBuildStages(Stage upTo) {
Preconditions.checkArgument(
upTo != Stage.Finished,
"Stage.Finished is not supported by doBuildStages."
);
try {
if (stage == null && gradle.isRootBuild()) {
buildOptionBuildOperationProgressEventsEmitter.emit(gradle.getStartParameter());
}
if (upTo == Stage.RunTasks && configurationCache.canLoad()) {
doConfigurationCacheBuild();
} else {
doClassicBuildStages(upTo);
}
} catch (Throwable t) {
finishBuild(upTo.getDisplayName(), t);
}
}
private void doClassicBuildStages(Stage upTo) {
if (stage == null) {
configurationCache.prepareForConfiguration();
}
prepareSettings();
if (upTo == Stage.LoadSettings) {
return;
}
prepareProjects();
if (upTo == Stage.Configure) {
return;
}
prepareTaskExecution();
if (upTo == Stage.TaskGraph) {
return;
}
configurationCache.save();
runWork();
}
代码可以看到doClassicBuildStages中调用了prepareSettings方法,该方法就是我们理解的gradle配置阶段,本篇主要来梳理下内部实现流程
private void prepareSettings() {
if (stage == null) {
buildListener.buildStarted(gradle);
settingsPreparer.prepareSettings(gradle);
stage = Stage.LoadSettings;
}
}
配置篇小结:
生命接口方法buildStarted调用
首先是触发了buildListener的buildStarted方法(该监听器可以通过grade.addListener来实现)
执行初始化脚本
InitScriptHandler.executeScripts
寻找并解析setting.gradle文件
加载gradle.properties文件
解析buildSrc工程文件
涉及服务类参见BuildScopeServices;有关服务类如何注入参见启动篇

// DefaultSettingsPreparer.java
public void prepareSettings(GradleInternal gradle) {
// 1. Evaluate init scripts
initScriptHandler.executeScripts(gradle);
// Build `buildSrc`, load settings.gradle, and construct composite (if appropriate)
SettingsLoader settingsLoader = gradle.isRootBuild() ? settingsLoaderFactory.forTopLevelBuild() : settingsLoaderFactory.forNestedBuild();
//CompositeBuildSettingsLoader
settingsLoader.findAndLoadSettings(gradle);
}
主要做了三件事。
执行初始化脚本(.gradle) InitScriptHandler.executeScripts
构建buildSrc工程
寻找并解析settings.gradle
CompositeBuildSettingsLoader.findAndLoadSettings ==>
ChildBuildRegisteringSettingsLoader.findAndLoadSettings ==>
CommandLineIncludedBuildSettingsLoader.findAndLoadSettings==>
SettingsAttachingSettingsLoader.findAndLoadSettings ==>
DefaultSettingsLoader.findAndLoadSettings ==>
// CompositeBuildSettingsLoader.java
public SettingsInternal findAndLoadSettings(GradleInternal gradle) {
SettingsInternal settings = delegate.findAndLoadSettings(gradle);
// Lock-in explicitly included builds
buildRegistry.finalizeIncludedBuilds();
return settings;
}
// ChildBuildRegisteringSettingsLoader.java
public SettingsInternal findAndLoadSettings(GradleInternal gradle) {
// delegate :CommandLineIncludedBuildSettingsLoader
SettingsInternal settings = delegate.findAndLoadSettings(gradle);
// Add included builds defined in settings
List<IncludedBuildSpec> includedBuilds = settings.getIncludedBuilds();
if (!includedBuilds.isEmpty()) {
Set<IncludedBuild> children = new LinkedHashSet<>(includedBuilds.size());
for (IncludedBuildSpec includedBuildSpec : includedBuilds) {
if (!includedBuildSpec.rootDir.equals(buildRegistry.getRootBuild().getBuildRootDir())) {
IncludedBuildState includedBuild = addIncludedBuild(includedBuildSpec, gradle);
children.add(includedBuild.getModel());
} else {
buildRegistry.registerSubstitutionsForRootBuild();
children.add(new IncludedRootBuild((CompositeBuildParticipantBuildState) buildRegistry.getRootBuild()));
}
}
// Set the visible included builds
gradle.setIncludedBuilds(children);
} else {
gradle.setIncludedBuilds(Collections.emptyList());
}
return settings;
}
// CommandLineIncludedBuildSettingsLoader.java
public SettingsInternal findAndLoadSettings(GradleInternal gradle) {
// delegate: SettingsAttachingSettingsLoader
SettingsInternal settings = delegate.findAndLoadSettings(gradle);
// Add all included builds from the command-line
for (File rootDir : gradle.getStartParameter().getIncludedBuilds()) {
settings.includeBuild(rootDir);
}
return settings;
}
// SettingsAttachingSettingsLoader.java
public SettingsInternal findAndLoadSettings(GradleInternal gradle) {
// delegate:DefaultSettingsLoader
SettingsInternal settings = delegate.findAndLoadSettings(gradle);
gradle.setSettings(settings);
projectRegistry.registerProjects(gradle.getServices().get(BuildState.class));
return settings;
}
/**
* Handles locating and processing setting.gradle files. Also deals with the buildSrc module, since that modules is
* found after settings is located, but needs to be built before settings is processed.
*/
public class DefaultSettingsLoader implements SettingsLoader {
....
public SettingsInternal findAndLoadSettings(GradleInternal gradle) {
StartParameter startParameter = gradle.getStartParameter();
// 1. 寻找setting.gradle位置
SettingsLocation settingsLocation = buildLayoutFactory.getLayoutFor(new BuildLayoutConfiguration(startParameter));
if (settingsLocation.isSettingsLoadedFromMasterDirectory()) {
DeprecationLogger.deprecateBehaviour("Searching for settings files in a directory named 'master' from a sibling directory has been deprecated.")
.willBeRemovedInGradle7()
.withUpgradeGuideSection(6, "master_subdirectory_root_build")
.nagUser();
}
// 2. 加载gradle.properties文件
loadGradlePropertiesFrom(settingsLocation);
// 3. 解析settings.gradle 文件
SettingsInternal settings = findSettingsAndLoadIfAppropriate(gradle, startParameter, settingsLocation, gradle.getClassLoaderScope());
ProjectSpec spec = ProjectSpecs.forStartParameter(startParameter, settings);
if (useEmptySettings(spec, settings, startParameter)) {
settings = createEmptySettings(gradle, startParameter, settings.getClassLoaderScope());
}
// 4. 设置默认工程
setDefaultProject(spec, settings);
return settings;
}
}
可以看到DefaultSettingsLoader类注释说明可以知道它的职责是

最终调用到DefaultGradlePropertiesLoader.loadProperties
@Override
public GradleProperties loadGradleProperties(File rootDir) {
return loadProperties(rootDir, startParameter, getAllSystemProperties(), getAllEnvProperties());
}
GradleProperties loadProperties(File rootDir, StartParameterInternal startParameter, Map<String, String> systemProperties, Map<String, String> envProperties) {
Map<String, String> defaultProperties = new HashMap<>();
Map<String, String> overrideProperties = new HashMap<>();
// 1. gradle-home-dir:/Users/dingbaosheng/.gradle/wrapper/dists/gradle-6.9-bin/2ecsmyp3bolyybemj56vfn4mt/gradle-6.9
addGradleProperties(defaultProperties, new File(startParameter.getGradleHomeDir(), GRADLE_PROPERTIES));
// 2. eg:/Users/dingbaosheng/work/open-source-project/gradle
addGradleProperties(defaultProperties, new File(rootDir, GRADLE_PROPERTIES));
// 3. gradle-user-home-dir:/Users/dingbaosheng/.gradle
addGradleProperties(overrideProperties, new File(startParameter.getGradleUserHomeDir(), GRADLE_PROPERTIES));
addSystemPropertiesFromGradleProperties(defaultProperties);
addSystemPropertiesFromGradleProperties(overrideProperties);
System.getProperties().putAll(startParameter.getSystemPropertiesArgs());
// 从环境变量中读取ORG_GRADLE_PROJECT_开头的key,有就返回,无就返回空
overrideProperties.putAll(getEnvProjectProperties(envProperties));
// 从系统属性中读取org.gradle.project.开头key,有则返回,无则返回空
overrideProperties.putAll(getSystemProjectProperties(systemProperties));
// 启动命令参数重读取
overrideProperties.putAll(startParameter.getProjectProperties());
return new DefaultGradleProperties(defaultProperties, overrideProperties);
}
上面主要是从
gradle-home-dir、项目根工程目录、gradle-user-home目录,环境变量,系统属性及启动参数中加载properties属性
DefaultSettingsLoader.findSettingsAndLoadIfAppropriate
/**
* Finds the settings.gradle for the given startParameter, and loads it if contains the project selected by the
* startParameter, or if the startParameter explicitly specifies a settings script. If the settings file is not
* loaded (executed), then a null is returned.
*/
private SettingsInternal findSettingsAndLoadIfAppropriate(
GradleInternal gradle,
StartParameter startParameter,
SettingsLocation settingsLocation,
ClassLoaderScope classLoaderScope
) {
// 此处的settingsProcessor为BuildOperationSettingsProcessor
SettingsInternal settings = settingsProcessor.process(gradle, settingsLocation, classLoaderScope, startParameter);
// 交验工程名称合法性(不能是buildSrc)
validate(settings);
return settings;
}
private void validate(SettingsInternal settings) {
settings.getProjectRegistry().getAllProjects().forEach(project -> {
if (project.getPath().equals(BUILD_SRC_PROJECT_PATH)) {
Path buildPath = settings.getGradle().getIdentityPath();
String suffix = buildPath == Path.ROOT ? "" : " (in build " + buildPath + ")";
throw new GradleException("'" + SettingsInternal.BUILD_SRC + "' cannot be used as a project name as it is a reserved name" + suffix);
}
});
}
链路调用:
参见:BuildScopeService

// BuildOperationSettingsProcessor.java
@Override
public SettingsInternal process(final GradleInternal gradle, final SettingsLocation settingsLocation, final ClassLoaderScope buildRootClassLoaderScope, final StartParameter startParameter) {
return buildOperationExecutor.call(new CallableBuildOperation<SettingsInternal>() {
@Override
public SettingsInternal call(BuildOperationContext context) {
// 直接委托给RootBuildCacheControllerSettingsProcessor处理
SettingsInternal settingsInternal = settingsProcessor.process(gradle, settingsLocation, buildRootClassLoaderScope, startParameter);
context.setResult(RESULT);
return settingsInternal;
}
}
可以看到BuildOperationSettingsProcessor类中的process方法将任务直接委派给RootBuildCacheControllerSettingsProcessor.process处理了
public class RootBuildCacheControllerSettingsProcessor implements SettingsProcessor {
public static void process(GradleInternal gradle) {
// The strategy for sharing build cache configuration across included builds in a composite,
// requires that the cache configuration be finalized (and cache controller available)
// before configuring them. This achieves that.
if (gradle.isRootBuild()) {
BuildCacheController rootController = gradle.getServices().get(BuildCacheController.class);
RootBuildCacheControllerRef rootControllerRef = gradle.getServices().get(RootBuildCacheControllerRef.class);
rootControllerRef.set(rootController);
}
}
private final SettingsProcessor delegate;
public RootBuildCacheControllerSettingsProcessor(SettingsProcessor delegate) {
this.delegate = delegate;
}
@Override
public SettingsInternal process(GradleInternal gradle, SettingsLocation settingsLocation, ClassLoaderScope buildRootClassLoaderScope, StartParameter startParameter) {
// 1. 交给SettingsEvaluatedCallbackFiringSettingsProcessor类处理
SettingsInternal settings = delegate.process(gradle, settingsLocation, buildRootClassLoaderScope, startParameter);
// 2. 设置缓存相关配置
process(gradle);
return settings;
}
}
RootBuildCacheControllerSettingsProcessor类顾名思义就是在执行配置阶段,设置缓存配置参见process(grade)
执行process时做了2件事情
public class SettingsEvaluatedCallbackFiringSettingsProcessor implements SettingsProcessor {
private final SettingsProcessor delegate;
public SettingsEvaluatedCallbackFiringSettingsProcessor(SettingsProcessor delegate) {
this.delegate = delegate;
}
@Override
public SettingsInternal process(GradleInternal gradle, SettingsLocation settingsLocation, ClassLoaderScope buildRootClassLoaderScope, StartParameter startParameter) {
// 1. 委托ScriptEvaluatingSettingsProcessor类处理
SettingsInternal settings = delegate.process(gradle, settingsLocation, buildRootClassLoaderScope, startParameter);
// 2. 执行gradle中setting.gradle方法被解析的生命周期方法
gradle.getBuildListenerBroadcaster().settingsEvaluated(settings);
// 3. I don't know,
settings.preventFromFurtherMutation();
return settings;
}
}
上述操作经过层层委托,终于来到类ScriptEvaluatingSettingsProcessor类处理,我们看下其内部实现
public class ScriptEvaluatingSettingsProcessor implements SettingsProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptEvaluatingSettingsProcessor.class);
private final SettingsFactory settingsFactory;
private final GradleProperties gradleProperties;
private final ScriptPluginFactory configurerFactory;
private final TextFileResourceLoader textFileResourceLoader;
public ScriptEvaluatingSettingsProcessor(ScriptPluginFactory configurerFactory,
SettingsFactory settingsFactory,
GradleProperties gradleProperties,
TextFileResourceLoader textFileResourceLoader) {
this.configurerFactory = configurerFactory;
this.settingsFactory = settingsFactory;
this.gradleProperties = gradleProperties;
this.textFileResourceLoader = textFileResourceLoader;
}
@Override
public SettingsInternal process(GradleInternal gradle,
SettingsLocation settingsLocation,
ClassLoaderScope baseClassLoaderScope,
StartParameter startParameter) {
Timer settingsProcessingClock = Time.startTimer();
Map<String, String> properties = gradleProperties.mergeProperties(emptyMap());
TextResourceScriptSource settingsScript = new TextResourceScriptSource(textFileResourceLoader.loadFile("settings file", settingsLocation.getSettingsFile()));
// 1. 创建一个DefaultSettings的一个包装对象
SettingsInternal settings = settingsFactory.createSettings(gradle, settingsLocation.getSettingsDir(), settingsScript, properties, startParameter, baseClassLoaderScope);
// 2. 生命周期调用
gradle.getBuildListenerBroadcaster().beforeSettings(settings);
// 3. 应用脚本
applySettingsScript(settingsScript, settings);
LOGGER.debug("Timing: Processing settings took: {}", settingsProcessingClock.getElapsed());
return settings;
}
private void applySettingsScript(TextResourceScriptSource settingsScript, final SettingsInternal settings) {
// 1. 生成一个BuildOperationScriptPlugin类型对象
ScriptPlugin configurer = configurerFactory.create(settingsScript, settings.getBuildscript(), settings.getClassLoaderScope(), settings.getBaseClassLoaderScope(), true);
// 2. apply
configurer.apply(settings);
}
}

因为gradle源码中的settings文件采用了kotlin语言编写,所以此处apply选择为kotlin脚本插件解析
BuildOperationScriptPlugin.java

private void setDefaultProject(ProjectSpec spec, SettingsInternal settings) {
settings.setDefaultProject(spec.selectProject(settings.getSettingsScript().getDisplayName(), settings.getProjectRegistry()));
}