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

Ninja not executing archive command despite its presence in build.ninja file #2553

Open
reshmavk opened this issue Jan 15, 2025 · 14 comments
Open

Comments

@reshmavk
Copy link

We are trying to build glib2 with the latest ninja 1.12.1.
In AIX, we archive shared libraries. The rule for the same is written in build.ninja as follows:
rule AIX_LINKER
command = ar -q -v $out $in && rm -f $in
description = Archiving AIX shared library

and the command to build the archive is as follows.
build glib/libglib-2.0.a: AIX_LINKER glib/libglib-2.0.so.0

This command is not being executed.
In the build all: section of the build.ninja file, we do have the "glib/libglib-2.0.a" target.
Ninja was working fine till 1.11.1 in AIX. Please let me know what could be the reason for this.

@digit-google
Copy link
Contributor

Can you be more specific about what's going on here, what I mean is:

  • When you say the command is not being executed, is during a clean build or an incremental one? Under any other specific conditions?

  • Your command is removing the input on completion of the ar tool. This is suspicious as it means that Ninja incremental builds will always try to rebuild the .so, then the archive after that. Are you sure this is something you really need? This also looks the opposite of what you are describing here, so this is rather puzzling.

  • What is the output of ninja -t commands glib/libglib-2.0.a, which should print the command. It should end with the ar ... command line.

  • Does glib/libglib-2.0.a appears in the output of ninja -t inputs all at all? If not your build plan is probably invalid.

A minimal build.ninja that reproduces the issue would be helpful here.

@reshmavk
Copy link
Author

It is a clean build and it creates glib/libglib-2.0.so.0 file but not glib/libglib-2.0.a.

"ninja -t commands glib/libglib-2.0.a" command ends with the ar command as follows:
ar -q -v glib/libglib-2.0.a glib/libglib-2.0.so.0 && rm -f glib/libglib-2.0.so.0
However it doesn't execute this ar command.

The output of "ninja -t inputs all" doesn't include glib/libglib-2.0.a. This is the same even in the working case.

@reshmavk
Copy link
Author

I just wanted to understand more. Can you tell why "ninja -t inputs all" should have "glib/libglib-2.0.a" in the output?
Should this come from meson or ninja?

@digit-google
Copy link
Contributor

digit-google commented Jan 16, 2025

ninja -t inputs <target> prints all transitive inputs for a given <target> by parsing the build graph.
Note: this ignores validation targets.

If ninja -t inputs all does not list the archive target, it is not a transitive dependency, then ninja all will not rebuild it.

Are you sure the archive is listed in your build all: ... statement, and is not a validation target?

@reshmavk
Copy link
Author

Yes, the archive is listed in "build all:" and is not a validation target. Even in a clean build,it doesn't create the archive.

How can we make sure ninja -t inputs all lists the archive target? Is it required to write something in the build.ninja file?

@digit-google
Copy link
Contributor

Then this looks like a bug in the ninja -t inputs logic then (which did change in 1.12), but also the rest of the logic used for regular builds (which is even more puzzling).

A reproduction case is needed to inspect what's going on here. Can you share your Ninja build plan somewhere? We don't need build artifacts or source files, just the .ninja files.

@reshmavk
Copy link
Author

build.ninja.txt

@reshmavk
Copy link
Author

Please ignore the echo commands in rules c_LINKER and AIX_LINKER. I added those for debugging.

@digit-google
Copy link
Contributor

A small update on this issue.

I have rebuilt Ninja 1.11.1, 1.12.1 and tip-of-tree to compare results.

