ninjabackend: fix class file path to include build_subdir

Compute the class file path relative to the private dir
using the full name of the .class file, not just the src.fname.
For example, for target subdir "java" and source
"java/icd/Api.java", the class path is "icd/Api.class" rather
than just "Api.class".

Using the wrong class file name caused unnecessary rebuilds
of jar files.

Fixes: #15582
This commit is contained in:
Paolo Bonzini authored and Paolo Bonzini committed 2026-03-06 15:41:00 +01:00
1 parent e16d8b0a70
commit 1edb401fe8
5 files changed
+38 -2

No files matched your search

+3 -1
View File
@@ -1614,7 +1614,9 @@ class NinjaBackend(backends.Backend):
rel_src = src.rel_to_builddir(self.build_to_src)
rel_srcs.append(rel_src)
plain_class_path = src.fname[:-4] + 'class'
# Preserve any additional path components on top of the target's subdir
plain_class_path = os.path.relpath(src.relative_name(), target.get_subdir())
plain_class_path = plain_class_path[:-4] + 'class'
plain_class_paths.append(plain_class_path)
rel_obj = os.path.join(self.get_target_private_dir(target), plain_class_path)
rel_objs.append(rel_obj)
@@ -0,0 +1,7 @@
package com.mesonbuild;
public class HelloWorldMainLauncherClass {
public static void main(String [] args) {
System.out.println("hello nanowar of steel");
}
}
@@ -0,0 +1,6 @@
#!/usr/bin/env python3
import sys
import shutil
shutil.copyfile(sys.argv[1], sys.argv[2])
@@ -0,0 +1,13 @@
project('build subdir java', 'java')
copyfile = find_program('copyfile.py')
generated = custom_target(
command: [copyfile, '@INPUT@', '@OUTPUT@'],
input: 'com-mesonbuild-HelloWorldMainLauncherClass.java',
output: 'HelloWorldMainLauncherClass.java',
build_subdir: 'com/mesonbuild',
)
jar('hello', generated,
main_class: 'com.mesonbuild.HelloWorldMainLauncherClass')
+9 -1
View File
@@ -15,7 +15,7 @@ from unittest import skipIf, SkipTest
from pathlib import Path
from .baseplatformtests import BasePlatformTests
from .helpers import IS_CI
from .helpers import *
from mesonbuild.mesonlib import EnvironmentVariables, ExecutableSerialisation, MesonException, is_linux, python_command, windows_proof_rmtree
from mesonbuild.mformat import Formatter, match_path
from mesonbuild.optinterpreter import OptionInterpreter, OptionException
@@ -626,3 +626,11 @@ class PlatformAgnosticTests(BasePlatformTests):
self.init(testdir)
self.build()
@skip_if_not_language('java')
def test_java_build_subdir_correct_deps(self):
"""Test that jar() with build_subdir sources does not rebuild unnecessarily."""
testdir = os.path.join(self.src_root, 'test cases', 'java', '11 build subdir')
self.init(testdir)
self.build()
self.assertBuildIsNoop()