@@ -108,6 +108,26 @@ class FuzzTargetsPlugin : Plugin<Project> {
108108 val crashDir = extension.crashDir.get().asFile
109109 val duration = extension.duration.get()
110110
111+ // Profiler sources are identical for every fuzz target (same compiler args and
112+ // includes), so compile them once and share the resulting objects across targets
113+ // instead of recompiling the whole profiler per target.
114+ val sharedObjDir = project.file(" ${project.layout.buildDirectory.get()} /obj/fuzz/_profiler" )
115+ val compileProfilerTask = project.tasks.register(" compileFuzzProfilerSources" , NativeCompileTask ::class .java) {
116+ onlyIf { hasFuzzer && ! project.hasProperty(" skip-tests" ) && ! project.hasProperty(" skip-native" ) && ! project.hasProperty(" skip-fuzz" ) }
117+ group = " build"
118+ description = " Compile the profiler sources shared by all fuzz targets"
119+
120+ this .compiler.set(compiler)
121+ this .compilerArgs.set(compilerArgs)
122+ sources.from(
123+ extension.profilerSourceDir.map { dir ->
124+ project.fileTree(dir) { include(" **/*.cpp" ) }
125+ }
126+ )
127+ includes.from(includeFiles)
128+ objectFileDir.set(sharedObjDir)
129+ }
130+
111131 // Discover and create tasks for each fuzz target
112132 if (fuzzSourceDir.exists()) {
113133 fuzzSourceDir.listFiles()?.filter { file -> file.name.endsWith(" .cpp" ) }?.forEach { fuzzFile ->
@@ -119,34 +139,33 @@ class FuzzTargetsPlugin : Plugin<Project> {
119139 val binary = project.file(" $binDir /$fuzzName " )
120140 val targetCorpusDir = File (corpusBaseDir, fuzzName)
121141
122- // Compile task
142+ // Compile task - only compiles this target's own fuzz driver; profiler
143+ // sources come from the shared compileFuzzProfilerSources task.
123144 val compileTask = project.tasks.register(" compileFuzz_$fuzzName " , NativeCompileTask ::class .java) {
124145 onlyIf { hasFuzzer && ! project.hasProperty(" skip-tests" ) && ! project.hasProperty(" skip-native" ) && ! project.hasProperty(" skip-fuzz" ) }
125146 group = " build"
126147 description = " Compile the fuzz target $fuzzName "
127148
128149 this .compiler.set(compiler)
129150 this .compilerArgs.set(compilerArgs)
130- sources.from(
131- extension.profilerSourceDir.map { dir ->
132- project.fileTree(dir) { include(" **/*.cpp" ) }
133- },
134- fuzzFile
135- )
151+ sources.from(fuzzFile)
136152 includes.from(includeFiles)
137153 objectFileDir.set(objDir)
138154 }
139155
140156 // Link task
141157 val linkTask = project.tasks.register(" linkFuzz_$fuzzName " , NativeLinkExecutableTask ::class .java) {
142158 onlyIf { hasFuzzer && ! project.hasProperty(" skip-tests" ) && ! project.hasProperty(" skip-native" ) && ! project.hasProperty(" skip-fuzz" ) }
143- dependsOn(compileTask)
159+ dependsOn(compileProfilerTask, compileTask)
144160 group = " build"
145161 description = " Link the fuzz target $fuzzName "
146162
147163 linker.set(compiler)
148164 this .linkerArgs.set(linkerArgs)
149- objectFiles.from(project.fileTree(objDir) { include(" *.o" ) })
165+ objectFiles.from(
166+ project.fileTree(sharedObjDir) { include(" *.o" ) },
167+ project.fileTree(objDir) { include(" *.o" ) }
168+ )
150169 outputFile.set(binary)
151170 }
152171
0 commit comments