AdaCore / gprbuild

GPRbuild is an advanced build system designed to help automate the construction of multi-language systems.
Other
65 stars 21 forks source link

Trouble building (on nix) #83

Closed Ptival closed 3 years ago

Ptival commented 3 years ago

Hello,

I am currently trying to build gprbuild on nix ( https://nixos.org/ ) and am encountering difficulties that are somewhat hard to solve with my lack of knowledge of Ada and GPR.

What I have successfully done so far:

I am now trying to build the bootstrapped gprbuild using those two. In my first attempt doing so, I get the following error:

gprbuild -p -m   -j0 -XBUILD=production  gprbuild.gpr -XLIBRARY_TYPE=static -XXMLADA_BUILD=static
gprbuild.gpr:19:06: imported project file "xmlada.gpr" not found

So it seems the build system is not aware of where the xmlada source lives. On this GitHub's issues, I found mentions of options to help gprbuild find projects, such as GPR_PROJECT_PATH, so I try to set it to point to some (read-only) checkout of xmlada, and now I get the following message:

gprbuild -p -m   -j0 -XBUILD=production  gprbuild.gpr -XLIBRARY_TYPE=static -XXMLADA_BUILD=static
gprbuild.gpr:22:18: cannot import aggregate project "/nix/store/lfrhvyb51w2h8xrfy6i2pj7zmqpc67pn-xmlada-source/xmlada.gpr"
xmlada.gpr:24:06: imported project file "xmlada_shared" not found
xmlada.gpr:24:06: imported by "/nix/store/lfrhvyb51w2h8xrfy6i2pj7zmqpc67pn-xmlada-source/xmlada.gpr"
xmlada.gpr:24:06: imported by "/build/source/gprbuild.gpr"
gpr.gpr:21:21: cannot import aggregate project "/nix/store/lfrhvyb51w2h8xrfy6i2pj7zmqpc67pn-xmlada-source/xmlada.gpr"
gprbuild: "gprbuild.gpr" processing failed

Now this error message is quite opaque to me, so any help understanding what is wrong would be appreciated!

If it helps, the /nix/store/lfrhvyb51w2h8xrfy6i2pj7zmqpc67pn-xmlada-source/xmlada.gpr file exists, but due to nix's nature, it exists in a read-only file system (is this a problem?).


NOTE: the imported project file "xmlada_shared" not found made me think that the problem could be I was pointing at the xmlada source before configure is run, and so xmlada_shared.gpr did not exist.

I have made a change to point GPR_PROJECT_PATH to a xmlada source after configure is run, where xmlada_shared.gpr exists. Now only the following errors remain:

gprbuild -p -m   -j0 -XBUILD=production  gprbuild.gpr -XLIBRARY_TYPE=static -XXMLADA_BUILD=static
gprbuild.gpr:22:18: cannot import aggregate project "/nix/store/ccv0ah8fbc11czlmbcbmldmz2yxz7lgp-xmlada-source-configured/xmlada.gpr"
gpr.gpr:21:21: cannot import aggregate project "/nix/store/ccv0ah8fbc11czlmbcbmldmz2yxz7lgp-xmlada-source-configured/xmlada.gpr"
gprbuild: "gprbuild.gpr" processing failed
t-14 commented 3 years ago

You need to not just build but also install xmlada. The dependency of gprbuild is not on xmlada's source but on the deployed library (which will contain an auto-generated xmlada.gpr which is not the same project as the one in the source area).

fluffynukeit commented 3 years ago

@Ptival I am also working on creating a nix install, specifically this WIP flake: https://github.com/fluffynukeit/adaspark

I likewise could only build+install xmlada using the static and static-pic modes, not relocatable mode. (I learned --disable-shared disables relocatable and static-pic, so it's overkill). My problem was that I could not build xmlada due to linker errors not being able to find crti.o (reddit post where I asked for help a couple days ago: https://www.reddit.com/r/NixOS/comments/jwwoqv/invitation_to_fix_and_critique_my_flake_for_ada/). Building xmlada with only static and static-pic allowed me to overcome the crti.o errors, and eventually I built xmlada only to run into the same issues and solutions you have.

My problem is that, eventually, I always run into crti.o linker error, so I think I need to resolve that at the fundamental level instead of working around it. Is this the problem you encountered and were you able to solve it?

Ptival commented 3 years ago

Hi @fluffynukeit ,

I have indeed managed to get through the crti.o linker error, and build and run gprbuild successfully on nix.

All of my derivations are here if you need a peek: https://github.com/ge-high-assurance/RACK/tree/vr/ada/ada/nix

In particular, the thing I found that helps with the linker error is to add:

    export LIBRARY_PATH="${glibc}/lib"

in the configure phase, as done here:

https://github.com/ge-high-assurance/RACK/blob/15dae70f7e114bf040eddf9ccdbc798905d18711/ada/nix/gprbuild/default.nix#L15

Feel free to reach out if you have more questions!

fluffynukeit commented 3 years ago

@Ptival Thanks so much for the tips. I got it all built at least now! Your repo is a treasure trove of nix/ada integration guidance, so I bet it will continue to be a good resource. One question I have along the topic of nix/ada integration is how well do ada libraries integrate into the nix environment? The manual page 24 outlines the search path for gprbuild, so the buildInputs of a gprbuild-based derivation would need to be traversed for other gprbuild projects, then collect all their */share/gpr paths in the nix store, and set GPR_PROJECT_PATH so they are all visible to gprbuild. Do you have any experience along those lines? I wonder if it's worth a custom mkDerivation function to set all that up. TYVM.

Fabien-Chouteau commented 3 years ago

@Ptival, @fluffynukeit, are you planning to add gprbuild and other Ada libraries in mainstream NIX? I'd be glad to help if I can.

fluffynukeit commented 3 years ago

@Fabien-Chouteau I'm using a yet-to-be-released new feature of nix called flakes that is meant to be a solution to several issues related with nix, one of which is the nixpkgs "monorepo." Flakes allow composing different git repos together easily instead of dumping every derivation into nixpkgs as has been the modus operandi for a long time. So, under the upcoming flakes model, I'm not sure whether nixpkgs will continue in its current giant form or whether it will be broken up into smaller flakes, each with a different role. I mention this because the concept of "mainstream nix" might be changing very soon. For instance, AdaCore could even convert each of their github repos to be flakes by adding the right flake.nix files to each repo, and they'd work with the entire nix ecosystem without ever being added to nixpkgs repo. In some sense, that's what my flake is doing except that all the recipes are in one repo instead of each being included in its respective AdaCore repo.

My goal in developing my flake is two fold: 1) learn modern nix after trying it off and on for many years and it never "sticking" to my dev workflows due to the aforementioned issues flakes are supposed to address, and 2) to create a means to "push one button" and automatically build the entire toolchain needed for spark and ada development without the license restrictions. I'm completely new to ada+spark and want to learn, but navigating the whole license question between compilers, runtimes, spark, etc. was a real headache that I just want to avoid by using a fsf-based toolchain that includes everything needed.

