Skip to content

Commit 9cdec83

Browse files
committed
kbuild: Use tuxmake native fragment support with --kconfig-add
Switch to tuxmake's native --kconfig-add parameter for applying configuration fragments instead of manually merging them. Add --output-dir to specify where tuxmake places build artifacts. Build the dtbs target for architectures that support it. Handle multiple defconfigs by passing the first to --kconfig and the rest as --kconfig-add. Handle ChromeOS defconfig by pre-creating the .config file. Reviewed-by: Ben Copeland <ben.copeland@linaro.org> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
1 parent f037259 commit 9cdec83

File tree

1 file changed

+95
-16
lines changed

1 file changed

+95
-16
lines changed

kernelci/kbuild.py

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -593,10 +593,17 @@ def _parse_fragments(self, firmware=False):
593593
# Use fragment configs passed from scheduler
594594
content = self.add_fragment(fragment)
595595

596+
if not content:
597+
print(f"[_parse_fragments] WARNING: Fragment {fragment} has no content")
598+
continue
599+
596600
fragfile = os.path.join(self._fragments_dir, f"{idx}.config")
597601
with open(fragfile, 'w') as f:
598602
f.write(content)
599603

604+
config_count = len([line for line in content.split('\n') if line.strip()])
605+
print(f"[_parse_fragments] Created {fragfile} ({config_count} configs)")
606+
600607
fragment_files.append(fragfile)
601608

602609
# add fragment to artifacts but relative to artifacts dir
@@ -610,12 +617,14 @@ def _parse_fragments(self, firmware=False):
610617
with open(fragfile, 'w') as f:
611618
f.write(content)
612619

613-
fragment_files.append(fragfile)
614-
615-
# add fragment to artifacts but relative to artifacts dir
616-
frag_rel = os.path.relpath(fragfile, self._af_dir)
617-
self._artifacts.append(frag_rel)
620+
if os.path.exists(fragfile):
621+
fragment_files.append(fragfile)
622+
frag_rel = os.path.relpath(fragfile, self._af_dir)
623+
self._artifacts.append(frag_rel)
624+
else:
625+
print("[_parse_fragments] ERROR: Failed to create firmware fragment")
618626

627+
print(f"[_parse_fragments] Created {len(fragment_files)} fragment files")
619628
return fragment_files
620629

621630
def _merge_frags(self, fragment_files):
@@ -727,18 +736,78 @@ def _build_with_make(self):
727736
self._build_dtbs_check()
728737

729738
def _build_with_tuxmake(self):
730-
""" Build kernel using tuxmake """
739+
""" Build kernel using tuxmake with native fragment support """
740+
print("[_build_with_tuxmake] Starting tuxmake build")
741+
742+
if not hasattr(self, '_fragment_files'):
743+
print("[_build_with_tuxmake] ERROR: No fragment files available")
744+
self._fragment_files = []
745+
746+
print(f"[_build_with_tuxmake] Using {len(self._fragment_files)} fragment files")
747+
748+
# Handle defconfigs - first goes to --kconfig, rest to --kconfig-add
749+
extra_defconfigs = []
750+
if isinstance(self._defconfig, list):
751+
defconfig = self._defconfig[0]
752+
extra_defconfigs = self._defconfig[1:]
753+
self._config_full = '+'.join(self._defconfig) + self._config_full
754+
elif isinstance(self._defconfig, str):
755+
defconfig = self._defconfig
756+
self._config_full = self._defconfig + self._config_full
757+
else:
758+
defconfig = 'defconfig'
759+
print("[_build_with_tuxmake] WARNING: No defconfig specified, using 'defconfig'")
760+
761+
# Fetch firmware for builds that need it
762+
self._fetch_firmware()
763+
731764
self.startjob("build_tuxmake")
732765
self.addcmd("cd " + self._srcdir)
733766

734-
tuxmake_cmd = (
735-
f"tuxmake --runtime=null "
736-
f"--target-arch={self._arch} "
737-
f"--toolchain={self._compiler} "
738-
f"kernel modules"
739-
)
767+
use_kconfig_flag = True
740768

741-
print(f"Building with tuxmake: {tuxmake_cmd}")
769+
# Handle ChromeOS defconfig
770+
if defconfig.startswith('cros://'):
771+
print(f"[_build_with_tuxmake] Handling ChromeOS defconfig: {defconfig}")
772+
dotconfig = os.path.join(self._srcdir, ".config")
773+
content, defconfig_name = self._getcrosfragment(defconfig)
774+
with open(dotconfig, 'w') as f:
775+
f.write(content)
776+
self.addcmd("make olddefconfig")
777+
use_kconfig_flag = False
778+
779+
cmd_parts = [
780+
"tuxmake --runtime=null",
781+
f"--target-arch={self._arch}",
782+
f"--toolchain={self._compiler}",
783+
f"--output-dir={self._af_dir}",
784+
]
785+
786+
if use_kconfig_flag:
787+
cmd_parts.append(f"--kconfig={defconfig}")
788+
for extra in extra_defconfigs:
789+
cmd_parts.append(f"--kconfig-add={extra}")
790+
print(f"[_build_with_tuxmake] Adding extra defconfig: {extra}")
791+
792+
for fragfile in self._fragment_files:
793+
if os.path.exists(fragfile):
794+
cmd_parts.append(f"--kconfig-add={fragfile}")
795+
print(f"[_build_with_tuxmake] Adding fragment: {os.path.basename(fragfile)}")
796+
else:
797+
print(f"[_build_with_tuxmake] WARNING: Fragment file not found: {fragfile}")
798+
799+
# Build targets: kernel modules, plus dtbs if arch supports it
800+
targets = ["kernel", "modules"]
801+
if self._arch not in DTBS_DISABLED:
802+
targets.append("dtbs")
803+
if self._kfselftest:
804+
targets.append("kselftest")
805+
cmd_parts.append(" ".join(targets))
806+
print(f"[_build_with_tuxmake] Building targets: {' '.join(targets)}")
807+
808+
tuxmake_cmd = " ".join(cmd_parts)
809+
print(f"[_build_with_tuxmake] Command: {tuxmake_cmd}")
810+
print(f"[_build_with_tuxmake] Output directory: {self._af_dir}")
742811
self.addcmd(tuxmake_cmd)
743812

744813
# tuxmake outputs 'config' (no dot), rename to '.config' for consistency
@@ -996,9 +1065,19 @@ def upload_artifacts(self):
9961065

9971066
# Prepare all artifacts for upload
9981067
upload_tasks = []
999-
for artifact in self._artifacts:
1000-
artifact_path = os.path.join(self._af_dir, artifact)
1001-
upload_tasks.append((artifact, artifact_path))
1068+
if self._backend == 'tuxmake':
1069+
# For TuxMake, upload everything in artifacts directory
1070+
print("[_upload_artifacts] TuxMake backend: discovering files in artifacts dir")
1071+
for root, dirs, files in os.walk(self._af_dir):
1072+
for file in files:
1073+
file_rel = os.path.relpath(os.path.join(root, file), self._af_dir)
1074+
artifact_path = os.path.join(self._af_dir, file_rel)
1075+
upload_tasks.append((file_rel, artifact_path))
1076+
else:
1077+
# For make backend, upload only listed artifacts
1078+
for artifact in self._artifacts:
1079+
artifact_path = os.path.join(self._af_dir, artifact)
1080+
upload_tasks.append((artifact, artifact_path))
10021081

10031082
# Function to handle a single artifact upload
10041083
# args: (artifact, artifact_path)

0 commit comments

Comments
 (0)