Gradle构建流程
前面我们分析了Gradle的Daemon启动。后续我们需要对Gradle的构建流程进行分析(粗略分析)
缘起
前面分析到,Gradle的Daemon启动源于Client Connector连接。
由于Client连接了Server,Server在没有启动的时候才会进行Fork启动。
启动后的Server并不会构建,因为Server也不知道Client要干嘛,因为Server还没有Client的构建信息。
所以接下来会介绍Gradle构建的触发。
(其实上部分Daemon启动的解析中有提到——也就是Connect accept过程会触发构建流程)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class DaemonTcpServerConnector implements DaemonServerConnector { @Override public Address start (final IncomingConnectionHandler handler, final Runnable connectionErrorHandler) { lifecycleLock.lock(); try { Action<ConnectCompletion> connectEvent = new Action <ConnectCompletion>() { @Override public void execute (ConnectCompletion completion) { RemoteConnection<Message> remoteConnection; try { remoteConnection = completion.create(Serializers.stateful(serializer)); } catch (UncheckedIOException e) { connectionErrorHandler.run(); throw e; } handler.handle(new SynchronizedDispatchConnection <Message>(remoteConnection)); } }; acceptor = incomingConnector.accept(connectEvent, false ); started = true ; return acceptor.getAddress(); } finally { lifecycleLock.unlock(); } } }
每当有客户端连接的时候就会调用 到handle方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 @Override public ConnectionAcceptor accept (Action<ConnectCompletion> action, boolean allowRemote) { final ServerSocketChannel serverSocket; int localPort; try { serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind(new InetSocketAddress (addressFactory.getLocalBindingAddress(), 0 )); localPort = serverSocket.socket().getLocalPort(); } catch (Exception e) { } UUID id = idGenerator.generateId(); List<InetAddress> addresses = Collections.singletonList(addressFactory.getLocalBindingAddress()); final Address address = new MultiChoiceAddress (id, localPort, addresses); final ManagedExecutor executor = executorFactory.create("Incoming " + (allowRemote ? "remote" : "local" )+ " TCP Connector on port " + localPort); executor.execute(new Receiver (serverSocket, action, allowRemote)); } @Override public void run () { try { try { while (true ) { final SocketChannel socket = serverSocket.accept(); InetSocketAddress remoteSocketAddress = (InetSocketAddress) socket.socket().getRemoteSocketAddress(); InetAddress remoteInetAddress = remoteSocketAddress.getAddress(); if (!allowRemote && !addressFactory.isCommunicationAddress(remoteInetAddress)) { LOGGER.error("Cannot accept connection from remote address {}." , remoteInetAddress); socket.close(); continue ; } try { action.execute(new SocketConnectCompletion (socket)); } catch (Throwable t) { socket.close(); throw t; } } } } } Action<ConnectCompletion> connectEvent = new Action <ConnectCompletion>() { @Override public void execute (ConnectCompletion completion) { RemoteConnection<Message> remoteConnection; try { remoteConnection = completion.create(Serializers.stateful(serializer)); } catch (UncheckedIOException e) { connectionErrorHandler.run(); throw e; } handler.handle(new SynchronizedDispatchConnection <Message>(remoteConnection)); } };
handle方法很实在
将connect加入队列中
使用workers线程池执行构建
1 2 3 4 5 6 7 8 9 10 @Override public void handle (SynchronizedDispatchConnection<Message> connection) { onStartHandling(connection); workers.execute(new ConnectionWorker(connection)); }
缘中
也就是构建过程
逻辑如下
接收command信息
处理执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 private class ConnectionWorker implements Runnable { @Override public void run () { try { receiveAndHandleCommand(); } finally { onFinishHandling(connection); } } private void receiveAndHandleCommand () { try { DefaultDaemonConnection daemonConnection = new DefaultDaemonConnection (connection, executorFactory); try { Command command = receiveCommand(daemonConnection); if (command != null ) { handleCommand(command, daemonConnection); } } finally { daemonConnection.stop(); } } finally { connection.stop(); } private void handleCommand (Command command, DaemonConnection daemonConnection) { try { if (!Arrays.equals(command.getToken(), token)) { } commandExecuter.executeCommand(daemonConnection, command, daemonContext, daemonStateControl); } catch (Throwable e) { daemonConnection.completed(new Failure (e)); } Object finished = daemonConnection.receive(60 , TimeUnit.SECONDS); } }
后面的构建过程极大的使用了责任链的设计模式,步骤如下
环境准备
a. Command Actions
b. Build Executors
c. Action Executors
d. Build Tree Action Executors
构建生命周期
a. Configure Settings Projects
b. Configure Tasks
c. Run Tasks
环境准备
Command Actions
executor执行模式才用了责任链。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class DaemonCommandExecuter { public void executeCommand ( DaemonConnection connection, Command command, DaemonContext daemonContext, DaemonStateControl daemonStateControl ) { new DaemonCommandExecution ( configuration, connection, command, daemonContext, daemonStateControl, actions ).proceed(); } ImmutableList.of( new HandleStop (get(ListenerManager.class)), new HandleInvalidateVirtualFileSystem (get(GradleUserHomeScopeServiceRegistry.class)), new HandleCancel (), new HandleReportStatus (), new ReturnResult (), new StartBuildOrRespondWithBusy (daemonDiagnostics), new EstablishBuildEnvironment (processEnvironment), new LogToClient (loggingManager, daemonDiagnostics), new LogAndCheckHealth (healthStats, healthCheck), new ForwardClientInput (), new RequestStopIfSingleUsedDaemon (), new ResetDeprecationLogger (), new WatchForDisconnection (), new ExecuteBuild (buildActionExecuter, runningStats) ); }
然后就是一系列的递归调用
最后这个ExecuteBuild doBuild 触发了后续的构建流程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class ExecuteBuild extends BuildCommandOnly { @Override protected void doBuild (final DaemonCommandExecution execution, Build build) { runningStats.buildStarted(); DaemonConnectionBackedEventConsumer buildEventConsumer = new DaemonConnectionBackedEventConsumer (execution); try { BuildCancellationToken cancellationToken = execution.getDaemonStateControl().getCancellationToken(); BuildRequestContext buildRequestContext = new DefaultBuildRequestContext (build.getBuildRequestMetaData(), cancellationToken, buildEventConsumer); if (!build.getAction().getStartParameter().isContinuous()) { buildRequestContext.getCancellationToken().addCallback(new Runnable () { @Override public void run () { LOGGER.info(DaemonMessages.CANCELED_BUILD); } }); } BuildActionResult result = actionExecuter.execute(build.getAction(), build.getParameters(), buildRequestContext); execution.setResult(result); } finally { buildEventConsumer.waitForFinish(); runningStats.buildFinished(); LOGGER.debug(DaemonMessages.FINISHED_BUILD); } execution.proceed(); } }
Build Executors
这里actionExecutor也是一个责任链
1 2 3 4 5 new SetupLoggingActionExecuter (loggingManager, new SessionFailureReportingActionExecuter (buildLoggerFactory, new StartParamsValidatingActionExecuter ( new BuildSessionLifecycleBuildActionExecuter (userHomeServiceRegistry, globalServices ))));
经过四层调用最后会调用到BuildSessionLifecycleBuildActionExecuter
中进行后续构建
Build Session Action Executors
紧接着就是BuildActionExecutor的执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 return new SubscribableBuildActionExecutor ( listenerManager, buildOperationListenerManager, listenerFactory, eventConsumer, new ContinuousBuildActionExecutor ( workListeners, fileChangeListeners, styledTextOutputFactory, executorFactory, requestMetaData, cancellationToken, deploymentRegistry, listenerManager, buildStartedTime, clock, fileSystem, caseSensitivity, fileSystemWatchingInformation, new RunAsWorkerThreadBuildActionExecutor ( workerLeaseService, new RunAsBuildOperationBuildActionExecutor ( new BuildTreeLifecycleBuildActionExecutor (buildModelServices, buildLayoutValidator), buildOperationExecutor, loggingBuildOperationProgressBroadcaster, buildOperationNotificationValve))));
如下是整体的调用栈
Build Tree Action Executors
Tree Action Executors和他的Actions。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 return new RootBuildLifecycleBuildActionExecutor ( buildStateRegistry, new BuildCompletionNotifyingBuildActionRunner ( new FileSystemWatchingBuildActionRunner ( eventEmitter, virtualFileSystem, deploymentRegistry, statStatisticsCollector, fileHasherStatisticsCollector, directorySnapshotterStatisticsCollector, buildOperationRunner, new BuildOutcomeReportingBuildActionRunner ( styledTextOutputFactory, listenerManager, new ProblemReportingBuildActionRunner ( new ChainingBuildActionRunner (buildActionRunners), exceptionAnalyser, buildLayout, problemReporters ), buildStartedTime, buildRequestMetaData, buildLoggerFactory)), gradleEnterprisePluginManager));
函数调用栈。
需要注意的是,到目前为止,Build还没有开始。还是处于准备的阶段
构建生命周期
Gradle的整个构建过程有很明显的状态机驱动。
其中有几个比较重要的状态机
DefaultBuildTreeLifecycleController
用于控制整个构建状态的流转
DefaultBuildLifecycleController
用于控制整个构建3周期的流转( Configure Setttings Projects 、Configure Tasks、Run Tasks)
VintageBuildModelController
控制Settings、Projects脚本的运行
ProjectLifecycleController
单独控制Projects的脚本的执行
Build Tree State Controller 即public class DefaultBuildTreeLifecycleController implements BuildTreeLifecycleController
这个Controller有两个State
这个过程所做的即将
State从NotStarted转化到Complete
1 2 3 private enum State implements StateTransitionController .State { NotStarted, Complete }
执行doScheduleAndRunTasks(selector)实现状态的偏移
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class DefaultBuildTreeLifecycleController implements BuildTreeLifecycleController { @Override public void scheduleAndRunTasks (EntryTaskSelector selector) { runBuild(() -> doScheduleAndRunTasks(selector)); } private <T> T runBuild (Supplier<ExecutionResult<? extends T>> action) { return state.transition(State.NotStarted, State.Complete, () -> { ExecutionResult<? extends T > result; try { result = action.get(); } catch (Throwable t) { result = ExecutionResult.failed(t); } RuntimeException finalReportableFailure = finishExecutor.finishBuildTree(result.getFailures()); if (finalReportableFailure != null ) { throw finalReportableFailure; } return result.getValue(); }); } }
scheduleAndRuntask
1.prepare task graph
2.执行task
1 2 3 4 5 6 private ExecutionResult<Void> doScheduleAndRunTasks (@Nullable EntryTaskSelector taskSelector) { return taskGraph.withNewWorkGraph(graph -> { BuildTreeWorkGraph.FinalizedGraph finalizedGraph = workPreparer.scheduleRequestedTasks(graph, taskSelector); return workExecutor.execute(finalizedGraph); }); }
Build Lifecycle
Build Lifecycle也是一个状态机
1 2 3 4 5 6 7 8 9 private enum State implements StateTransitionController .State { Configure, TaskSchedule, ReadyToRun, Finished }
Configure -> TaskSchedule
1 2 3 4 5 6 7 @Override public void prepareToScheduleTasks () { state.maybeTransition(State.Configure, State.TaskSchedule, () -> { hasTasks = true ; modelController.prepareToScheduleTasks(); }); }
Build Model Lifecycle
Build Model Lifecycle只有三个
1 2 3 private enum Stage implements StateTransitionController .State { Created, SettingsLoaded, Configured }
modelController.prepareToScheduleTasks();
直接就走完了他短暂的生命
1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public void prepareToScheduleTasks () { prepareSettings(); prepareProjects(); } private void prepareSettings () { state.transitionIfNotPreviously(Stage.Created, Stage.SettingsLoaded, () -> settingsPreparer.prepareSettings(gradle)); } private void prepareProjects () { state.transitionIfNotPreviously(Stage.SettingsLoaded, Stage.Configured, () -> projectsPreparer.prepareProjects(gradle)); }
prepareSettings
Created -> SettingsLoaded
1 2 3 4 5 6 7 8 public class BuildOperationFiringProjectsPreparer implements ProjectsPreparer { @Override public void prepareSettings (GradleInternal gradle) { buildOperationExecutor.run(new LoadBuild (gradle)); } }
LoadBuild可以认为是一个runnable.
触发Build执行
1 2 3 4 5 6 7 8 9 10 11 12 13 private class LoadBuild implements RunnableBuildOperation { @Override public void run (BuildOperationContext context) { doLoadBuild(); context.setResult(RESULT); } void doLoadBuild () { delegate.prepareSettings(gradle); } }
SettingsPreparer用于配置settings.gradle(.kts)并将配置好的settings实例存入gradle实例中
1 2 3 4 5 6 7 8 9 10 11 12 13 public class DefaultSettingsPreparer implements SettingsPreparer { @Override public void prepareSettings (GradleInternal gradle) { SettingsLoader settingsLoader = gradle.isRootBuild() ? settingsLoaderFactory.forTopLevelBuild() : settingsLoaderFactory.forNestedBuild(); settingsLoader.findAndLoadSettings(gradle); } }
Loader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public SettingsLoader forTopLevelBuild () { return new GradlePropertiesHandlingSettingsLoader ( new InitScriptHandlingSettingsLoader ( new CompositeBuildSettingsLoader ( new ChildBuildRegisteringSettingsLoader ( new CommandLineIncludedBuildSettingsLoader ( defaultSettingsLoader() ), buildRegistry, buildIncluder), buildRegistry), initScriptHandler), buildLayoutFactory, gradlePropertiesController ); }
然后在最后一个Loader内,调用了Process去创建Settings实例
1 2 3 4 5 6 7 8 9 10 private SettingsInternal findSettingsAndLoadIfAppropriate ( GradleInternal gradle, StartParameter startParameter, SettingsLocation settingsLocation, ClassLoaderScope classLoaderScope ) { SettingsInternal settings = settingsProcessor.process(gradle, settingsLocation, classLoaderScope, startParameter); validate(settings); return settings; }
Processor呢也是一个责任链,目的内在于去创建一个settings实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 protected SettingsProcessor createSettingsProcessor ( ScriptPluginFactory scriptPluginFactory, ScriptHandlerFactory scriptHandlerFactory, Instantiator instantiator, ServiceRegistryFactory serviceRegistryFactory, GradleProperties gradleProperties, BuildOperationExecutor buildOperationExecutor, TextFileResourceLoader textFileResourceLoader ) { return new BuildOperationSettingsProcessor ( new RootBuildCacheControllerSettingsProcessor ( new SettingsEvaluatedCallbackFiringSettingsProcessor ( new ScriptEvaluatingSettingsProcessor ( scriptPluginFactory, new SettingsFactory ( instantiator, serviceRegistryFactory, scriptHandlerFactory ), gradleProperties, textFileResourceLoader ) ) ), buildOperationExecutor ); }
会在ScriptEvaluatingSettingsProcessor中通过factory创建一个settings实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public SettingsInternal process ( GradleInternal gradle, SettingsLocation settingsLocation, ClassLoaderScope baseClassLoaderScope, StartParameter startParameter ) { Timer settingsProcessingClock = Time.startTimer(); TextResourceScriptSource settingsScript = new TextResourceScriptSource (textFileResourceLoader.loadFile("settings file" , settingsLocation.getSettingsFile())); SettingsInternal settings = settingsFactory.createSettings(gradle, settingsLocation.getSettingsDir(), settingsScript, gradleProperties, startParameter, baseClassLoaderScope); gradle.getBuildListenerBroadcaster().beforeSettings(settings); applySettingsScript(settingsScript, settings); LOGGER.debug("Timing: Processing settings took: {}" , settingsProcessingClock.getElapsed()); return settings; }
script执行
script的执行分为两步
1.编译
2.运行
1 2 3 4 5 6 private void applySettingsScript (TextResourceScriptSource settingsScript, final SettingsInternal settings) { ScriptPlugin configurer = configurerFactory.create(settingsScript, settings.getBuildscript(), settings.getClassLoaderScope(), settings.getBaseClassLoaderScope(), true ); configurer.apply(settings); }
编译过程暂且跳过。执行过程可以讲讲。
我们的settings.gradle.kts会被编译成一个jar包,然后被层层包裹(settings.gradle也类似,可能类名不一样)
configure.apply会层层剥开回调,最后调用到jar方法进行gradle的配置。(具体怎么配置的留在后面讲)
prepareProjects
SettingsLoaded -> Configured
build prepare过程是由preparer完成的,但不知一个preparer。
其中以后使用了责任链的设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 protected ProjectsPreparer createBuildConfigurer ( ProjectConfigurer projectConfigurer, BuildSourceBuilder buildSourceBuilder, BuildStateRegistry buildStateRegistry, BuildInclusionCoordinator inclusionCoordinator, BuildLoader buildLoader, ListenerManager listenerManager, BuildOperationExecutor buildOperationExecutor, BuildModelParameters buildModelParameters ) { ModelConfigurationListener modelConfigurationListener = listenerManager.getBroadcaster(ModelConfigurationListener.class); return new BuildOperationFiringProjectsPreparer ( new BuildTreePreparingProjectsPreparer ( new DefaultProjectsPreparer ( projectConfigurer, buildModelParameters, modelConfigurationListener, buildOperationExecutor, buildStateRegistry), buildLoader, inclusionCoordinator, buildSourceBuilder), buildOperationExecutor); }
FiringProjectsPreparer
BuildTreePreparer
DefaultPreparer
过程比prepareSettings要长一点、 tygh nhbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbj
1.设置classloader
2.attach root project实例
3.使用include build做依赖替换
4.构建buildSrc并将依赖导入到root project的classpath下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class BuildTreePreparingProjectsPreparer implements ProjectsPreparer { @Override public void prepareProjects (GradleInternal gradle) { SettingsInternal settings = gradle.getSettings(); ClassLoaderScope settingsClassLoaderScope = settings.getClassLoaderScope(); ClassLoaderScope buildSrcClassLoaderScope = settingsClassLoaderScope.createChild("buildSrc[" + gradle.getIdentityPath() + "]" ); gradle.setBaseProjectClassLoaderScope(buildSrcClassLoaderScope); generateDependenciesAccessorsAndAssignPluginVersions(gradle.getServices(), settings, buildSrcClassLoaderScope); buildLoader.load(gradle.getSettings(), gradle); if (gradle.isRootBuild()) { coordinator.registerGlobalLibrarySubstitutions(); } buildBuildSrcAndLockClassloader(gradle, buildSrcClassLoaderScope); delegate.prepareProjects(gradle); } }
设置classloader 1 2 3 4 5 6 7 8 SettingsInternal settings = gradle.getSettings(); ClassLoaderScope settingsClassLoaderScope = settings.getClassLoaderScope(); ClassLoaderScope buildSrcClassLoaderScope = settingsClassLoaderScope.createChild("buildSrc[" + gradle.getIdentityPath() + "]" ); gradle.setBaseProjectClassLoaderScope(buildSrcClassLoaderScope); generateDependenciesAccessorsAndAssignPluginVersions(gradle.getServices(), settings, buildSrcClassLoaderScope);
attach root project
buildLoader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 protected BuildLoader createBuildLoader ( GradleProperties gradleProperties, BuildOperationExecutor buildOperationExecutor, ListenerManager listenerManager ) { return new NotifyingBuildLoader ( new ProjectPropertySettingBuildLoader ( gradleProperties, new InstantiatingBuildLoader (), listenerManager.getBroadcaster(FileResourceListener.class) ), buildOperationExecutor ); }
触发位置
1 2 buildLoader.load(gradle.getSettings(), gradle);
具体的load逻辑
1 2 3 4 5 6 7 8 9 10 11 public class InstantiatingBuildLoader implements BuildLoader { @Override public void load (SettingsInternal settings, GradleInternal gradle) { createProjects(gradle, settings.getProjectRegistry().getRootProject()); attachDefaultProject(gradle, settings.getDefaultProject()); } }
使用include build做依赖替换 1 2 3 4 5 6 7 8 9 if (gradle.isRootBuild()) { coordinator.registerGlobalLibrarySubstitutions(); } public void registerGlobalLibrarySubstitutions () { for (IncludedBuildState includedBuild : libraryBuilds) { buildStateRegistry.registerSubstitutionsFor(includedBuild); } }
打包buildsrc并把其加载到classpath 1 2 3 4 5 6 buildBuildSrcAndLockClassloader(gradle, buildSrcClassLoaderScope); private void buildBuildSrcAndLockClassloader (GradleInternal gradle, ClassLoaderScope baseProjectClassLoaderScope) { ClassPath buildSrcClassPath = buildSourceBuilder.buildAndGetClassPath(gradle); baseProjectClassLoaderScope.export(buildSrcClassPath).lock(); }
delegate
delegate.prepareProjects (即DefaultProjectsPreparer)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 delegate.prepareProjects(gradle); @Override public void prepareProjects (GradleInternal gradle) { if (!buildModelParameters.isConfigureOnDemand() || !gradle.isRootBuild()) { projectConfigurer.configureHierarchy(gradle.getRootProject()); new ProjectsEvaluatedNotifier (buildOperationExecutor).notify(gradle); } if (gradle.isRootBuild()) { buildStateRegistry.afterConfigureRootBuild(); } modelConfigurationListener.onConfigure(gradle); }
后续的流程由projectConfigurer.configureHierarchy(gradle.getRootProject());触发
他会触发当前project和当前project的子project的configure操作
1 2 3 4 5 6 7 @Override public void configureHierarchy (ProjectInternal project) { configure(project); for (Project sub : project.getSubprojects()) { configure((ProjectInternal) sub); } }
project lifecycle
project 的configure操作又会触发另外一个lifecycle的执行——即ProjectLifecycleController
project lifecycle有三个状态,实例化以后状态就处于NotCreated,调用了create以后就进入了Created状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void createMutableModel ( DefaultProjectDescriptor descriptor, BuildState build, ProjectState owner, ClassLoaderScope selfClassLoaderScope, ClassLoaderScope baseClassLoaderScope, IProjectFactory projectFactory ) { controller.transition(State.NotCreated, State.Created, () -> { ProjectState parent = owner.getBuildParent(); ProjectInternal parentModel = parent == null ? null : parent.getMutableModel(); project = projectFactory.createProject(build.getMutableModel(), descriptor, owner, parentModel, selfClassLoaderScope, baseClassLoaderScope); }); }
状态迁移又会触发ProjectInternal的evaluate方法
1 2 3 public void ensureSelfConfigured () { controller.maybeTransitionIfNotCurrentlyTransitioning(State.Created, State.Configured, () -> project.evaluate()); }
接着会通过ConfigureActionsProjectEvaluator触发build.gradle dsl的执行
1 2 3 4 5 6 7 8 9 10 11 12 13 fun createProjectEvaluator ( buildOperationExecutor: BuildOperationExecutor , cachingServiceLocator: CachingServiceLocator , scriptPluginFactory: ScriptPluginFactory , cancellationToken: BuildCancellationToken ) : ProjectEvaluator { val withActionsEvaluator = ConfigureActionsProjectEvaluator( PluginsProjectConfigureActions.from(cachingServiceLocator), BuildScriptProcessor(scriptPluginFactory), DelayedConfigurationActions() ) return LifecycleProjectEvaluator(buildOperationExecutor, withActionsEvaluator, cancellationToken) }
1 2 3 4 5 public void evaluate (ProjectInternal project, ProjectStateInternal state) { for (ProjectConfigureAction configureAction : configureActions) { configureAction.execute(project); } }
script执行
dsl的执行是由ConfigureActionsProjectEvaluator中BuildScriptProcessor完成的
其中BuildScriptProcessor包含一个ScriptPluginFactory,
execute的过程中会通过ScriptPluginFactory编译指定的build.gradle文件。
加载到指定的classloader中去。
调用apply方法执行build.gradle脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class BuildScriptProcessor implements ProjectConfigureAction { private static final Logger LOGGER = LoggerFactory.getLogger(BuildScriptProcessor.class); private final ScriptPluginFactory configurerFactory; public BuildScriptProcessor (ScriptPluginFactory configurerFactory) { this .configurerFactory = configurerFactory; } @Override public void execute (final ProjectInternal project) { final Timer clock = Time.startTimer(); try { final ScriptPlugin configurer = configurerFactory.create(project.getBuildScriptSource(), project.getBuildscript(), project.getClassLoaderScope(), project.getBaseClassLoaderScope(), true ); project.getOwner().applyToMutableState(configurer::apply); } } }
KotlinScriptPlugin会把执行委托给script代码快
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class KotlinScriptPlugin ( private val scriptSource: ScriptSource, private val script: (Any) -> Unit ) : ScriptPlugin { override fun getSource () = scriptSource override fun apply (target: Any ) { logger.debug("Applying Kotlin script to {}" , target) script(target) } } KotlinScriptPlugin(scriptSource) { target -> kotlinScriptEvaluator .evaluate( target, scriptSource, scriptHandler, targetScope, baseScope, topLevelScript, kotlinScriptOptions() ) }
流程就到了evaluator完成script的执行
evaluator内有一个interpretor对script代码进行编译执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 internal class StandardKotlinScriptEvaluator ( private val classPathProvider: KotlinScriptClassPathProvider, private val classloadingCache: KotlinScriptClassloadingCache, private val pluginRequestApplicator: PluginRequestApplicator, private val pluginRequestsHandler: PluginRequestsHandler, private val embeddedKotlinProvider: EmbeddedKotlinProvider, private val classPathModeExceptionCollector: ClassPathModeExceptionCollector, private val kotlinScriptBasePluginsApplicator: KotlinScriptBasePluginsApplicator, private val scriptSourceHasher: ScriptSourceHasher, private val classpathHasher: ClasspathHasher, private val implicitImports: ImplicitImports, private val progressLoggerFactory: ProgressLoggerFactory, private val buildOperationExecutor: BuildOperationExecutor, private val cachedClasspathTransformer: CachedClasspathTransformer, private val scriptExecutionListener: ScriptExecutionListener, private val executionEngine: ExecutionEngine, private val workspaceProvider: KotlinDslWorkspaceProvider, private val fileCollectionFactory: FileCollectionFactory, private val inputFingerprinter: InputFingerprinter ) : KotlinScriptEvaluator { override fun evaluate ( target: Any , scriptSource: ScriptSource , scriptHandler: ScriptHandler , targetScope: ClassLoaderScope , baseScope: ClassLoaderScope , topLevelScript: Boolean , options: EvalOptions ) { withOptions(options) { interpreter.eval( target, scriptSource, scriptSourceHasher.hash(scriptSource), scriptHandler, targetScope, baseScope, topLevelScript, options ) } } }
Interpretor编译执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 fun eval ( target: Any , scriptSource: ScriptSource , sourceHash: HashCode , scriptHandler: ScriptHandler , targetScope: ClassLoaderScope , baseScope: ClassLoaderScope , topLevelScript: Boolean , options: EvalOptions = defaultEvalOptions ) { programHost.eval(specializedProgram, scriptHost) } fun eval (compiledScript: CompiledScript , scriptHost: KotlinScriptHost <*>) { val program = load(compiledScript, scriptHost) withContextClassLoader(program.classLoader) { host.onScriptClassLoaded(scriptHost.scriptSource, program) instantiate(program).execute(this , scriptHost) } }
task
这一过程的职责很单一即,准备task,对task进行拓扑排序。获得拓扑排序后的节点。
BuildTreeWorkPreparer中有两个步骤
configure modules ()
configure tasks
1 2 3 4 5 6 7 8 9 10 11 12 13 public class DefaultBuildTreeWorkPreparer implements BuildTreeWorkPreparer { public BuildTreeWorkGraph.FinalizedGraph scheduleRequestedTasks (BuildTreeWorkGraph graph, @Nullable EntryTaskSelector selector) { targetBuildController.prepareToScheduleTasks(); return graph.scheduleWork(graphBuilder -> { graphBuilder.withWorkGraph(targetBuild, builder -> builder.addRequestedTasks(selector)); }); } }
主要完成了
workGraphPreparer的方法初始化配置项
controllers准备tasks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Override public FinalizedGraph scheduleWork (Consumer<? super Builder> action) { assertIsOwner(); expectInState(State.NotPrepared); state = State.Preparing; buildOperationExecutor.run(new RunnableBuildOperation () { @Override public void run (BuildOperationContext context) { DefaultBuildTreeWorkGraphBuilder graphBuilder = new DefaultBuildTreeWorkGraphBuilder (DefaultBuildTreeWorkGraph.this ); workGraphPreparer.prepareToScheduleTasks(graphBuilder); action.accept(graphBuilder); controllers.populateWorkGraphs(); context.setResult(new CalculateTreeTaskGraphBuildOperationType .Result() { }); } @Override public BuildOperationDescriptor.Builder description () { return BuildOperationDescriptor.displayName("Calculate build tree task graph" ) .details(new CalculateTreeTaskGraphBuildOperationType .Details() { }); } }); state = State.ReadyToRun; return this ; }
简单看看拓扑排序的过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 private void processNodeQueue () { while (!nodeQueue.isEmpty()) { final NodeInVisitingSegment nodeInVisitingSegment = nodeQueue.peekFirst(); final int currentSegment = nodeInVisitingSegment.visitingSegment; final Node node = nodeInVisitingSegment.node; if (visitingNodes.put(node, currentSegment)) { if (node instanceof TaskNode) { TaskNode taskNode = (TaskNode) node; recordEdgeIfArrivedViaShouldRunAfter(path, taskNode); removeShouldRunAfterSuccessorsIfTheyImposeACycle(taskNode, nodeInVisitingSegment.visitingSegment); takePlanSnapshotIfCanBeRestoredToCurrentTask(planBeforeVisiting, taskNode); } for (Node finalizer : node.getFinalizers()) { addFinalizerToQueue(visitingSegmentCounter++, finalizer); } ListIterator<NodeInVisitingSegment> insertPoint = nodeQueue.listIterator(); for (Node successor : node.getAllSuccessors()) { if (visitingNodes.containsEntry(successor, currentSegment)) { if (!walkedShouldRunAfterEdges.isEmpty()) { GraphEdge toBeRemoved = walkedShouldRunAfterEdges.pop(); TaskNode sourceTask = (TaskNode) toBeRemoved.from; TaskNode targetTask = (TaskNode) toBeRemoved.to; sourceTask.removeShouldSuccessor(targetTask); restorePath(path, toBeRemoved); restoreQueue(toBeRemoved); restoreExecutionPlan(planBeforeVisiting, toBeRemoved); break ; } else { onOrderingCycle(successor, node); } } insertPoint.add(new NodeInVisitingSegment (successor, currentSegment)); } path.push(node); } else { nodeQueue.removeFirst(); maybeRemoveProcessedShouldRunAfterEdge(node); visitingNodes.remove(node, currentSegment); path.pop(); nodeMapping.add(node); } } }
run
run过程即已经拓扑排序后的结果,对task逐一执行。
其中finalizedGraph是上一部task配置的参数
1 return workExecutor.execute(finalizedGraph);
首先会经过两层prepare的配置
1 2 3 4 5 6 7 8 protected BuildWorkPreparer createWorkPreparer (BuildOperationExecutor buildOperationExecutor, ExecutionPlanFactory executionPlanFactory) { return new BuildOperationFiringBuildWorkPreparer ( buildOperationExecutor, new DefaultBuildWorkPreparer ( executionPlanFactory )); }
之后会向线程池中放入一个runnable——ExecutorWorker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public void run () { try { boolean releaseLeaseOnCompletion; if (workerLease == null ) { workerLease = workerLeaseService.newWorkerLease(); releaseLeaseOnCompletion = true ; } else { releaseLeaseOnCompletion = false ; } while (true ) { WorkItem workItem = getNextItem(workerLease); if (workItem == null ) { break ; } Object selected = workItem.selection.getItem(); LOGGER.info("{} ({}) started." , selected, Thread.currentThread()); execute(selected, workItem.plan, workItem.executor); } if (releaseLeaseOnCompletion) { coordinationService.withStateLock(() -> workerLease.unlock()); } } finally { stats.finish(); } }
最后经过一系列executor & action之后就开始执行task了(这些不是核心逻辑。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 TaskExecuter createTaskExecuter ( AsyncWorkTracker asyncWorkTracker, BuildCacheController buildCacheController, BuildOperationExecutor buildOperationExecutor, BuildOutputCleanupRegistry cleanupRegistry, GradleEnterprisePluginManager gradleEnterprisePluginManager, ClassLoaderHierarchyHasher classLoaderHierarchyHasher, Deleter deleter, ExecutionHistoryStore executionHistoryStore, FileCollectionFactory fileCollectionFactory, FileOperations fileOperations, ListenerManager listenerManager, OutputChangeListener outputChangeListener, OutputFilesRepository outputFilesRepository, ReservedFileSystemLocationRegistry reservedFileSystemLocationRegistry, org.gradle.api.execution.TaskActionListener actionListener, TaskCacheabilityResolver taskCacheabilityResolver, TaskExecutionGraphInternal taskExecutionGraph, org.gradle.api.execution.TaskExecutionListener taskExecutionListener, TaskExecutionModeResolver repository, TaskListenerInternal taskListenerInternal, ExecutionEngine executionEngine, InputFingerprinter inputFingerprinter ) { TaskExecuter executer = new ExecuteActionsTaskExecuter ( buildCacheController.isEnabled() ? ExecuteActionsTaskExecuter.BuildCacheState.ENABLED : ExecuteActionsTaskExecuter.BuildCacheState.DISABLED, gradleEnterprisePluginManager.isPresent() ? ExecuteActionsTaskExecuter.ScanPluginState.APPLIED : ExecuteActionsTaskExecuter.ScanPluginState.NOT_APPLIED, executionHistoryStore, buildOperationExecutor, asyncWorkTracker, actionListener, taskCacheabilityResolver, classLoaderHierarchyHasher, executionEngine, inputFingerprinter, listenerManager, reservedFileSystemLocationRegistry, fileCollectionFactory, fileOperations ); executer = new CleanupStaleOutputsExecuter ( buildOperationExecutor, cleanupRegistry, deleter, outputChangeListener, outputFilesRepository, executer ); executer = new FinalizePropertiesTaskExecuter (executer); executer = new ResolveTaskExecutionModeExecuter (repository, executer); executer = new SkipTaskWithNoActionsExecuter (taskExecutionGraph, executer); executer = new SkipOnlyIfTaskExecuter (executer); executer = new CatchExceptionTaskExecuter (executer); executer = new EventFiringTaskExecuter (buildOperationExecutor, taskExecutionListener, taskListenerInternal, executer); return executer; }
其中ExecuteActionsTaskExecuter包含了一个ExecutionEngine,这个Engine包含有很多的actions。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public ExecutionEngine createExecutionEngine ( BuildCacheController buildCacheController, BuildCancellationToken cancellationToken, BuildInvocationScopeId buildInvocationScopeId, BuildOperationExecutor buildOperationExecutor, BuildOutputCleanupRegistry buildOutputCleanupRegistry, GradleEnterprisePluginManager gradleEnterprisePluginManager, ClassLoaderHierarchyHasher classLoaderHierarchyHasher, CurrentBuildOperationRef currentBuildOperationRef, Deleter deleter, ExecutionStateChangeDetector changeDetector, OutputChangeListener outputChangeListener, WorkInputListeners workInputListeners, OutputFilesRepository outputFilesRepository, OutputSnapshotter outputSnapshotter, OverlappingOutputDetector overlappingOutputDetector, TimeoutHandler timeoutHandler, ValidateStep.ValidationWarningRecorder validationWarningRecorder, VirtualFileSystem virtualFileSystem, DocumentationRegistry documentationRegistry ) { Supplier<OutputsCleaner> skipEmptyWorkOutputsCleanerSupplier = () -> new OutputsCleaner (deleter, buildOutputCleanupRegistry::isOutputOwnedByBuild, buildOutputCleanupRegistry::isOutputOwnedByBuild); return new DefaultExecutionEngine (documentationRegistry, new IdentifyStep <>( new IdentityCacheStep <>( new AssignWorkspaceStep <>( new LoadPreviousExecutionStateStep <>( new MarkSnapshottingInputsStartedStep <>( new RemoveUntrackedExecutionStateStep <>( new SkipEmptyWorkStep (outputChangeListener, workInputListeners, skipEmptyWorkOutputsCleanerSupplier, new CaptureStateBeforeExecutionStep <>(buildOperationExecutor, classLoaderHierarchyHasher, outputSnapshotter, overlappingOutputDetector, new ValidateStep <>(virtualFileSystem, validationWarningRecorder, new ResolveCachingStateStep <>(buildCacheController, gradleEnterprisePluginManager.isPresent(), new MarkSnapshottingInputsFinishedStep <>( new ResolveChangesStep <>(changeDetector, new SkipUpToDateStep <>( new RecordOutputsStep <>(outputFilesRepository, new StoreExecutionStateStep <>( new BuildCacheStep (buildCacheController, deleter, outputChangeListener, new ResolveInputChangesStep <>( new CaptureStateAfterExecutionStep <>(buildOperationExecutor, buildInvocationScopeId.getId(), outputSnapshotter, outputChangeListener, new CreateOutputsStep <>( new TimeoutStep <>(timeoutHandler, currentBuildOperationRef, new CancelExecutionStep <>(cancellationToken, new RemovePreviousOutputsStep <>(deleter, outputChangeListener, new ExecuteStep <>(buildOperationExecutor )))))))))))))))))))))))); }
最后一个ExecuteStep会触发task的执行。
其中Task是一个简单包裹的数据结构
其执行过程,其实也就是把所有的actions都遍历调用execute方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private void executeActions (TaskInternal task, @Nullable InputChangesInternal inputChanges) { boolean hasTaskListener = listenerManager.hasListeners(org.gradle.api.execution.TaskActionListener.class) || listenerManager.hasListeners(org.gradle.api.execution.TaskExecutionListener.class); Iterator<InputChangesAwareTaskAction> actions = new ArrayList <>(task.getTaskActions()).iterator(); while (actions.hasNext()) { InputChangesAwareTaskAction action = actions.next(); task.getState().setDidWork(true ); task.getStandardOutputCapture().start(); boolean hasMoreWork = hasTaskListener || actions.hasNext(); try { executeAction(action.getDisplayName(), task, action, inputChanges, hasMoreWork); } catch (StopActionException e) { LOGGER.debug("Action stopped by some action with message: {}" , e.getMessage()); } catch (StopExecutionException e) { LOGGER.info("Execution stopped by some action with message: {}" , e.getMessage()); break ; } finally { task.getStandardOutputCapture().stop(); } } }
缘灭
诶~灭不了了。