It appears that the logic for ninja -t inputs was broken in 1.12 and before (this was fixed in PR##2485).
This explains why the archive doesn't appear for -t inputs with ninja-1.11 and ninja-1.12, but does with ninja-tot.

Unfortunately, this is not enough to understand why the issue exists. I couldn´t find any other difference when using other tools (i.e. without building anything) with the build plan you provided.

For example, all three versions, the command appears properly with -t commands though.

Can I ask you to try a build with a Ninja binary built from the current tip-of-tree to see if the issue still persists?

Also, the full output of ninja -d explain all for a clean build would be useful to determine what is happening here.

Note that the -d explain has changed too. In 1.12 and before, all explanations were dumped before build actions. After PR#2067, the explanations are now dumped before each action they relate to, which makes the output much more readable.

@reshmavk
Copy link
Author

reshmavk commented Jan 24, 2025

Thanks for the update.

I tried with the master branch, unfortunately the issue still exists.
Attaching the output of ninja -d explain all for a clean build

ninja_d_explain_all_output.txt

@reshmavk
Copy link
Author

We tried with a simple example where ninja executed the archive command but not in this case.

@digit-google
Copy link
Contributor

Thanks for the -d explain output. I think I understand what's going on (short version: build plan has incorrect dependencies, Meson is likely broken).

In the log you shared, the first command to fail is trying to link gobject/libgobject-2.0.so.0 (look for FAILED:), and the error from the linker says: gcc: error: glib/libglib-2.0.a: No such file or directory

Inspection of the build plan shows that the corresponding build rules does not list libglib-2.0.a as an input, though it does list it in the LINK_ARGS associated variable that is passed to the command. In other words, it looks like this:

build gobject/libgobject-2.0.so.0: c_LINKER ..... glib/libglib-2.0.so.0.p/libglib-2.0.so.0.symbols
    LINK_ARGS = .... glib/libglib-2.0.a  ...

And the build command for libglib-2.0.so.0.symbols only depends on the shared library, not the archive:

build glib/libglib-2.0.so.0.p/libglib-2.0.so.0.symbols: SHSYM glib/libglib-2.0.so.0
 IMPLIB = glib/libglib-2.0.a

As such, there is nothing that tells Ninja that these targets require glib/libglib-2.0.a to be built first, and Ninja starts to build the gobject library before the archive is available, hence the failure.

Note that how Ninja determines the order of unrelated parallel commands has changed after 1.11.1 (probably through PR#2177, to optimize it for common cases).

I assume that before that, your builds were working by mere chance, i.e. because Ninja happened to select a dispatch order that didn´t trigger the invalid dependencies in your build plan.

In other words, the generator has created a Ninja build plan with missing / invalid dependencies.
I suggest contacting the Meson mailing list / issue tracker about this.

Hope this helps.

@eli-schwartz
Copy link

This seems related to mesonbuild/meson#11850, @KamathForAIX may know more. We (meson) currently rely on external contributions for AIX.

Please do open that Meson bug report.

@KamathForAIX
Copy link

Thank you, @eli-schwartz, for tagging me. I have reproduced this issue in my environment.

Your analysis is spot on @digit-google. Thank you very much. Yes,

build glib/libglib-2.0.so.0.p/libglib-2.0.so.0.symbols: SHSYM glib/libglib-2.0.so.0
 IMPLIB = glib/libglib-2.0.a

This here is a problem. This indeed made Ninja feel the archive was dummy and had nothing to do apart from being just an archive. In AIX, we archive shared libraries.

I need to get glib/libglib-2.0.a in the SHSYM to tell Ninja we need the symbols from the archived shared library and not from the shared object. And then ninja input -t all started having the archives as well.

I have fixed the issue by making changes here.

Please find the log of a successful compile and install of glib2 below this message with any version of Ninja >= 1.12 or the master after the fix.

I will work with @eli-schwartz to raise a PR and fix this in the meson page.

We can close this issue here.

Have a nice day ahead.

bin/msgfmt -o po/ta/LC_MESSAGES/glib20.mo ../po/ta.po
[1463/1477] /opt/freeware/bin/msgfmt -o po/te/LC_MESSAGES/glib20.mo ../po/te.po
[1464/1477] /opt/freeware/bin/msgfmt -o po/tg/LC_MESSAGES/glib20.mo ../po/tg.po
[1465/1477] /opt/freeware/bin/msgfmt -o po/th/LC_MESSAGES/glib20.mo ../po/th.po
[1466/1477] /opt/freeware/bin/msgfmt -o po/tl/LC_MESSAGES/glib20.mo ../po/tl.po
[1467/1477] /opt/freeware/bin/msgfmt -o po/tr/LC_MESSAGES/glib20.mo ../po/tr.po
[1468/1477] /opt/freeware/bin/msgfmt -o po/ug/LC_MESSAGES/glib20.mo ../po/ug.po
[1469/1477] /opt/freeware/bin/msgfmt -o po/tt/LC_MESSAGES/glib20.mo ../po/tt.po
[1470/1477] /opt/freeware/bin/msgfmt -o po/uk/LC_MESSAGES/glib20.mo ../po/uk.po
[1471/1477] /opt/freeware/bin/msgfmt -o po/vi/LC_MESSAGES/glib20.mo ../po/vi.po
[1472/1477] /opt/freeware/bin/msgfmt -o po/wa/LC_MESSAGES/glib20.mo ../po/wa.po
[1473/1477] /opt/freeware/bin/msgfmt -o po/xh/LC_MESSAGES/glib20.mo ../po/xh.po
[1474/1477] /opt/freeware/bin/msgfmt -o po/yi/LC_MESSAGES/glib20.mo ../po/yi.po
[1475/1477] /opt/freeware/bin/msgfmt -o po/zh_CN/LC_MESSAGES/glib20.mo ../po/zh_CN.po
[1476/1477] /opt/freeware/bin/msgfmt -o po/zh_HK/LC_MESSAGES/glib20.mo ../po/zh_HK.po
[1477/1477] /opt/freeware/bin/msgfmt -o po/zh_TW/LC_MESSAGES/glib20.mo ../po/zh_TW.po
Installing /glib/gio/gschema.dtd to /glib/install_dir/opt/freeware/share/glib-2.0/schemas
Installing /glib/gio/gschema.loc to /glib/install_dir/opt/freeware/share/gettext/its
Installing /glib/gio/gschema.its to /glib/install_dir/opt/freeware/share/gettext/its
Installing /glib/aix/meson-private/girepository-2.0.pc to /glib/install_dir/opt/freeware/lib64/pkgconfig
Installing /glib/po/Makefile.in.in to /glib/install_dir/opt/freeware/share/glib-2.0/gettext/po
Installing /glib/m4macros/glib-2.0.m4 to /glib/install_dir/opt/freeware/share/aclocal
Installing /glib/m4macros/glib-gettext.m4 to /glib/install_dir/opt/freeware/share/aclocal
Installing /glib/m4macros/gsettings.m4 to /glib/install_dir/opt/freeware/share/aclocal
Installing symlink pointing to libglib-2.0.so.0.8302.0 to /glib/install_dir/opt/freeware/lib64/libglib-2.0.so.0
Symlink creation does not work on this platform. Skipping all symlinking.

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

No branches or pull requests

4 participants