Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "objects" support to Rust targets #14031

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

bonzini
Copy link
Contributor

@bonzini bonzini commented Dec 20, 2024

Because rustc does not support extract_objects, QEMU creates a static library
with all the C objects. It then passes this static library as link_whole,
together with another static library containing general purpose utility
functions which is passed as link_with.

However, this is brittle because the two have a circular dependency and
they cannot be merged because of the link_whole/link_with difference.
While lld seems to have the --start-group/--end-group semantics
automatically, ld.bfd can fail if these options are needed. This can
cause difference between distros depending on how Rust is packaged
(e.g. Ubuntu 22.04 and Debian bookworm seem to use ld.bfd).

The simplest solution is for Meson to implement "objects:" properly
for Rust. Then QEMU can use the same internal dependency objects that it
already has in place for C programs.

To limit conflicts, this PR includes part of #13933.

os.path.abspath of the target subdir is not guaranteed to give a sensible
answer; depending on what directory you run meson from, it could build
an absolute path relative the source directory or the build directory
or possibly neither one.  In fact, using os.path.abspath is quite rare
in Meson's code and generally only done in code like

    subdir = os.path.abspath(os.path.join(self.sourcedir, target['subdir']))

or

    ndir1 = os.path.abspath(os.path.realpath(dir1))

While at it, don't use getattr unnecessarily, the cratetype is available.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Implement RustCompiler.build_rpath_args, so that more code can
be shared between non-Rust and Rust targets.  Then, RustCompiler
can override it to convert the arguments to "-C link-arg=" and
add the rustup sysroot.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Since the introduction of dep-info=... it is possible to move the depfile
away from the main build directory without using --out-dir.  This is
less surprising, since the rules for mixing --emit, --out-dir and -o
are not really documented.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Add functions to RustCompiler() to account for differences
between rustc and "rustdoc --test": rustdoc always generates
a binary, does not support -g, and does not need --emit.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Since we're going to split generate_rust_target() in multiple functions,
eliminate the only variable that spans large parts of it.

The cratetype ninja variable has been unused since Meson started invoking
rustc directly nine years ago (commit d952812, "Fix Rust to work with 1.3
release. Closes mesonbuild#277.", 2015-10-11).

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Allow reusing the code for doctests.  In particular, the sources are
shared between the two cases.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
All Fortran-specific handling of "objects:" is for now in generate_target();
parts of it can be reused for Rust.

Even though Rust is only supported by the ninja backend, move the Fortran
handling entirely outside ninjabackend.py: it's not specific to Ninja,
it can be implemented easily using inheritance, and it also gets better
typing this way.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
@@ -27,7 +27,7 @@

if T.TYPE_CHECKING:
from .. import coredata
from ..build import BuildTarget, DFeatures
from ..build import BuildTarget, BuildTargetTypes, DFeatures

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.compilers.
@@ -27,7 +27,7 @@

if T.TYPE_CHECKING:
from .. import coredata
from ..build import BuildTarget, DFeatures
from ..build import BuildTarget, BuildTargetTypes, DFeatures

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, a
@@ -27,7 +27,7 @@

if T.TYPE_CHECKING:
from .. import coredata
from ..build import BuildTarget, DFeatures
from ..build import BuildTarget, BuildTargetTypes, DFeatures

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
, as the
definition
of DFeatures occurs after the cyclic
import
of mesonbuild.compilers.compilers.
'DFeatures' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.compilers
@@ -27,6 +28,7 @@
)

if T.TYPE_CHECKING:
from ..build import BuildTarget, BuildTargetTypes

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTarget' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTarget occurs after the cyclic
import
of mesonbuild.compilers.fortran.
@@ -27,6 +28,7 @@
)

if T.TYPE_CHECKING:
from ..build import BuildTarget, BuildTargetTypes

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
'BuildTargetTypes' may not be defined if module
mesonbuild.build
is imported before module
mesonbuild.compilers.fortran
, as the
definition
of BuildTargetTypes occurs after the cyclic
import
of mesonbuild.compilers.fortran.
@bonzini bonzini changed the title Add "objects" support to Rust executables Add "objects" support to Rust targets Dec 20, 2024
Because rustc does not support extract_objects, QEMU creates a static library
with all the C objects. It then passes this static library as link_whole,
together with another static library containing general purpose utility
functions which is passed as link_with.

However, this is brittle because the two have a circular dependency and
they cannot be merged because of the link_whole/link_with difference.
While lld seems to have the --start-group/--end-group semantics
automatically, ld.bfd can fail if these options are needed. This can
cause difference between distros depending on how Rust is packaged
(e.g. Ubuntu 22.04 and Debian bookworm seem to use ld.bfd).

The simplest solution is for Meson to implement "objects:" properly
for Rust.  Then QEMU can use the same internal dependency objects that it
already has in place for C programs.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
@bonzini bonzini marked this pull request as ready for review December 20, 2024 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant