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

rust: Require native: true for proc-macro targets and allow linki… #11743

Closed
wants to merge 1 commit into from

Conversation

sdroege
Copy link
Contributor

@sdroege sdroege commented Apr 27, 2023

…ng into targets for other platforms

proc-macros are basically compiler extensions and must be compiled for the build machine so that the compiler can load and execute it at runtime.

Without this, cross-compilation of targets that use proc-macro dependencies is going to fail.

Fixes #11702

@@ -8,6 +8,7 @@ pm = shared_library(
'proc_macro_examples',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of lines above, why is this test disabled on non-Linux, how does it fail? Theoretically there shouldn't be anything special required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sdroege some of the tests are disabled on certain platforms because toolchains might not be setup on those platforms (work needed) or tests can take too long. In this case, you are probably running into the second option. Azure CI takes an ungodly amount of time and will timeout frequently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could very well be historical reasons that have been fixed since then. Feel free to open a separate PR that unskip them and see how it goes on the CI.

@@ -8,6 +8,7 @@ pm = shared_library(
'proc_macro_examples',
'proc.rs',
rust_crate_type : 'proc-macro',
native: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would I enable this test on the CI for actually doing cross-compilation? I see that there are Linux/armhf and mingw64 cross tests in the CI. Should I add the corresponding rust toolchains there? How would I then enable this test to actually run?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See e.g. cross/linux-mingw-w64-64bit.txt

You just need to set up the rust compiler as a cross binary, and configure the corresponding .json file to change e.g. "tests": ["common", "cmake"], to specify which run_project_tests.py suites are now supported by that cross test configuration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should add native: true here, the whole point of this PR is to test it's the default.

Giving it a try at cross rust compilation in CI there: #11990.

@sdroege sdroege force-pushed the rust-proc-macro-native branch from 105b7fd to 9d61c0f Compare April 27, 2023 12:05
@jpakkane
Copy link
Member

Is there ever a case where you'd want to compile proc-macro crates with a cross compiler? If no, could we not make it default to native: true instead of requiring people to write it out by hand every time?

@sdroege
Copy link
Contributor Author

sdroege commented May 2, 2023

Is there ever a case where you'd want to compile proc-macro crates with a cross compiler? If no, could we not make it default to native: true instead of requiring people to write it out by hand every time?

That would also work, I guess.

The only case I could think of is when someone wants to compile the proc-macro on some build machine, and then compile something with that proc-macro on the target machine. Not sure if that's something worth worrying about?

@eli-schwartz
Copy link
Member

You'd have to install one to do that. Is this expected to work?

@sdroege
Copy link
Contributor Author

sdroege commented May 2, 2023

You'd have to install it or copy it around somehow manually, yes. I wouldn't expect that to work but with enough motivation and carefully set up environments you can probably make it work. It's something I wouldn't want to support though.

@sdroege
Copy link
Contributor Author

sdroege commented May 3, 2023

So I guess the summary here would be to a) default to native: true, b) warn if native: false if not a crossbuild / error if crossbuild, c) warn if install: true that this is unsupported. I'll change it accordingly later.

For using a proc-macro built "elsewhere" (c) you need to ensure that exactly the same toolchain version is used and then it can theoretically work but I don't think this is explicitly supported by rustc either. If it's literally the same toolchain then there's no reason why it shouldn't work (you'd somehow need to tell the compiler where to find it though), if you build on a cross toolchain and then use it on the target with the same toolchain version it may or may not work.

@sdroege sdroege force-pushed the rust-proc-macro-native branch from 9d61c0f to ef0c71d Compare May 3, 2023 12:11
…ng into targets for other platforms

proc-macros are basically compiler extensions and must be compiled for
the build machine so that the compiler can load and execute it at
runtime.

Without this, cross-compilation of targets that use proc-macro
dependencies is going to fail.

Fixes mesonbuild#11702
@sdroege sdroege force-pushed the rust-proc-macro-native branch from ef0c71d to 7e7749d Compare May 3, 2023 12:22
@eli-schwartz
Copy link
Member

Ping. What's the status of wiring up tests?

Copy link
Member

@dcbaker dcbaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a code point of view this looks fine to me, I still wonder long-term if we want to deprecate the proc-macro crate type and just add a rust_module.proc_macro() helper to avoid this. I think this is a net improvement over what we have, so I'm happy

@dcbaker
Copy link
Member

dcbaker commented Jun 27, 2023

I'm also in favor of landing this after the rc if necessary. From my point of view this is a bug fix, since Meson allows something that cannot work in practice

@dcbaker dcbaker added this to the 1.2.0 milestone Jun 27, 2023
@eli-schwartz
Copy link
Member

Agreed -- once it is tested in CI I'm happy with merging it even past the rc freeze.

@sdroege
Copy link
Contributor Author

sdroege commented Jun 27, 2023

What's the status of wiring up tests?

Doing tests looks like an adventure that will take me a couple of hours once I figured out how the CI works exactly and waited for a few dozen failed runs in the meantime, so I didn't get to that yet and it will probably take a while. I'd like to have this merged but I also think that having tests on the CI for this is important because otherwise it will just stop working again sooner or later :)

If someone wants to take this over please go ahead, otherwise I'll get to it once I have a bigger slot of time available.

@tristan957 tristan957 modified the milestones: 1.2.0, 1.3.0, 1.1.2 Jul 13, 2023
@@ -1408,7 +1408,7 @@ def link(self, target):
msg = f"Can't link non-PIC static library {t.name!r} into shared library {self.name!r}. "
msg += "Use the 'pic' option to static_library to build with PIC."
raise InvalidArguments(msg)
if self.for_machine is not t.for_machine:
if self.for_machine is not t.for_machine and (not t.uses_rust() or t.rust_crate_type != 'proc-macro'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think t can be a CustomTarget which does not implement uses_rust(). What about:

Suggested change
if self.for_machine is not t.for_machine and (not t.uses_rust() or t.rust_crate_type != 'proc-macro'):
if self.for_machine is not t.for_machine and (not isinstance(t, SharedLibrary) or t.rust_crate_type != 'proc-macro'):

@@ -2328,6 +2328,13 @@ def process_kwargs(self, kwargs):
else:
raise InvalidArguments(f'Invalid rust_crate_type "{rust_crate_type}": must be a string.')
if rust_crate_type == 'proc-macro':
if 'native' not in kwargs:
kwargs['native'] = True
if not kwargs.get('native', False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You set it to true above if it's missing, so the False cannot be used.

Suggested change
if not kwargs.get('native', False):
if not kwargs['native']:

Comment on lines +2334 to +2337
if self.environment.is_cross_build():
raise InvalidArguments('Rust "proc-macro" crate type requires "native: true". This will fail in a cross-build.')
else:
mlog.warning('Rust "proc-macro" crate type requires "native: true". This will fail in a cross-build.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not require "native: true", that's the default in this case. I think it should always be an hard error, no need to downgrade to a warning if it's not a cross build. To happen, user must have explicitely wrote:

shared_library(..., rust_crate_type: 'proc-macros', native: false)

which is always wrong.

What about:

Suggested change
if self.environment.is_cross_build():
raise InvalidArguments('Rust "proc-macro" crate type requires "native: true". This will fail in a cross-build.')
else:
mlog.warning('Rust "proc-macro" crate type requires "native: true". This will fail in a cross-build.')
raise InvalidArguments('Rust "proc-macro" crate type does not allow "native: false".')

@jpakkane jpakkane modified the milestones: 1.2.0, 1.3.0 Jul 16, 2023
xclaesse pushed a commit to xclaesse/meson that referenced this pull request Jul 21, 2023
rust: Require `native: true` for `proc-macro` targets and allow linking into targets for other platforms

proc-macros are basically compiler extensions and must be compiled for
the build machine so that the compiler can load and execute it at
runtime.

Without this, cross-compilation of targets that use proc-macro
dependencies is going to fail.

Fixes mesonbuild#11702
xclaesse pushed a commit to xclaesse/meson that referenced this pull request Jul 21, 2023
rust: Require `native: true` for `proc-macro` targets and allow linking into targets for other platforms

proc-macros are basically compiler extensions and must be compiled for
the build machine so that the compiler can load and execute it at
runtime.

Without this, cross-compilation of targets that use proc-macro
dependencies is going to fail.

Fixes mesonbuild#11702
@heftig
Copy link
Contributor

heftig commented Jul 30, 2023

I'm encountering a bit more trouble cross-compiling Mesa for i686; the rusticl_proc-macros shared lib is used to build the rusticl static lib, which is then link_wholed into the RusticlOpenCL shared lib.

Meson adds the rusticl_proc-macros shared lib to the link args of the RusticlOpenCL shared lib, which doesn't do anything in a native build but fails to link in a cross build.

@xclaesse
Copy link
Member

@heftig Can you please open a separate issue? A minimal test case would be nice too because I failed to reproduce.

@xclaesse
Copy link
Member

Closing this PR because it is included into #11714 which does a bigger refactoring of proc-macro.

@xclaesse xclaesse closed this Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rust: Uses wrong target architecture for proc-macro targets when cross-compiling
7 participants