AdaCore / libadalang

Ada semantic analysis library.
https://www.adacore.com
Other
147 stars 42 forks source link

How to use LAL Python when installed via Alire? #961

Closed Heziode closed 1 year ago

Heziode commented 1 year ago

The title speaks for itself, how can I use LAL in Python?

I does the following things:

alr get libadalang
cd libadalang
alr build

Now, I triying to follow this tutorial on the official user doc, but I don't know where to start.

LAL is not reconnized:

> python lal_playground 
Traceback (most recent call last):
  File "lal_playground", line 18, in <module>
    import libadalang
ModuleNotFoundError: No module named 'libadalang'

I can't find anything in the doc to make it work…

I am working on an ubuntu Docker (VSCode), so I the dev environment are on Linux (the host is MacOS).


Furthere more, from the doc (building):

  1. Building Libadalang First, note that if you have access to a pre-built Libadalang package, bundled with GNAT Pro if you have a GNAT Pro subscription (for community users, we have a Libadalang crate on Alire), then you do not need to go through the following steps: just follow the instructions in the README file that comes with this pre-built package.

There is no README ship with Alire…

thvnx commented 1 year ago

Hi,

You don't have to build anything (IIUC), I think you forgot to source the environment. I tried this on my side and it works:

$ alr get libadalang
$ cd libadalang_XXX
$ eval `alr printenv`
$ ./scripts/lal_playground test.adb
--
-- libadalang playground
--

The file(s) passed as argument have been put into the u variable, or units if
there are multiple.

Enjoy!

In [1]: 

You can also use alr exec -- cmd instead of the printenv command (it execute the command cmd in the local Alire environement):

$ alr exec -- ./scripts/lal_playground test.adb
--
-- libadalang playground
--

The file(s) passed as argument have been put into the u variable, or units if
there are multiple.

Enjoy!
thvnx commented 1 year ago

Hi @Heziode , I assume your problem is solved so I'm closing the issue. Feel free to reopen if you need more help with this.

grochoge commented 10 months ago

I'm running into a similar issue. It seems alr build is only building libadalang.a. I don't see any .pyd files and there's nothing to install IPython so I just get "ModuleNotFoundError: No module named 'IPython'" when trying to run alr exec -- python .\scripts\lal_playground

thvnx commented 10 months ago

Hi @grochoge , looks like my previous comment was not completely true. Can you try the following commands:

$ alr get libadalang
$ cd libadalang_XXX
# Build the relocatable (.so) version of libadalang
$ LIBRARY_TYPE=relocatable alr build
# Install the libadalang python package
$ cd python
$ pip install .
$ cd -
# Set env
$ eval `alr printenv`
$ export LD_LIBRARY_PATH=$PWD/lib/relocatable/dev/ 
# Run lal_playground
$ ./scripts/lal_playground test.adb

I'm not an Alire expert so there is maybe a better way to setup the build process and environment. I'll try to find it out, or to fix the Alire crate so that the python package is easier to use.

If you get the ModuleNotFoundError: No module named 'IPython' error, install it with pip install ipython

NathanielPoteat commented 3 months ago

I was running into a similar issue trying to use the Python API from the libadalang alire crate. First, is it possible that these instructions can be put somewhere more visible so other people don't have to dig to figure this out? Second, now that I have built the Python API I am running into a new issue:

OSError: dlopen(libadalang.dylib, 0x0006): tried: 'libadalang.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibadalang.dylib' (no such file), '/opt/homebrew/lib/libadalang.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/lib/libadalang.dylib' (no such file), '/usr/lib/libadalang.dylib' (no such file, not in dyld cache), 'libadalang.dylib' (no such file)

I am running this on an M2 MacBook Pro, but I have also had issues getting past this point on an x64 AMD Linux machine as well:

Traceback (most recent call last):
  File "/home/*********/repos/libadalang/scripts/lal_playground", line 15, in <module>
    import libadalang
  File "/home/*********/repos/libadalang/venv/lib/python3.9/site-packages/libadalang/__init__.py", line 84, in <module>
    _c_lib = ctypes.cdll.LoadLibrary(_c_lib_path)
  File "/usr/lib/python3.9/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python3.9/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libadalang.so: cannot open shared object file: No such file or directory

Have I missed any steps when building the libadalang alr crate that would not create the libadalang object file? I ran a find on my machine, but was unable to find it.

thvnx commented 2 months ago

Hi @NathanielPoteat , did you correctly set the relocatable build type when building the crate?

When running LIBRARY_TYPE=relocatable alr build you should find libadalang.so under lib/relocatable/dev/.

NathanielPoteat commented 2 months ago

Thank you, @thvnx. After running LIBRARY_TYPE=relocatable alr build I was able to find libadalang.so under lib/relocatable/dev on my Linux machine. However, now I'm running into another error with a libgpr2.so. Do I have to follow the same steps for libgpr2?

  File "/home/npoteat3-temp/repos/libadalang/scripts/lal_playground", line 15, in <module>
    import libadalang
ImportError: libgpr2.so: cannot open shared object file: No such file or directory

