skip to content

How do you make a subproject use a build file with a non-default name, and why might you want to?

level: middleimportance: should knowfreq 30%

answer

  1. buildFileName on ProjectDescriptor
  2. default build.gradle.kts per dir
  3. resolved relative to projectDir
  4. deprecated in modern Gradle
  5. prefer convention now

basics

~10 s

Set the descriptor's buildFileName in settings.gradle.kts: project(":lib").buildFileName = "lib.gradle.kts". Gradle then reads that file instead of the default build.gradle.kts in the project directory.

solid answer

~30 s

By default Gradle looks for `build.gradle.kts` (or `build.gradle`) inside each project's directory. You can override the filename per project via the `ProjectDescriptor` in `settings.gradle.kts`: ```kotlin include(":lib") project(":lib").buildFileName = "lib.gradle.kts" ``` Useful reasons: distinguishing build files when several projects share a directory layout, giving each module a uniquely named, greppable build file, or supporting legacy/imported layouts. Note that `buildFileName` is **deprecated** in modern Gradle in favour of the conventional `build.gradle.kts` per directory — so prefer the default unless you have a concrete need. The filename is resolved relative to the project's `projectDir`, so it works together with a customized `projectDir`.

code

kotlin · 6 lines
kotlin
// settings.gradle.kts
include(":lib")
project(":lib").apply {
    projectDir = file("libs/lib")
    buildFileName = "lib.gradle.kts" // reads libs/lib/lib.gradle.kts (deprecated)
}

go deeper

for a junior

Know the default is build.gradle.kts and that a property can override the name in settings.

for a middle

Set buildFileName on the descriptor, explain it resolves against projectDir, and note it composes with a custom projectDir.

for a senior

Mention the deprecation and steer toward the per-directory convention; reserve overrides for legacy layouts.

for a principal

Advocate convention-over-configuration org-wide so tooling and IDEs stay predictable; treat custom build-file names as tech debt.

## The default build-file convention Gradle's convention is one build file per project directory, named `build.gradle.kts` (Kotlin DSL) or `build.gradle` (Groovy DSL). When Gradle configures project `:lib` it reads the build script from `<lib projectDir>/build.gradle.kts`. This convention-over-configuration approach means most builds never touch the filename. ## Overriding the build-file name The `ProjectDescriptor` exposes a mutable `buildFileName` property, settable at settings-evaluation time: ```kotlin include(":lib") project(":lib").buildFileName = "lib.gradle.kts" ``` Gradle then reads `<lib projectDir>/lib.gradle.kts` instead of the default. Because the name is resolved against the project's `projectDir`, it composes naturally with a relocated directory: ```kotlin include(":lib") project(":lib").apply { projectDir = file("libs/lib") buildFileName = "lib.gradle.kts" } // reads libs/lib/lib.gradle.kts ``` ## Why teams used it Historically the motivations were: uniquely named build files for easier IDE navigation and grepping; supporting unusual or imported directory layouts where multiple logical concerns live near each other; and migration of non-standard legacy builds. ## Important: deprecation In modern Gradle (8.x) `ProjectDescriptor.buildFileName` is **deprecated**. The Gradle team standardised on the conventional per-directory `build.gradle.kts` to keep builds predictable and tooling-friendly. New code should rely on the default filename and use `projectDir` (which is not deprecated) when it only needs to relocate the directory. In interviews, knowing that `buildFileName` exists, what it did, and that it is now discouraged is the complete answer. ## Relationship to projectDir `projectDir` controls WHERE the project lives; `buildFileName` controls WHAT the build script is called inside that directory. They are independent descriptor properties — you can set either, both, or neither — but in current practice you almost always set only `projectDir`.

  • Where is buildFileName resolved relative to?
    Relative to the project's projectDir. So if projectDir is libs/lib and buildFileName is lib.gradle.kts, Gradle reads libs/lib/lib.gradle.kts.
  • Is buildFileName recommended in modern Gradle?
    No. It's deprecated; the conventional per-directory build.gradle.kts is preferred. Use it only for legacy compatibility, and prefer projectDir for relocation needs.

saying these in an interview costs you the question

  • Claiming buildFileName is the current best practice rather than a deprecated escape hatch
  • Saying buildFileName is resolved relative to the root rather than the project's projectDir

context