Regarding 2), I do intend for my flake to be accessible for anyone to use, but I do not currently plan to put it into nixpkgs because the flake mechanism eliminates the need to. I'm thinking that if you and AdaCore are open to nix-fying your software for easier use, it makes sense for the flakes to be in your repo and under your version control instead of third parties like myself, or this one, or @Ptival repo, or other build repos like @Lucretia free ada.

I'm not a nix or flake expert by any means, but I've managed to get a lot of the spark dependencies flake-ified (with many tips from @Ptival repo code). You can check it out if you want. Right now I'm trying to build the spark2014 repo but running into errors like the one below when building. If you have tips or can provide insight into how AdaCore might want to leverage nix, I think there is certainly some interest in a joint effort.

   [Ada]          exp_tss.adb
spark_definition.adb:1496:15: "N_Iterated_Element_Association" is undefined
spark_definition.adb:2545:28: "Is_Attribute_Loop_Entry" is undefined
spark_definition.adb:2868:15: "Attribute_Initialized" is undefined
spark_definition.adb:2976:43: "Aspect_Relaxed_Initialization" is undefined
spark_definition.adb:3210:15: "Is_Effectively_Volatile_Object_For_Reading" is undefined
spark_definition.adb:3221:24: "Is_Effectively_Volatile_For_Reading" is undefined (more references follow)
spark_definition.adb:4130:21: "Has_Relaxed_Initialization" is undefined (more references follow)
spark_definition.adb:4347:36: "Pragma_Subprogram_Variant" is undefined (more references follow)
spark_definition.adb:5587:21: "Access_Subprogram_Wrapper" is not visible
spark_definition.adb:5587:21: non-visible declaration at spark_atree-entities.ads:526
spark_definition.adb:6282:07: missing case value: "E_Protected_Object"
spark_definition.adb:6717:24: "Set_Overflow_Mode" not declared in "Sem_Prag"
spark_definition.adb:7218:10: "S_Long_Long_Long_Integer" is undefined
spark_atree-entities.ads:527:11: "Access_Subprogram_Wrapper" not declared in "Einfo"
spark_atree-entities.ads:527:11: "Access_Subprogram_Wrapper" not declared in "Einfo"

Edit: I suspect that the problem is at least partially due to setting prefix in gnat2why's makefile because I'm seeing it get set as NOPREFIX.

steve-cs commented 3 years ago

@fluffynukeit, some of that looks like a compiler spark2014 mismatch. spark2014 fsf branch is a development branch and currently requires a recent GCC 11 compiler to build cleanly. If you are sticking with gcc 10.2 (binaries and source) then you'll likely have an easier time with the slightly older spark2014 version 20 branches such as 20.2.

fluffynukeit commented 3 years ago

@steve-cs Thanks for the tip. I'll try it out. I admit I've been pretty lax about the source matching, I suppose naively hoping to get lucky. Will I need to change the versions of the dependencies to 20.2 as well or is 21.0.0 ok?

Edit: 20.2 built with a few tweaks. TYVM!

steve-cs commented 3 years ago

I'd recommend starting with AdaCore 20.2 branches across the board unless you've got a reason otherwise.

Mixing major versions can lead to issues. Interfaces between repos can and will vary and are not backwards compatible. Things are simpler if you pick a consistent base version for all repos and backport fixes from more recent versions or development branches. Matching gcc source and spark2014 versions is sensitive, as is matching versions between gps, libadalang, and langkit.

Fabien-Chouteau commented 3 years ago

Thank you for all the detailed explanation @fluffynukeit. It's very unlikely that we add nix support directly in our projects, but we will try to be helpful in your quest :)