I would also like to note that the libadalang.dylib file was not created on my Mac M2 machine following the same instructions.

thvnx commented 2 months ago

Strange! Did you follow the steps I mentioned here? Especially the pip install . command (it should install all you need to run the lal_playground). I've just checked on a linux machine and it works.

For the M2 machine you should try the same list of commands (replacing LD_LIBRARY_PATH by DYLD_LIBRARY_PATH). But I'm not sure that Alire and our tools support this architecture right now.

NathanielPoteat commented 2 months ago

Yes, I went back through and did all of the steps listed above again. It might be related to this error:

Building wheels for collected packages: Libadalang
  Building wheel for Libadalang (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/npoteat3-temp/repos/libadalang/venv/bin/python3.9 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-cnit3ygr/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-cnit3ygr/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-aml0d9mi
       cwd: /tmp/pip-req-build-cnit3ygr/
  Complete output (6 lines):
  usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
     or: setup.py --help [cmd1 cmd2 ...]
     or: setup.py --help-commands
     or: setup.py cmd --help

  error: invalid command 'bdist_wheel'
  ----------------------------------------
  ERROR: Failed building wheel for Libadalang
  Running setup.py clean for Libadalang
Failed to build Libadalang
Installing collected packages: Libadalang
  Attempting uninstall: Libadalang
    Found existing installation: Libadalang 0.1
    Uninstalling Libadalang-0.1:
      Successfully uninstalled Libadalang-0.1
    Running setup.py install for Libadalang ... done
Successfully installed Libadalang-0.1

Which I don't remember seeing the first time I did pip install . in the python directory.

thvnx commented 2 months ago

Looks like there is something wrong with your Python environment. Do you have the wheel package installed?

NathanielPoteat commented 2 months ago

It turns out that I did not have the wheel package installed on my Linux machine. Installing that solved the error when running pip install ., but I still run into the ImportError: libgpr2.so: cannot open shared object file: No such file or directory error when trying to run lal_playground. Should the LIBRARY_TYPE=relocatable alr build also ensure all dependency libraries are relocatable as well?

thvnx commented 2 months ago

Should the LIBRARY_TYPE=relocatable alr build also ensure all dependency libraries are relocatable as well?

I think so!

What gives ldd on libadalang.so ? On my side it gives this for libgpr2.so:

libgpr2.so => /tmp/libadalang_24.0.0_a1358075/lib/relocatable/dev/../../..//alire/cache/dependencies/libgpr2_24.0.0_eda3c693/.build/release/lib-relocatable/libgpr2.so (0x00007de206a00000)

libgpr2 has been built by alr during the libadalang build. Try to clean your alr cache maybe?

NathanielPoteat commented 2 months ago

When I run ldd libadalang.so, I see

libgpr2.so => /home/npoteat3-temp/repos/libadalang/lib/relocatable/dev/./../../../../..//.local/share/alire/builds/libgpr2_24.0.0_eda3c693/ee49417aad43e0ae9e1023ffb3696aa8fb6611fed1f20124c2ee879ea9ef9f99/.build/release/lib-relocatable/libgpr2.so (0x00007fe75fc40000).

However, I still get the same error (ImportError: libgpr2.so: cannot open shared object file: No such file or directory) unless I copy the .so file to the same directory as the file I'm trying to use. After copying said libgpr2.so file, I then run into the same issue but for another .so file:

Traceback (most recent call last): File "/home/npoteat3-temp/repos/libadalang/scripts/lal_playground", line 15, in <module> import libadalang ImportError: liblangkit_support.so: cannot open shared object file: No such file or directory.

I can solve this by manually copying all the .so files into the same directory as lal_playground, but I don't believe this is the best solution once I start trying to work on my own project.

NathanielPoteat commented 2 months ago

Even after copying all .so files into the same directory, I get another error:

  File "/home/npoteat3-temp/repos/libadalang/scripts/lal_playground", line 15, in <module>
    import libadalang
ImportError: dynamic module does not define module export function (PyInit_libadalang)
thvnx commented 2 months ago

There is something wrong with your environment if you have to copy the *.sos. That's probably an issue on the Alire side at this point. You should check that alr printenv correctly prints the paths to the Alire local share builds and that the command is correctly evaluated.

NathanielPoteat commented 2 months ago

Executing alr printenv prints all the .so file locations as expected, but it still throws the same errors when I delete them from the directory on my Linux machine.

On my M2 Mac machine, alr printenv also prints everything as expected, but it appears that alr doesn't pass the environment variables appropriately when importing libadalang.

printenv ''' export ADASAT_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/adasat_24.0.0_46db8c9a/af518c49e0f8ebbc8a657b8f4eb3f44198fbd2b5e7f8d856cae31fdfd00703bb" export ALIRE="True" export CPLUS_INCLUDE_PATH="/opt/homebrew/include" export C_INCLUDE_PATH="/opt/homebrew/include" export GNATCOLL_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/gnatcoll_24.0.0_11c512d1/3794c9da006282ff4d0063cd2e95ff2123faea51ed24f3ed8fc9cfc9c1e628d7" export GNATCOLL_BUILD_MODE="PROD" export GNATCOLL_GMP_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/gnatcoll_gmp_24.0.0_e90c5b4d/54ab17d0cfed9b7e20ade9acf9150596adc363c7d21d612402220d75a64d503f" export GNATCOLL_ICONV_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/gnatcoll_iconv_24.0.0_e90c5b4d/feac2fd1f2043590964c6fec89adbc484b407d822ddc06122f8af5d61983c2d2" export GNATCOLL_OS="osx" export GNATCOLL_VERSION="24.0.0" export GNAT_NATIVE_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/toolchains/gnat_native_14.1.3_ece13bc5" export GPR2_BUILD="release" export GPRBUILD_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/toolchains/gprbuild_22.0.1_b1220e2b" export GPR_PROJECT_PATH="/Users/npoteat3/.local/share/alire/builds/adasat_24.0.0_46db8c9a/af518c49e0f8ebbc8a657b8f4eb3f44198fbd2b5e7f8d856cae31fdfd00703bb:/Users/npoteat3/.local/share/alire/builds/gnatcoll_24.0.0_11c512d1/3794c9da006282ff4d0063cd2e95ff2123faea51ed24f3ed8fc9cfc9c1e628d7:/Users/npoteat3/.local/share/alire/builds/gnatcoll_gmp_24.0.0_e90c5b4d/54ab17d0cfed9b7e20ade9acf9150596adc363c7d21d612402220d75a64d503f/gmp:/Users/npoteat3/.local/share/alire/builds/gnatcoll_iconv_24.0.0_e90c5b4d/feac2fd1f2043590964c6fec89adbc484b407d822ddc06122f8af5d61983c2d2/iconv:/Users/npoteat3/.local/share/alire/builds/langkit_support_24.0.0_e7945e68/56e05bc6c873878848d645cad710a3afe7e7205d5faeabb9e5b69c93386408e6:/Users/npoteat3/.local/share/alire/builds/libgpr2_24.0.0_eda3c693/51cc735e38dec92bc93923669272fd8ba1670215735022300fc0c42729432262:/Users/npoteat3/.local/share/alire/builds/libgpr_24.0.0_d9c96bda/ab5a8449e50442ee1b11507d1b8b42bcb41f62b0c668a4289f1dc897e911f994/gpr:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/distrib:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/dom:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/input_sources:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/sax:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/schema:/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e/unicode:/Users/npoteat3/repos/libadalang" export LANGKIT_SUPPORT_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/langkit_support_24.0.0_e7945e68/56e05bc6c873878848d645cad710a3afe7e7205d5faeabb9e5b69c93386408e6" export LD_LIBRARY_PATH="/Users/npoteat3/.local/share/alire/toolchains/gnat_native_14.1.3_ece13bc5/lib" export LD_RUN_PATH="/Users/npoteat3/.local/share/alire/toolchains/gnat_native_14.1.3_ece13bc5/lib" export LIBADALANG_ALIRE_PREFIX="/Users/npoteat3/repos/libadalang" export LIBGMP_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/releases/libgmp_6.3.0_system" export LIBGPR2_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/libgpr2_24.0.0_eda3c693/51cc735e38dec92bc93923669272fd8ba1670215735022300fc0c42729432262" export LIBGPR_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/libgpr_24.0.0_d9c96bda/ab5a8449e50442ee1b11507d1b8b42bcb41f62b0c668a4289f1dc897e911f994" export LIBRARY_PATH="/Users/npoteat3/.local/share/alire/toolchains/gnat_native_14.1.3_ece13bc5/lib:/opt/homebrew/lib" export PATH="/Users/npoteat3/.local/share/alire/toolchains/gprbuild_22.0.1_b1220e2b/bin:/Users/npoteat3/.local/share/alire/toolchains/gnat_native_14.1.3_ece13bc5/bin:/Users/npoteat3/repos/libadalang/venv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/usr/local/share/dotnet:~/.dotnet/tools" export XMLADA_ALIRE_PREFIX="/Users/npoteat3/.local/share/alire/builds/xmlada_24.0.0_ae5a015b/491f4fc1c53e9962115b4d147015304630bb0fe17452e174cc1c07e3972f8d1e" '''

python3 lal_playground


  File "/Users/npoteat3/repos/libadalang/scripts/lal_playground", line 15, in <module>
    import libadalang
  File "/Users/npoteat3/repos/libadalang/venv/lib/python3.10/site-packages/libadalang/__init__.py", line 84, in <module>
    _c_lib = ctypes.cdll.LoadLibrary(_c_lib_path)
  File "/opt/homebrew/Cellar/python@3.10/3.10.14_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ctypes/__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "/opt/homebrew/Cellar/python@3.10/3.10.14_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(libadalang.dylib, 0x0006): tried: 'libadalang.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibadalang.dylib' (no such file), '/opt/homebrew/lib/libadalang.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/lib/libadalang.dylib' (no such file), '/usr/lib/libadalang.dylib' (no such file, not in dyld cache), 'libadalang.dylib' (no such file)'''