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

newbie questions #2

Closed
omarcostahamido opened this issue Jun 25, 2021 · 142 comments
Closed

newbie questions #2

omarcostahamido opened this issue Jun 25, 2021 · 142 comments

Comments

@omarcostahamido
Copy link
Contributor

Hi @shakfu
What a great repo!
I have some newbie questions if you don't mind me asking:

  • is this mac os only?
  • does it only work with homebrew python installation or vanilla python from python.org also works?
  • does it actually embeds python into the external or is the external connecting to local python installation?
  • could you add a simple list of dependencies to the readme?
  • any reason why you can't provide already compiled max externals?
    • I know you probably don't want to populate the repo history with it but you could always add them to a release?
  • does this work with python packages?
    • is it possible to provide an example that installs for example numpy and makes use of it?

Thank you for your attention and sorry for the long list of questions.
Best,
OCH

@shakfu
Copy link
Owner

shakfu commented Jun 26, 2021

Thanks for your interest in this project. I suggest you go through the README carefully since it directly addresses many topics raised in your questions.

First, it's important to understand that this repo is a kind of umbrella project for different ways to use Python in Max/MSP. So in many cases, the answer is qualified by a 'it depends'.

  • This project is macOS only for now and because of this it works by default with Homebrew installed python but it can also work with python compiled from source as well.

  • The default build creates a lightweight external linked to your local homebrew python3; another variation embeds python3 into an external linked to python3 which resides in a Max package; and another variation embeds python into the external itself without an dependencies. There are other ways as well. The README gives an overview of the differences between the different approaches.

  • The dependencies are there included in the README, but its not too complicated: python3 installed on your system, cython, Xcode or xcode-select --install command line tools for compilation.

  • As per your request I have made a pre-release0 available (see the release section).

  • It definitely works with python packages but depends on the build: if it connects to your local system python then you can use any package as you like. Otherwise, if you create a custom python build you can include packages manually or via pip.

Hope the above was useful.

@shakfu
Copy link
Owner

shakfu commented Jun 30, 2021

Hi @omarcostahamido just in case you were not aware I made a pre-release of a couple of python3 externals. Let me know if they work for you.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Jul 1, 2021

Max[33565:5524040] Error loading /Users/user/Documents/Max 8/Library/pyexternals/pyjs.mxo/Contents/MacOS/pyjs:  
dlopen(/Users/user/Documents/Max 8/Library/pyexternals/pyjs.mxo/Contents/MacOS/pyjs, 262): 
Library not loaded: /usr/local/opt/gettext/lib/libintl.8.dylib
Referenced from: /Users/user/Documents/Max 8/Library/pyexternals/pyjs.mxo/Contents/MacOS/pyjs

@shakfu
Copy link
Owner

shakfu commented Jul 1, 2021

Ok, it looks like there's still a dependency on gettext or libintl. This can be fixed but it will take a little time to revise the build script. Otherwise, a quick fix right now on a mac using homebrew should be:

brew install gettext

then try again.

Let me know if you still have problems.

@shakfu
Copy link
Owner

shakfu commented Jul 3, 2021

@omarcostahamido, I fixed the dependency issue on the pre-release0 externals (it's is now statically linked at build-time instead of dynamically linked so it should not require the brew install gettext solution mentioned above).

If you have a chance download the new externals from the releases section and give them a go. Let me know is you have any further issues.

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu
py.mxo is good now, but pyjs still becomes red / unusable everytime. Nothing logged on the console tho :/
Thanks

@omarcostahamido
Copy link
Contributor Author

btw, having a full python 3.9 system running in that little 9.3 MB external is a pretty impressive feat. I've previously compiled my python as an executable using pyinstaller for quick access (and sharing with non tech-avy users). If it is really possible to compile this guy with custom python packages included I am definitely gonna relearn this and follow your steps :)

@shakfu
Copy link
Owner

shakfu commented Jul 5, 2021

Hi @omarcostahamido

Good to hear that you go at least one of the externals working. It's my bad, I should have included a README in the release: the other one, pyjs.mxo is in fact a bit different frompy.mxo because it's a jsextension, a not well-documented way of making a c-based external which only works in the [js] object.

Unlike a regular c external such as py.mxo, a jsextension needs to reside in a Max package structure with some extra files to work properly:

mypackage

If you look at the image of a minimal package with both externals. The pyjs.mxo external requires the jsextension folder with the maxclasswrap.js file inside. The package folder also needs a javascript folder to hold .js files which need to be used as an argument to the [js] object which hosts pyjs.mxo.

A demonstration of this is give below on the right side of the py_test_standalone.maxpat patcher file which tests both externals at the same time. If you open up this test file you can double-click on the [js] object as below and it will open up the test_pyjs.js file in the code editor. This is a demo on how to use pyjs.

pyjs

Hope all of the above makes sense. My advice is to just use the py external for now. It has the most features, and then if you want to work in javascript and python at the same time then you can use the pyjs external. I will add a README to the release to make the above clearer in any case.

@shakfu
Copy link
Owner

shakfu commented Jul 5, 2021

btw, having a full python 3.9 system running in that little 9.3 MB external is a pretty impressive feat. I've previously compiled my python as an executable using pyinstaller for quick access (and sharing with non tech-avy users). If it is really possible to compile this guy with custom python packages included I am definitely gonna relearn this and follow your steps :)

(-: Yes, that was one of the biggest hurdles to making this feasible. In fact packaging was a huge pita which took 3 times as long as development due to a lot of trial and error as there's no official documentation to help you make a minimal python distribution and because Apple's code-signing and notarization rules kept classifying bundled externals which embedded python as illformed after compilation. The Aha moment was discovering that the only place you could keep the python standard lib was in the Resources folder in the bundle and that one needed to compile python in the most static way possible to get things down to a reasonable size and make Apple's codesigning / notarization algorithm happy -- a technique I learned from a side project of the beware briefcase project.

In any case, if you want to learn how a minimal python distribution is built have a look at the builder python package in the py directory.

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu !
I'm trying the new release 0.1 😄
Every time I open py_overview.maxpat this is printed to the console:
Screen Shot 2022-03-07 at 12 25 23 PM

Should we be concerned?

On the readme you write

Open up any of the patch files in the patcher directory of the generated max package, and also look at the .maxhelp patcher to understand how the py and the pyjs objects work.

There is no pyjs help patch, and I think it would be good to have one since it appears as an object in the package but in reality we are never meant to create a pyjs object instance in a patch but only to call it from within a js max object - am I understanding it correctly?

edit: I just suggested a simple help patch on #4 this will be helpful if someone creates a pyjs object and starts scratching their head trying to understand how to use it. I think, for maxers, one of the first instincts is to alt-click to open the help patch 😉

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 7, 2022

I would also like to suggest moving all positional arguments into attributes. There are some options that I would like to try but I don't want to declare all the others before getting into that place. And I know that you can use any positional attribute and turn into a sort of attribute just by using its name but you need to know their exact name in order to do that. And if you do that you loose not only the neat autocomplete but also the handy instructions that let you quickly confirm what you are doing without the need to go open its reference page. For example:
Screen Shot 2022-03-07 at 5 09 54 PM

edit: I just added #5 that address this

@shakfu
Copy link
Owner

shakfu commented Mar 7, 2022

Hi Omar,

Thanks for your feedback and for revisiting this project. I'll address a number of a your questions in the sequence that I read them:

1. Every time I open py_overview.maxpat there is a some debug information in the console. Should we be concerned?

It looks like I left @debug=on in this patch py_overview.maxpat.zip and it further must have cached some paths to related on my system in the patch. You should be able to switch it off by setting @debug=off (although, it seems some logging is not conditioned on the debug flag it seems). In any case, I have fixed this on the main branch (also attached in this post).

2. There is no pyjs help patch, and I think it would be good to have one.

An omission on my part. Couldn't agree with you more. The py-js/javascript/test_pyjs.js would be useful in this instance.

3. I would also like to suggest moving all positional arguments into attributes.

Agreed.

Thanks for the pull requests, Omar. Your feedback and contributions are much appreciated!

S

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 7, 2022

Dear Shakeeb,

My pleasure. I have my eyes on your repo, and I am really glad you continue to work on it.
You really summed it up very well at the end of the readme the different attempts and struggles of dealing with Python in Max. I am personally very interested in helping you in this project (if you don't mind me asking some newbie questions along the way).
Next thing up for me: figure out how to extend this with other python packages. I know you wrote in the readme:

each external 'bundle' contains an embedded python3 interpreter with a zipped standard library in the Resources folder which also has a site-packages directory for your own code.

But I am just thinking right now if there is a way to programmatically download a python package (we can't assume pip is available right?... or can py object actually provide it!? ). I'm going to try creating a virtual env, install numpy, rip the site-packages folder somewhere in the max path and add it to py using the pythonpath attribute, which I've been meaning to try.

Question: which one is this patch? If you also don't remember we can recreate it. It should be easily available to users when they open your package.

More serious question: do you plan on working on a windows version? I have access to a windows machine with visual studio. I can try dipping my toes here too. Reason for asking this ties back into what I said above about packages. Using the Resources folder is a neat trick but... it is so mac-centered: what happens when you have a windows version for this? It be nice to start thinking about a cross-platform way to go about this. (please correct me if I am missing something). Thx.

OCH

@omarcostahamido
Copy link
Contributor Author

I think I need your insight into this. I still can't import python packages. Tried both playing around with pythonpath and copying packages to the py site-packages folder. I'm always faced with:
Screen Shot 2022-03-07 at 11 35 33 PM

[py main] import numpy: ImportError('\n\nIMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!\n\nImporting the numpy C-extensions failed. This error can happen for\nmany reasons, often due to issues with your setup or how NumPy was\ninstalled.\n\nWe have compiled some common reasons and troubleshooting tips at:\n\n https://numpy.org/devdocs/user/troubleshooting-importerror.html\n\nPlease note and check the following:\n\n * The Python version is: Python3.9 from "/Applications/Max.app/Contents/MacOS/Max"\n * The NumPy version is: "1.21.5"\n\nand make sure that they are the versions you expect.\nPlease carefully study the documentation linked above for further help.\n\nOriginal error was: No module named 'numpy.core._multiarray_umath'\n')

Now, for sake of completion I should note that I myself am running python 3.7.3 on purpose (no fancy homebrew install, just plain old install from python.org) and I wonder if that could influence the version of numpy that I install by default with pip to something that is not compatible with your embedded python 3.9.6 version (?). Thoughts?

edit: it seems this problem is specific to NumPy. I just tried another random package and it didn't complain when importing.

@omarcostahamido
Copy link
Contributor Author

This issue suggested that a simple upgrade would suffice to solve this problem. I managed to install the very latest numpy available (and via pip in a machine that has python 3.8.9, not mine), but it still complains... What do you reckon?
Screen Shot 2022-03-08 at 1 43 24 AM

@shakfu
Copy link
Owner

shakfu commented Mar 8, 2022

Hi Omar,

Not sure why, but I'm unable to push to this repo just recently and I've raised an issue with GitHub support to help me fix things so I'm pausing development till this happens.

In the meantime, I'll try to answer your questions as far as I can:

How to extend python with your own scripts and 3rd party libraries

  1. The easiest solution is not to use a self-contained external and use an external that's linked to your system python3 installation. This is what gets built if you run ./build.sh in the root of the project. If you do it this way, you automatically get access to all of your python libraries.

  2. If you insist on using a relocatable external (for packages or standalones), then it's a little bit more effort depending on what you want to do. First you have to note that there several locations where this can be done:
    A. The external site-packages: py-js/externals/py.mxo/Contents/Resources/lib/python3.9/site-packages
    B. The package script folder: py-js/examples/scripts
    C. Whichever path you set the patcher PYTHONPATH property to.

For A, I have tested pure python scripts which should work without re-codesigning the externals, but if you add compiled extensions, then I think you have to re-codesign the external. Check out my maxutils project for help with that.

For B, this is just a location that's automatically added to the PYTHONPATH, if I recall correctly, so pure python scripts and compiled extensions should be fine for Package Distribution. (code signing may be required for 3rd party distributions)

For C, this is just setting that is done at the patch level so it should be straightforward.

Note that it is possible to compile a python externals with an embedded pip (see the python builder package), but it will be rather large, but it will allow you to install to the bundle directly rather than manually.

Getting numpy to work in py-js

The easiest way is to use (1) above and just create an adhoc python external linked to your system python3 setup. If you have numpy installed there, then you should be good to go with the following caveat: the type translation system does not currently automatically cover native numpy dtypes so they would have to be converted to normal lists before use with Max. This is not a hard constraint, just not implemented yet.

If you want to go the way of (2) above, then it should be possible to package numpy in the full relocatable external version, but it will take some work. It'll be easiest to just start with the full external build (using the the python builder package) and not the minimal version that is built by default. If you do this, it's just straightforward and you can pip install numpy, but you will end up with a huge external bundle due to numpy's size (90.2 MB). I haven't yet tried getting access to numpy via setting PYTHONPATH property.

Windows version?

It should be theoretically possible to make the code more portable for use in windows, but I really gave up on windows development ages ago so it'll have to be someone other than me who make this possible.

Where is this patch?

Question: which one is this patch? If you also don't remember we can recreate it. It should be easily available to users when they open your package.

It the py_test_standalone.maxpat patch in the patchers folder.

S

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

Not sure why, but I'm unable to push to this repo...

Strange... I use github desktop it works pretty well.

I really gave up on windows development ages ago...

Understood.

The easiest solution is not to use a self-contained external and use an external that's linked to your system python3 installation.

I understand that is the most stable approach, but for the people I work with they'll just loose interest the moment I ask them to open the terminal window or install python. So, yes, I really need the self contained version, which I also think is what makes your project so unique (and I haven't got into your other python implementations yet)

Getting numpy to work in py-js

I do want to go the route (2). I'm surprised you said:

It'll be easiest to just start with the full external build (using the the python builder package) and not the minimal version that is built by default.

In my mind the current minimal python external should have no problem accessing it using the PYTHONPATH property to add a directory where the 90mb numpy site-packages folders are located. In fact, that worked just fine to import some other packages just not numpy. Can you try this on your end? Using your current py object, add your site-packages folder (or a "new venv with just numpy"s site-packages folder) via pythonpath and then try to send it an import numpy message.

Thank you so much for your thorough response answering all my questions. I really appreciate it!

OCH

edit: I've noticed that you were able to merge the PRs (thank you), I wonder if you can overcome your issues the same way: creating a fork and sending PRs to here (silly workaround for a silly bug indeed).

@shakfu
Copy link
Owner

shakfu commented Mar 8, 2022

Hi @omar

With regards to your question about numpy, as you have seen it is not so straightforward to use it for some reason outside of method (1).

I will look into t a bit more. There may be a bug in relation the setting of pythonpaths or perhaps the minimal relocatable external is missing something or the other. That's why I had the sense that the regular full build would most likely work.

@shakfu
Copy link
Owner

shakfu commented Mar 8, 2022

Fyi Github support fixed the issue with the repo which looked like it was a malfunctioning server from their side. All good now.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 8, 2022

With regards to your question about numpy, as you have seen it is not so straightforward to use it for some reason outside of method (1).

Indeed. But we must push through 😄 I got a hold of a machine where I was able to install python 3.9.6 (from python.org though) and create a virtual env and install numpy, then I grabbed the sitepackages folder and put it on my (3.7.3) venv folder aaaand...
Screen Shot 2022-03-08 at 7 43 58 PM
it still gives me an error. But a different one! That means I am getting somewhere at least, even if in the wrong direction (ha!).
Next thing I am going to try is to also copy over the 3 f2py files that I noticed are installed in the bin foder when numpy is installed. The problem is...

I will look into t a bit more. There may be a bug in relation the setting of pythonpaths or perhaps the minimal relocatable external is missing something or the other. That's why I had the sense that the regular full build would most likely work.

I have been having trouble with pythonpath method. The only way I can make it to work is by setting it on the object itself py @pythonpath {my_path_to_sitepackages}. If I just create a plain py object and then send it the message pythonpath {my_path_to_sitepackages} it doesn't really do anything... not even debug mode acknowledges it!

Thank you for also looking into this.

edit: yup right now this is the bottleneck I am facing. I think I tried all the combinations. putting these numpy site-packages folders inside the external resources doesn't help either.

@omarcostahamido
Copy link
Contributor Author

Good to know Github got back to you and fixed problem! Thank you @github 🎉

@shakfu
Copy link
Owner

shakfu commented Mar 8, 2022

Incidentally, I created a 'fat' static python external and installed numpy in its site-packages and had the same error. After a little research, I found this which provided a good analysis (and possible solution) for why this happens with numpy. I did try a quick fix as per the advice but it still didn't work, so it'll probably be more involved to get statically compiled python externals to work. No quick fixes unfortunately!

In the meantime, use method (1) or ... use an alternative packaging variation (it's in the README):

In the root of the py-js directory:

make -C source/py bin-homebrew-pkg

or in py-js/source/py

make bin-homebrew-pkg

NOTE that this will create a py package in $HOME/Documents/Max 8/packages/py

In this package, you will find two externals in the externals folder, and in the support folder, you'll find a 'supporting' python installation. For the purposes of testing whether NumPy works in this case, do the following somewhere:

virtualenv venv
source venv/bin/activate
pip install numpy
mv venv/lib/python3.9/site-packages/numpy ~/Documents/Max 8/Packages/py/support/python3.9/lib/python3.9/site-packages/numpy

Then open ~/Documents/Max 8/Packages/py/patchers/tests/test_numpy.maxpat and after running the test you should get (what I got :-)

numpy-lives

Note that recent changes in Max have allowed for this to work in standalones too. Just create your standalone application from a patcher which includes the py and pyjs objects. Once it is built into a then copy the whole aforementioned py package to <STANDALONE>/Contents/Resources/C74/packages and delete the redundant py.mxo in <STANDALONE>/Contents/Resources/C74/externals since it already exists in the just-copied package.

@omarcostahamido
Copy link
Contributor Author

In the meantime, use method (1) or ... use an alternative packaging variation (it's in the README):

Ok, trying to use the make bin-homebrew-pkg but several errors occur:

/Documents/Max 8/Packages/py-js/source/py/api.c:6:10: fatal error: 'Python.h' file not found
#include "Python.h"
         ^~~~~~~~~~
1 error generated.
warning: Could not read serialized diagnostics file: Cannot Load File: Failed to open diagnostics file (in target 'py' from project 'py-js')

** BUILD FAILED **


The following build commands failed:
	CompileC /Users/omar/Documents/Max\ 8/Packages/py-js/source/py/targets/bin-homebrew-pkg/build/py-js.build/Development/py.build/Objects-normal/x86_64/api.o /Users/omar/Documents/Max\ 8/Packages/py-js/source/py/api.c normal x86_64 c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
Command line invocation:
    /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -project targets/bin-homebrew-pkg/py-js.xcodeproj -target pyjs
/Documents/Max 8/Packages/py-js/source/py/pyjs.c:5:10: fatal error: 'Python.h' file not found
#include <Python.h>
         ^~~~~~~~~~
1 error generated.

** BUILD FAILED **


The following build commands failed:
	CompileC /Users/omar/Documents/Max\ 8/Packages/py-js/source/py/targets/bin-homebrew-pkg/build/py-js.build/Development/pyjs.build/Objects-normal/x86_64/pyjs.o /Users/omar/Documents/Max\ 8/Packages/py-js/source/py/pyjs.c normal x86_64 c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
make: *** [build-bin-homebrew-pkg] Error 65

@omarcostahamido
Copy link
Contributor Author

I have regular Python (from Python.org). And it is here /Library/Frameworks/Python.framework/Versions instead of the /usr/local/opt/python3/Frameworks/Python.framework/Versions. So, I tried changing line 64 of core.py but it is still complaining. Thoughts?

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 9, 2022

So, I know this is terribly messy, but I am sharing here in any case:

  • I copied /Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m to /Documents/Max\ 8/Packages/py-js/source/py. I was really annoyed at the missing files and just wanted to get on with this.
  • changed several file referring to #include "Python.h" and other neighbor files to be referring to the local copy #include "python3.7m/Python.h" (yeah, I told you it was messy)
    • I think these included py.h api.c api.h and pyjs.c
  • changed the reference to a supposedly homebrew installed python location /usr/local/opt/python3/Frameworks/Python.framework/Versions to a vanilla python.org install location /Library/Frameworks/Python.framework/Versions
    • this was in core.py and bin-homebrew.sh
  • changed a couple other places where I could still find a force reference to python 3.9
    • line 25 of /py-js/source/py/targets/src-shared-ext/py-js.xcodeproj/project.pbxproj
    • and in /py-js/source/py/targets/common.xcconfig
  • only then it successfully compiled this guy... into two 2.9 and 2.6mb externals!?
    • (maybe you could clarify for me what was supposed to happen and what is the difference of this version?)
    • when I open /py-js/externals/py.mxo/Contents/Resources/lib it still shows a python3.9 folder and python39.zip file - fml 🤦
    • also, it did create a /Documents/Max\ 8/Packages/py folder but it is empty. It seems all it does will replace the contents of the current py-js package folder 😞
  • finally I tried running and... it's weird. It kinda worked for a little bit. I realized that after I create a py object with the @pythonpath attribute declared in it, this path becomes available to other py objects... and then it crashed Max.

I think this all goes to say that I am really trying to get this working, but I am still not entirely sure how to properly use/configure it for my setup (python 3.7.3, installed via python.org installer). If you can make some sense out of this (and I am pretty sure you're the only person who can) it would be great. Thank you!

@shakfu
Copy link
Owner

shakfu commented Mar 9, 2022

Hi @omar

I think this all goes to say that I am really trying to get this working, but I am still not entirely sure how to properly use/configure it for my setup (python 3.7.3, installed via python.org installer). If you can make some sense out of this (and I am pretty sure you're the only person who can) it would be great.

Really really appreciate that you are trying to get this working. But first thing you should do is just take a breather and get some perspective on what should be done.

On MacOS, in this particular project, I spent the initial 25% of my time happily coding and solving programming problems, and the rest trying to overcome packaging problems (which include codesigning and notarization requirements by Apple). This is the reason why I have developed so many ways to package an external for my particular case (a Homebrew python user).

On MacOS Catalina (my current macOS version), there's system python2 (/usr/bin/python2), there's system python3 (/usr/bin/python3) and there's homebrew python3 (/usr/local/bin/python3 as a symlink to /usr/local//Cellar/python@3.9/3.9.10/bin/python3). As a rule, I don't touch my system python installations. So let's put these aside for now, and focus on my homebrew python3 installation.

All of the <xxx>-homebrew-<yyy> methods (in the Makefile in py-js/source/py/Makefile are specific to the category of homebrew installed python on macOS).

Please note that I did not test any of my packaging methods on a binary-installed python3 from python.org on a macOS. I have only developed externals that were built from source downloaded from python.org. Indeed, the python package py-js/source/py/builder handles this case by automatically downloading python source code from python.org, downloading its dependencies, configuring and compiling, etc..

It is a recipe for pain and suffering to try to retrofit one method on the other in the manner in which you were doing earlier. I know this too well (-:

In any case, it should not be too difficult to create a method to handle the case of someone who has installed python3 in binary form from python.org:

First step is to get the python3-config values:

PYTHON_VERSION=$(python3 --version | sed s/Python[[:space:]]//) # 3.9.5
PYTHON_VER=${PYTHON_VERSION%.*}          # 3.9
CFLAGS=`python3-config --cflags`
LDFLAGS=`python3-config --ldflags`

Please make sure that these are from you python.org installation and not the system pythons installation. Are you able to you obtain these?

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 9, 2022

Really really appreciate that you are trying to get this working.

This is a very exciting project, and I am also learning a lot from it, so thank you!

On MacOS Catalina (my current macOS version), there's system python2 (/usr/bin/python2), there's system python3 (/usr/bin/python3)

I am also on MacOS Catalina (10.15.7 more precisely)! I have a system python2 but not a system python3 (edit: correction, I do have a python3 in there, but whenever I do which python3 I get the one I installed)

All of the -homebrew- methods (in the Makefile in py-js/source/py/Makefile are specific to the category of homebrew installed python on macOS).

Ok, so I get that what you are trying to say is that I should create a new <xxx>-pythonorg-<yyy> instead of going around editing those that you have carefully crafted for homebrew version, haha. I understand the messy approach described on my last post is not the way to go. And I promise I won't create a PR with any of this trash! I am just trying to move in some direction here and learn how this works - or better yet, how this can work with my system 😉

Please note that I did not test any of my packaging methods on a binary-installed python3 from python.org on a macOS. I have only developed externals that were built from source downloaded from python.org. Indeed, the python package py-js/source/py/builder handles this case by automatically downloading python source code from python.org, downloading its dependencies, configuring and compiling, etc..

Ok, so this is the first thing I really need to clarify. The files I modified on the second bullet point of my last post (py.h api.c api.h and pyjs.c) are all referring to some Python header files. Is this the python source code you are referring to? If so, how can I actually make the builder be aware of their current location? With my python.org installation these files are all located under /Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m. What about on your side? I thought simply changing /usr/local/opt/python3/Frameworks/Python.framework/Versions to /Library/Frameworks/Python.framework/Versions would make the trick. You also say that it supposedly downloads python source from python.org, so this shouldn't even be a problem then? How can I make sure that it is in fact downloading these?

It is a recipe for pain and suffering to try to retrofit one method on the other in the manner in which you were doing earlier. I know this too well (-:

ooof! haha. no need to say more. I know, you know, we all know. But I am still learning this project though! Please have a little patience with me. And thank you for guiding me!

In any case, it should not be too difficult to create a method to handle the case of someone who has installed python3 in binary form from python.org:
First step is to get the python3-config values:

Alright, here we go!

PYTHON_VERSION=$(python3 --version | sed s/Python[[:space:]]//)

  • 3.7.3

PYTHON_VER=${PYTHON_VERSION%.*}

  • 3.7

CFLAGS=python3-config --cflags

  • -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g

LDFLAGS=python3-config --ldflags

  • -L/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/config-3.7m-darwin -lpython3.7m -ldl -framework CoreFoundation

@shakfu
Copy link
Owner

shakfu commented Mar 9, 2022

Ok, with a little manual work, I managed to generate a 'sumo' version of the py external which contains 'numpy'. It took me a while lay it out internally and then to notarize it but I finally managed to sort that out, thankfully.

It's in the releases section, and you can also download it from here.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 29, 2022

You seem to be out of step with the posts.

hold on, I'm answering all the things in order. It takes time to do all the compilations here.

To get the dev branch do the following:
Then test everything: make test

Here's what happened:

$  make test
>>> cleaning externals
>>> cleaning support directory
>>> cleaning build artifacts from local-sys target
>>> cleaning build artifacts from homebrew-pkg target
>>> cleaning build artifacts from homebrew-ext target
>>> cleaning build artifacts from framework-pkg target
>>> cleaning build artifacts from framework-ext target
>>> cleaning build artifacts from shared-pkg target
>>> cleaning build artifacts from shared-ext target
>>> cleaning build artifacts from static-pkg target
>>> cleaning build artifacts from static-ext target
>>> cleaning build artifacts from relocatable-pkg target
>>> cleaning build directory
>>> running tests

running 'make default'

real	0m4.782s
user	0m0.978s
sys	0m0.480s

~/.build_pyjs/logs/3.7.3/default.log           -> FAILURE: 1 out of 2 builds OK

running 'make homebrew-pkg'

real	0m6.468s
user	0m1.643s
sys	0m1.311s

~/.build_pyjs/logs/3.7.3/homebrew-pkg.log      -> FAILURE: 0 out of 2 builds OK

running 'make homebrew-ext'

real	0m5.562s
user	0m1.491s
sys	0m1.304s

~/.build_pyjs/logs/3.7.3/homebrew-ext.log      -> FAILURE: 0 out of 2 builds OK

running 'make shared-pkg'

real	4m20.318s
user	3m0.586s
sys	0m51.593s

~/.build_pyjs/logs/3.7.3/shared-pkg.log        -> FAILURE: 0 out of 2 builds OK

running 'make shared-ext'

real	1m56.238s
user	1m23.673s
sys	0m24.728s

~/.build_pyjs/logs/3.7.3/shared-ext.log        -> FAILURE: 0 out of 2 builds OK

running 'make static-ext'

real	2m5.724s
user	1m37.792s
sys	0m20.783s

~/.build_pyjs/logs/3.7.3/static-ext.log        -> FAILURE: 0 out of 2 builds OK

running 'make framework-pkg'

real	1m57.009s
user	1m21.525s
sys	0m24.765s

~/.build_pyjs/logs/3.7.3/framework-pkg.log     -> FAILURE: 0 out of 2 builds OK

running 'make framework-ext'

real	1m56.812s
user	1m24.074s
sys	0m24.973s

~/.build_pyjs/logs/3.7.3/framework-ext.log     -> FAILURE: 0 out of 2 builds OK

running 'make relocatable-pkg'

real	0m43.716s
user	0m18.873s
sys	0m14.810s

~/.build_pyjs/logs/3.7.3/relocatable-pkg.log   -> SUCCESS: 2 out of 2 builds OK

the log 3.7.3.zip

Best

@shakfu
Copy link
Owner

shakfu commented Mar 29, 2022

Hi @omarcostahamido

After reading through one of your logs, it looks like you are running things out of a virtualenv called MYENV. If so, that may be the problem, since the test environment which was used did not entail using a virtualenv.

Please see the attached log of my python3.7 run and where it differs from yours.

3.7.9.zip

@shakfu
Copy link
Owner

shakfu commented Mar 29, 2022

Hi @omarcostahamido

After spending more time with your logs, I am more and more convinced that we should put aside py-js for now and figure out if you have the basic dependencies and infrastructure to compile python3.7 on your system.

Just to highlight the 'breaking' errors in the simpler (-ext) variations:

static-ext

error: [Errno 2] No such file or directory: '~/.build_pyjs/lib/python-static/include/python3.7m/pyconfig.h'

This error typically indicates missing dependencies during compilation of python.

shared-ext

Same dependency error as static-ext

error: [Errno 2] No such file or directory: '~/.build_pyjs/lib/python-shared/include/python3.7m/pyconfig.h'

framework-ext

In this case, you are unable to build any of the python builtin extensions starting with _struct

building '_struct' extension
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -I. -IObjects -IInclude -IPython -I/usr/local/include -I~/Documents/Max 8/Packages/py-js/source/py/MYENV/include -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c _struct.c -o build/temp.macosx-10.9-x86_64-3.7/_struct.o
clang: error: no such file or directory: '_struct.c'
clang: error: no input files

Here I can see that you have possibly installed a virtualenv MYENV which is perhaps a complicating factor, and that you are running Mac os 10.9 (Mavericks) which may or may not be an issue.

So before I spend anymore time trying to solve issues on my front, I think we should establish whether your can build python3.7 from source on your system:

Here are basic steps test this:

  1. Download Python from python.org

Please download https://www.python.org/ftp/python/3.7.13/Python-3.7.13.tgz

  1. Build it
tar -xvf Python-3.7.13.tgz
cd Python-3.7.13
./configure
make

If you have the dependencies, the you should be able to build the above without errors and then run the built python interpreter without errors:

./python.exe

Can you please test this case.

Thanks.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 29, 2022

Hi @shakfu

a ./python.exe did appear after running all of it. For the reference it ended here:

Python build finished successfully!
The necessary bits to build these optional modules were not found:
_gdbm                 _hashlib              _ssl               
ossaudiodev           spwd                                     
To find the necessary bits, look in setup.py in detect_modules() for the module's name.


The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc                  atexit                pwd                
time                                                           


Failed to build these modules:
_lzma                 _tkinter                                 


Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381

running build_scripts
creating build/scripts-3.7
copying and adjusting /Users/omar/Downloads/buildingpython/Python-3.7.13/Tools/scripts/pydoc3 -> build/scripts-3.7
copying and adjusting /Users/omar/Downloads/buildingpython/Python-3.7.13/Tools/scripts/idle3 -> build/scripts-3.7
copying and adjusting /Users/omar/Downloads/buildingpython/Python-3.7.13/Tools/scripts/2to3 -> build/scripts-3.7
copying and adjusting /Users/omar/Downloads/buildingpython/Python-3.7.13/Tools/scripts/pyvenv -> build/scripts-3.7
changing mode of build/scripts-3.7/pydoc3 from 644 to 755
changing mode of build/scripts-3.7/idle3 from 644 to 755
changing mode of build/scripts-3.7/2to3 from 644 to 755
changing mode of build/scripts-3.7/pyvenv from 644 to 755
renaming build/scripts-3.7/pydoc3 to build/scripts-3.7/pydoc3.7
renaming build/scripts-3.7/idle3 to build/scripts-3.7/idle3.7
renaming build/scripts-3.7/2to3 to build/scripts-3.7/2to3-3.7
renaming build/scripts-3.7/pyvenv to build/scripts-3.7/pyvenv-3.7
/usr/bin/install -c -m 644 ./Tools/gdb/libpython.py python.exe-gdb.py
gcc -c -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall    -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration   -I. -I./Include    -DPy_BUILD_CORE -o Programs/_testembed.o ./Programs/_testembed.c
gcc     -Wl,-stack_size,1000000  -framework CoreFoundation -o Programs/_testembed Programs/_testembed.o libpython3.7m.a -ldl  -framework CoreFoundation     
sed -e "s,@EXENAME@,/usr/local/bin/python3.7m," < ./Misc/python-config.in >python-config.py
LC_ALL=C sed -e 's,\$(\([A-Za-z0-9_]*\)),\$\{\1\},g' < Misc/python-config.sh >python-config

edit:

Here I can see that you have possibly installed a virtualenv MYENV which is perhaps a complicating factor, and that you are running Mac os 10.9 (Mavericks) which may or may not be an issue.

I am running a venv, correct. No I am on Catalina. Never had Mavericks.

@shakfu
Copy link
Owner

shakfu commented Mar 29, 2022

Thanks, @omarcostahamido

How are you setting up your virtualenv? Have you tried without a virtualenv?

@shakfu
Copy link
Owner

shakfu commented Mar 29, 2022

@omarcostahamido May I suggest that you try again without a virtualenv with the 'dev' branch:

make test

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

How are you setting up your virtualenv? Have you tried without a virtualenv?

$ python3 -m venv MYENV
$ source MYENV/bin/activate
$ pip install --upgrade pip setuptools

that's about it.

May I suggest that you try again without a virtualenv with the 'dev' branch: make test

Done it on another machine I got access to running macOS 11.6.4 and python 3.7.3 (no virtual env). Cloned your dev branch, ran make test and...

11.6.4-python3.7.3-devbranch.zip

@omarcostahamido
Copy link
Contributor Author

Hey @shakfu

So, I just realized that you created this folder on my Documents folder:
Screen Shot 2022-03-29 at 7 05 22 PM

@shakfu
Copy link
Owner

shakfu commented Mar 29, 2022

Hi @omarcostahamido

Not sure I understand why you keep introducing new variables into the test: a virtualenv, or a new computer with a different setup than yours. Indeed the default log which you attached for the latter gives some indication that it doesn't even have Xcode installed. The only way this process is going to work is if one maintains consistent testing conditions.

Let's take a pause please. I'm trying to help you solve your specific case provided it remains your specific case. Clearly (from your use of a virtualenv and someone else's computer) you are worried about running test code in your Documents folder.

That's fine. I understand, but let's then forget about the 'dev' branch, and please switch to the master branch of py-js on your machine without a virtualenv and git clone it into your Downloads folder or something. then symlink from the py-js folder of the cloned rep to the $HOME/Documents/Max 8/Packages/py-js after ensuring that any prior install of py-js has been removed. We will build outside of Documents and then move py-js to $HOME/Documents/Max 8/Packages/py-js if the build is successful.

Please cd into ~/Downloads/py-js and make test and let me know how it goes.

@shakfu
Copy link
Owner

shakfu commented Mar 30, 2022

HI @omarcostahamido

As you perhaps gathered from my last post, I was a little bit frustrated with the last results on your machine and was expressing it in a manner which was, in retrospect, unfair to you. It really was no problem to run out of virtualenv or try another computer to get some additional information. It's on me if the code is not working!

In any case, I retested all versions again on my machine, and got positive results. I retested with a virtualenv and got the same. To remove the possibility that Homebrew on my machine was giving me a hidden advantage with respect to dependencies, I tried another machine (an older MacBook air, with Catalina) and removed all traces of Homebrew on it and got positive results. In all cases, I ran the dev branch inside $HOME/Documents/Max 8/Packages and builds were successful except for the homebrew-specific ones which were expected to fail on the external machine.

From one perspective, it is also positive outcome that you were able to compile python to the end without error. If this is reproducible, then the errors may be coming from some of my post-processing code (to shrink python basically), so another testing scenario could be that I create a vanilla case for you to test without any post-processing and to see if that works. I will do that shortly as its a low hanging fruit and quite easy to do.

Also taking a few steps back from trees, it should be unnecessary for you, and perhaps others having the same issues as you, to compile the externals and install xcode if we have automated builds which are producing and releasing build variants in a standardized way (via Github Actions for example). Then you just install the package and you are off. This is another area where a lot can be done.

So let's keep going.

@shakfu
Copy link
Owner

shakfu commented Mar 30, 2022

Hi @omarcostahamido

The 'vanilla' variations, mentioned in my previous post have been pushed to 'dev' branch.

These build variations have no cleaning or post-processing except for 'tests' removal and removal of *.pyc files. This alone shrinks each external from 150 MB to 37 MB

I'd appreciate if you can try both versions:

  1. self-contained external
make vanilla-ext

and

  1. package structure
make vanilla-pkg

I hope these work for you and thanks again for your help!

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Mar 31, 2022

Hi @shakfu

I'm sorry the 11.6.4 tests were not helpful at all. I had limited time with that machine and totally forgot to check xcode 😞

so another testing scenario could be that I create a vanilla case for you to test without any post-processing and to see if that works. I will do that shortly as its a low hanging fruit and quite easy to do.

I'd like to test that yes. I'm baffled that you copied my setup and got different results! I really have no idea what could be going on here... should we check the xcode version? I'm running xcode 11.6 here.

(...) if we have automated builds which are producing and releasing build variants in a standardized way (via Github Actions for example).

Wait, what!? You can setup github actions to build max externals?? I am very ignorant about github actions but I would very much like to learn a little bit about it. I would think that you need a mac (or windows) system to compile objects for those systems... github actions run on a linux system, no? (I mean, I remember seeing somewhere that you can actually point a local machine to be the designated worker for your action, but at that point it becomes just another layer of local setup in this case..)

The 'vanilla' variations, mentioned in my previous post have been pushed to 'dev' branch.

Ok, here we go:

So, make vanilla-ext didn't write the log file and ended here:

136413 INFO : VanillaPythonForExtBuilder changing working dir to: /Users/omar/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 265, in <module>
    app.cmdline()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/cli.py", line 194, in cmdline
    options.func(self, options)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 202, in do_pyjs_vanilla_ext
    self.ordered_dispatch('pyjs_vanilla_ext', args)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 72, in ordered_dispatch
    getattr(builder, method)()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1519, in install
    builder.install()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1005, in install
    self.post_process()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1444, in post_process
    self.fix_python_exec_for_framework2()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1423, in fix_python_exec_for_framework2
    self.cmd.chdir(parent_dir)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 287, in chdir
    os.chdir(path)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/omar/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS'
make: *** [vanilla-ext] Error 1

Then make vanilla-pkghad a similar reaction:

95414 INFO : VanillaPythonForPkgBuilder changing working dir to: /Users/omar/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 265, in <module>
    app.cmdline()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/cli.py", line 194, in cmdline
    options.func(self, options)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 207, in do_pyjs_vanilla_pkg
    self.ordered_dispatch('pyjs_vanilla_pkg', args)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/__main__.py", line 72, in ordered_dispatch
    getattr(builder, method)()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1519, in install
    builder.install()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1005, in install
    self.post_process()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1498, in post_process
    self.fix_python_exec_for_pkg2()
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 1477, in fix_python_exec_for_pkg2
    self.cmd.chdir(parent_dir)
  File "/Users/omar/Documents/GitHub/py-js/source/py/builder/core.py", line 287, in chdir
    os.chdir(path)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/omar/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS'
make: *** [vanilla-pkg] Error 1

hum...

edit: Just tried running make vanilla-ext outside of venv. Same results.

@shakfu
Copy link
Owner

shakfu commented Mar 31, 2022

Hi @omarcostahamido

Thanks for testing. No worries, even if it's not working right now, the information that you just provided helps towards localizing the problem.

I'd like to test that yes. I'm baffled that you copied my setup and got different results! I really have no idea what could be going on here... should we check the xcode version? I'm running xcode 11.6 here.

I'm also very curious why it hasn't been working on your system. I don't think it's an issue if you are running Xcode 11.6. I'm running Xcode 12.4 myself (on Catalina 10.15.7). I'm not sure that's the problem.

Wait, what!? You can setup github actions to build max externals?? I am very ignorant about github actions but I would very much like to learn a little bit about it. I would think that you need a mac (or windows) system to compile objects for those systems... github actions run on a linux system, no? (I mean, I remember seeing somewhere that you can actually point a local machine to be the designated worker for your action, but at that point it becomes just another layer of local setup in this case..)

I'm just starting to learn about Github actions. There's even an approved cycling74 external template which has a pretty decent Github action configuration (for macos/windows) see here

I'm going to have a go at getting this working. I thought the codesigning part would be a blocker but apparently there are GitHub actions which do this. So theoretically, I should be able to generate all of the variations (for mac and windows) on demand.

So, make vanilla-ext didn't write the log file and ended here:

Ok, my bad, I should have asked you to pull the latest 'dev' branch commit to get a fix (avoid downloading dependencies for vanilla builds) and also do this to get logging:

make test-vanilla-ext

I'll attach a log of a successful build of the above, logs shoud be in .build_pyjs

vanilla-ext.log.zip

also try the following:

make test-vanilla-pkg

Thanks!

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

This is the playlist regarding github actions that I was checking out the other day.

I thought the codesigning part would be a blocker but apparently there are GitHub actions which do this. So theoretically, I should be able to generate all of the variations (for mac and windows) on demand.

🙌

Ok, my bad, I should have asked you to pull the latest 'dev' branch commit to get a fix (avoid downloading dependencies for vanilla builds) and also do this to get logging:

Ok, here it goes:
vanilla-ext.log
vanilla-pkg.log

Thank you for looking into this

@shakfu
Copy link
Owner

shakfu commented Mar 31, 2022

It's quite curious why your system is failing to compile the external. Let's just look at one case:
vanilla-ext-3.7-diff-analysis.zip

I have attached three files, your failed log of compiling vanilla-ext-3.7.3, my successful log of compiling vanilla-ext-3.7.9 and a diff-analysis between the two, which I will quote partially here (note that the red lines are from your failed compilation and the green lines are from my successful one):

4205c4211
< Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
---
> Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/c++/4.2.1
4259c4265
< checking for -llvm-profdata... no
---
> checking for llvm-profdata... no
4309,4311c4315,4317
< checking libintl.h usability... no
< checking libintl.h presence... no
< checking for libintl.h... no
---
> checking libintl.h usability... yes
> checking libintl.h presence... yes
> checking for libintl.h... yes
4535c4541
< checking for textdomain in -lintl... no
---
> checking for textdomain in -lintl... yes
4544c4550,4551
< checking for pkg-config... no
---
> checking for pkg-config... /usr/local/bin/pkg-config
> checking pkg-config is at least version 0.9.0... yes
4547a4555

I think this is most likely where the failure occurs, your system does not have pkg-config, which is defined as:

pkg-config is a computer program that defines and supports a unified interface for querying installed libraries for the purpose of compiling software that depends on them. It allows programmers and installation scripts to work without explicit knowledge of detailed library path information. (wikipedia)

> checking for --with-decimal-contextvar... yes
4552c4560
< checking if PTHREAD_SCOPE_SYSTEM is supported... yes
---
> checking if PTHREAD_SCOPE_SYSTEM is supported... no
4572c4580
< checking for bind_textdomain_codeset... no
---
> checking for bind_textdomain_codeset... yes
4839,4840c4847,4848
< checking whether wchar_t is signed... yes
< checking whether wchar_t is usable... no
---
> checking whether wchar_t is signed... no
> checking whether wchar_t is usable... yes
4845c4853
< checking whether right shift extends the sign bit... yes
---
> checking whether right shift extends the sign bit... no
4896c4904
< checking for pkg-config... no
---
> checking for pkg-config... /usr/local/bin/pkg-config
4924c4932
< 47672 INFO : VanillaPythonForExtBuilder make altinstall
---
> 56596 INFO : VanillaPythonForExtBuilder make altinstall
5043c5051
< ./Modules/getpath.c:676:20: warning: 'NSModuleForSymbol' is deprecated: first deprecated in macOS 10.5 - dladdr() [-Wdeprecated-declarations]
---
> ./Modules/getpath.c:672:20: warning: 'NSModuleForSymbol' is deprecated: first deprecated in macOS 10.5 - dladdr() [-Wdeprecated-declarations]
5046c5054
< /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach-o/dyld.h:199:21: note: 'NSModuleForSymbol' has been explicitly marked deprecated here
---
> /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/mach-o/dyld.h:199:21: note: 'NSModuleForSymbol' has been explicitly marked deprecated here
5049c5057
< ./Modules/getpath.c:676:38: warning: 'NSLookupAndBindSymbol' is deprecated: first deprecated in macOS 10.4 - dlsym() [-Wdeprecated-declarations]
---
> ./Modules/getpath.c:672:38: warning: 'NSLookupAndBindSymbol' is deprecated: first deprecated in macOS 10.4 - dlsym() [-Wdeprecated-declarations]
5052c5060
< /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach-o/dyld.h:189:17: note: 'NSLookupAndBindSymbol' has been explicitly marked deprecated here
---
> /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/mach-o/dyld.h:189:17: note: 'NSLookupAndBindSymbol' has been explicitly marked deprecated here
5055c5063
< ./Modules/getpath.c:678:27: warning: 'NSLibraryNameForModule' is deprecated: first deprecated in macOS 10.5 [-Wdeprecated-declarations]
---
> ./Modules/getpath.c:674:27: warning: 'NSLibraryNameForModule' is deprecated: first deprecated in macOS 10.5 [-Wdeprecated-declarations]
5058c5066
< /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/mach-o/dyld.h:169:21: note: 'NSLibraryNameForModule' has been explicitly marked deprecated here
---
> /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/mach-o/dyld.h:169:21: note: 'NSLibraryNameForModule' has been explicitly marked deprecated here
5110c5118,5119
< 		-framework CoreFoundation -ldl  -framework CoreFoundation;
---
> 		-framework CoreFoundation -lintl -ldl  -framework CoreFoundation;
> ld: warning: dylib (/usr/local/lib/libintl.dylib) was built for newer macOS version (10.15) than being linked (10.13)
5121c5130
< sed 's/%VERSION%/'"`DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.3 ./python.exe -c 'import platform; print(platform.python_version())'`"'/g' < Mac/Resources/framework/Info.plist > ~/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Info.plist
---
> sed 's/%VERSION%/'"`DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.9 ./python.exe -c 'import platform; print(platform.python_version())'`"'/g' < Mac/Resources/framework/Info.plist > ~/.build_pyjs/lib/Python.framework/Versions/3.7/Resources/Info.plist
5129c5138,5139
< gcc     -Wl,-stack_size,1000000  -framework CoreFoundation Python.framework/Versions/3.7/Python -o python.exe Programs/python.o  -ldl  -framework CoreFoundation     
---
> gcc     -Wl,-stack_size,1000000  -framework CoreFoundation Python.framework/Versions/3.7/Python -o python.exe Programs/python.o  -lintl -ldl  -framework CoreFoundation     
> ld: warning: dylib (/usr/local/lib/libintl.dylib) was built for newer macOS version (10.15) than being linked (10.13)
5134c5144
< ./Tools/pythonw.c:214:9: warning: comparison of function 'posix_spawn' not equal to a null pointer is always true [-Wtautological-pointer-compare]
---
> ./Tools/pythonw.c:223:9: warning: comparison of function 'posix_spawn' not equal to a null pointer is always true [-Wtautological-pointer-compare]
5137c5147
< ./Tools/pythonw.c:214:9: note: prefix with the address-of operator to silence this warning
---
> ./Tools/pythonw.c:223:9: note: prefix with the address-of operator to silence this warning
5174c5184
< DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.3 ./python.exe -E -S -m sysconfig --generate-posix-vars ;\
---
> DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.9 ./python.exe -E -S -m sysconfig --generate-posix-vars ;\
5181c5191
< DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.3 CC='gcc' LDSHARED='gcc -bundle -undefined dynamic_lookup    ' OPT='-DNDEBUG -g -fwrapv -O3 -Wall' 	_TCLTK_INCLUDES='' _TCLTK_LIBS='' 	./python.exe -E ./setup.py  build
---
> DYLD_FRAMEWORK_PATH=~/.build_pyjs/src/Python-3.7.9 CC='gcc' LDSHARED='gcc -bundle -undefined dynamic_lookup    ' OPT='-DNDEBUG -g -fwrapv -O3 -Wall' 	_TCLTK_INCLUDES='' _TCLTK_LIBS='' 	./python.exe -E ./setup.py  build

Below you have the first sign of actual major failure: failing to build _struct.c

5185,5187c5195,5202
< gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -I. -IObjects -IInclude -IPython -I/usr/local/include -I~/Documents/Max 8/Packages/py-js/source/py/MYENV/include -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c _struct.c -o build/temp.macosx-10.9-x86_64-3.7/_struct.o
< clang: error: no such file or directory: '_struct.c'
< clang: error: no input files
---
> creating build/temp.macosx-10.13-x86_64-3.7/Users
> creating build/temp.macosx-10.13-x86_64-3.7~
> creating build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs
> creating build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs/src
> creating build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs/src/Python-3.7.9
> creating build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs/src/Python-3.7.9/Modules
> gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -I./Include -I. -I/usr/local/include -I~/.build_pyjs/src/Python-3.7.9/Include -I~/.build_pyjs/src/Python-3.7.9 -c ~/.build_pyjs/src/Python-3.7.9/Modules/_struct.c -o build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs/src/Python-3.7.9/Modules/_struct.o
> gcc -bundle -undefined dynamic_lookup build/temp.macosx-10.13-x86_64-3.7~/.build_pyjs/src/Python-3.7.9/Modules/_struct.o -L/usr/local/lib -o build/lib.macosx-10.13-x86_64-3.7/_struct.cpython-37m-darwin.so
5189,5192c5204,5206
< creating build/temp.macosx-10.9-x86_64-3.7/_ctypes
< gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -I. -IObjects -IInclude -IPython -I/usr/local/include -I~/Documents/Max 8/Packages/py-js/source/py/MYENV/include -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c _ctypes/_ctypes_test.c -o build/temp.macosx-10.9-x86_64-3.7/_ctypes/_ctypes_test.o
< clang: error: no such file or directory: '_ctypes/_ctypes_test.c'
< clang: error: no input files
---

After the failure to build _struct.c, there is the failure to build ctypes.c. Note that these are all python3 builtins (i.e. the source code for building them is included with python).

So my brief analysis leads me to speculate that the lack of pkg-config on your system as the most likely culprit.

See the pdf of the man page of pkg-config below:

pkg-config.pdf

My advice is have a look where the compilation is taking place in $HOME/.build_pyjs/src/Python-3.7.3 and see if you can find _struct.c etc.. also have a look why you don't have pkg-config installed and whether this is impactful to other programs which are trying to use to compile on your system.

@shakfu
Copy link
Owner

shakfu commented Apr 2, 2022

Hi @omarcostahamido

I have just run my first 'matrix'-type github workflow (i.e. macos 10.15 Catalina across pythons 3.7 to 3.10) and happily, I had a successful run on the first attempt which matches the testing I've been doing on my own machine.

The success of this run increases the likelihood that you are missing something or the other which is preventing your machine from building successfully. One thing occurred to me recently: have you tried to update your command-line tools? (see this stackoverflow article) which may help.

Incidentally, the successful run was running the 'master' branch, not the 'dev' branch which I have kept stable to test your particular setup preferences.

The GitHub workflow used was just a test run which didn't produce anything that one can use. In fact, it's really basic, but I am quite impressed how powerful this system can be:

name: Build2

on:
  workflow_dispatch:

jobs:
  build:
    name: macos-10.15 python-${{ matrix.python-version }}
    runs-on: macos-10.15
    strategy:
      matrix:
        python-version: ['3.7', '3.8', '3.9', '3.10']

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: 'recursive'
          fetch-depth: '0'

      - name: setup python
        uses: actions/setup-python@v3
        with:
          python-version: ${{ matrix.python-version }}

      - name: Display Python version
        run: python3 --version

      - name: build_default
        run: make

      - name: build_shared_pkg
        run: make shared-pkg

      - name: build_shared_ext
        run: make shared-ext

      - name: build_static_ext
        run: make static-ext

      - name: build_framework_pkg
        run: make framework-pkg

      - name: build_framework_ext
        run: make framework-ext

      - name: build_relocatable_pkg
        run:  make relocatable-pkg

The next iteration will attempt to try to extract the build products, codesign them, notarize them, and package them for release / download.

Before I do that, I want to get Apple Silicon compatibility working. I took a step towards that on the master branch by updating the sdk to version 8.2 and exclusively using max-sdk-base. After doing this, I had a quick attempt at the beginning of the weekend to compile an arm64 version of framework-ext on my m1 MacBook air, and it worked after a few tweaks.

So this direction looks promising.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Apr 3, 2022

Hi @shakfu

I'm really enjoying this thread.
Thank you so much for your careful look into the logs.
So, first things first, if I run which pkg-config it doesn't return a thing, so it is safe to say that it is MIA. But why?

have you tried to update your command-line tools?

I remember updating the command line tools at some point yes.
When I run softwareupdate --list it shows a sec updt for mac os and safari. I can try installing them after I cleanup some open tabs here. And see if that does something.
A quick google search for how to install pkg-config shows several homebrew entries.

Also, wow! I'm also really impressed that workflow actions are working! This is really exciting.
So, it ran all the make builds yet it didn't retrieve anything, so what did it do?

edit: note to self this is a nice starting place for git actions.

edit2: BTW, I was looking at the workflow and wondering if it wouldn't be better to split each build flavour into separate jobs so that they can run in parallel...

@omarcostahamido
Copy link
Contributor Author

Hey @shakfu
Plot Twist!
I just ran xcode-select --install and it... started installing command line tools!? I don't understand this... I remember installing it before. And also, when I openned xcode to inspect preferences > locations it showed:
Screen Shot 2022-04-03 at 6 35 20 PM

So, after installing command line tools (again?) I'm now trying again make test-vanilla-exton dev branch:
vanilla-ext.log

I reckon which pkg-config still returns nada. So, you'll probably still find the conflict there around pkg-config?

@shakfu
Copy link
Owner

shakfu commented Apr 3, 2022

Hi @omarcostahamido,

if I run which pkg-config it doesn't return a thing, so it is safe to say that it is MIA. But why?

One thing for sure is that it isn't on your system, but it's also the case that it isn't installed by default by Xcode tools, so it may not even be required. I was hoping that an update to xcode-select tools would have have installed some missing dependencies. But it looks like you are still having issues.

Another option would be to install the homebrew base system (without installing homebrew python) which might help. In fact all of the macos build environments used by GitHub have homebrew installed (see macos-10.15 and macos-11

Also, wow! I'm also really impressed that workflow actions are working! This is really exciting.
So, it ran all the make builds yet it didn't retrieve anything, so what did it do?

I'm still getting comfortable with the GitHub workflows and actions. I figured out how to cache and how to make available the externals at the end of a run, but I doubt these are usable until they are codesigned and notarized. This is possible but I haven't gotten round to it yet.

My current plan after trying a bunch of different configurations is to only use matrix-based multi-os and multi-python-version 'matrix'-based workflows for testing (without trying to collect the produced externals and linked python distributions). It's too complex to do this, and it isn't necessary to have one solution which fits all cases.

I am now testing a model which envisions one workflow per variant (using a simple matrix build to generate a package for each python versions). This can be extended in the future with an os dimension (for windows and arm64 architectures) to generate a package for os / python-version or even forgot about python-versions and just do iterate over os cases.

Incidentally, Github workflows don't actually support compiling on arm64 for macos yet.. so I can't use this system to test for apple silicon compatibility.

I think this will come though. Mostly, likely both GitHub (microsoft) and Apple have an interest in seeing this being made possible.

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

In fact all of the macos build environments used by GitHub have homebrew installed (see macos-10.15 and macos-11

You always finding a way to rope me back into homebrew... haha

It's too complex to do this, and it isn't necessary to have one solution which fits all cases.
I am now testing a model which envisions one workflow per variant (using a simple matrix build to generate a package for each python versions). This can be extended in the future with an os dimension (for windows and arm64 architectures) to generate a package for os / python-version or even forgot about python-versions and just do iterate over os cases.

I'd say your current goal is already pretty ambitious, but I like it!

Incidentally, Github workflows don't actually support compiling on arm64 for macos yet

So... you can focus on Windows first! Great! *wink

@shakfu
Copy link
Owner

shakfu commented Apr 7, 2022

Hi @omarcostahamido

Just fyi, I've implemented on-demand build (select any version of python3.7 to 3.10), with signing and notarization using GitHub workflows and actions. The workflow in question is called pyjs_builder and its implemented in pyjs_generic.yml

There's a caveat though, for *-pkg variants, the python framework or relocatable distribution that sites in the support folder isn't currently codesigned or notarized in this process (just the externals). Ideally they can codesigned and then notarized inside a .dmg but this isn't implemented by any GitHub action so far.. I could potentially do this manually, but I'd rather wait until there's an official GitHub action that does, which is inevitable.

Incidentally, I've been thinking that this extremely long exchange around one issue which you started. This has been great in many ways, but I think because of its length, it is perhaps not helpful for newbies who may get put off by the length and variety of topics discussed. It's probably better to close this and open up a bunch of topical issues which are shorter and more to the point. We can maybe have another issue called general development ideas or something for more general discussions and other one for for updates...

I have a couple more things I'd like to finish before trying to solve the compatibility problem (apple silicon or windows), namely producing a 'tiny' python3 external: I have it down to 8.8MB now, I want to keep going and see how far I can go before it becomes useless 😄

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

Congrats on pulling this off. And just like that I learned about actions artifacts, a neat way to store the output of running an action without having to make a release.

There's a caveat though, for *-pkg variants (...) Ideally they can codesigned and then notarized inside a .dmg

Are the pkg variants compiling a .dmg now? Or are you saying that packaging them in a dmg is the only way to notarize them? How does it differs from how it works now?

I've also been meaning to ask: in this table you mention that pkg variants have pip, but how do you actually use pip there? Is it possible to request a release asset?

Incidentally, I've been thinking that this extremely long exchange around one issue which you started. This has been great in many ways, but I think because of its length, it is perhaps not helpful for newbies who may get put off by the length and variety of topics discussed. It's probably better to close this and open up a bunch of topical issues which are shorter and more to the point. We can maybe have another issue called general development ideas or something for more general discussions and other one for for updates...

I agree. It is surely one of the longest github issue threads I've been on. And I'll remember it very dearly haha. So, if you must, please close this issue. It's been a great pleasure to have this open 1-on-1 conversation with you, Shakeeb.

I have a couple more things I'd like to finish before trying to solve the compatibility problem (apple silicon or windows),

Ha! One last thing, this reminded me of what you said previously:

Incidentally, Github workflows don't actually support compiling on arm64 for macos yet..

Since you moved sdk 8.2, shouldn't it be possible to compile a m1 compatible external on an intel-based mac? I'm pretty sure I've heard/read somewhere that is a thing.

@shakfu
Copy link
Owner

shakfu commented Apr 10, 2022

Hi @omarcostahamido

Let's conclude this thread with some good news.

There's a caveat though, for *-pkg variants, the python framework or relocatable distribution that sits in the support folder isn't currently codesigned or notarized in this process (just the externals). Ideally they can codesigned and then notarized inside a .dmg

Good news! This is now resolved, and one can generate on-demand both forms (self-contained externals and externals which depend on a Python.framework in the support folder of a package) from a GitHub action. Now you can select your variant, your python version, and then you have an artifact (a .zip archive) of a .dmg which is fully codesigned and notarized and which contains the py-js directory with externals and supporting patches and frameworks..

There was a hiccup along the way which prevented me from reporting this good news earlier, it seems that the shared-pkg format used in shared-pkg and homebrew-pkg is not a valid form that is acceptable to Apple's notarization algorithms (they only accept .frameworks). This was not a big problem and it just took a little bit to convert homebrew-pkg to .framework. shared-pkg itself is now not used (but the code still hasn't been deleted in case it proves useful for another platform).

I've also been meaning to ask: in this table you mention that pkg variants have pip, but how do you actually use pip there? Is it possible to request a release asset?

relocatable-pkg on its own includes pip by default. So you can just generate it using a GitHub action, and then when you are in the support directory of the package:

cd support
Python.framework/Versions/3.9/bin/pip3 install <something>

or since, you asked, I have uploaded the above and put it into 0.1 release section as a pre-release: py-js-relocatable-pkg-darwin-x86-3.9-5e7754b.zip

Since you moved sdk 8.2, shouldn't it be possible to compile a m1 compatible external on an intel-based mac? I'm pretty sure I've heard/read somewhere that is a thing.

I don't think i can do that on my intel mac running Xcode 12 on Catalina. No matter, I do have an M1 MacBook air which should help going forward.

@omarcostahamido
Copy link
Contributor Author

omarcostahamido commented Apr 10, 2022

Hi @shakfu

Great news indeed!

I very eagerly downloaded the py-js-relocatable-pkg-darwin asset and copied over the externals and support folder from the dmg file. When trying to install anything, though, I am faced with:

$  Versions/3.9/bin/pip3 install termcolor
Collecting termcolor
  Using cached termcolor-1.1.0.tar.gz (3.9 kB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error
  
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [1 lines of output]
      ERROR: Can not execute `setup.py` since setuptools is not available in the build environment.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

edit: and for the record

$  Versions/3.9/bin/pip3 list
Package    Version
---------- -------
pip        22.0.4
setuptools 58.1.0
wheel      0.37.1

@shakfu
Copy link
Owner

shakfu commented Apr 10, 2022

Hi @omarcostahamido

Preparing metadata (setup.py) ... error

That's what you get for playing with a pre-release 😄

Ok, before I uploaded it, I pip installed numpy and it worked without issues. I was sufficiently impressed that I did not further testing.

It seems I may need to reduce the aggression on the shrinking I apply to relocatable: I was able to upgrade pip via pip3 install --upgrade pip and also upgrade setuptools via pip3 install --upgrade setuptools successfully. But then I got an error with termcolor (even though it was installed) related to ctypes which I have removed as part of my shrinking process. Strangely ctypes is not invoked in term color, so I suspected it's more to do with setuptools. I ran a dependency scan and it looks like setup tools does indeed invoke ctypes:

setuptool-ctypes

So that's the mystery of termcolor, or rather of setup tools needing ctypes which was removed.....By the way termcolor has no place in a python3 embedded in Max!!

I think the moral of the story is to release some kind of vanilla-relocatable-pkg which has minimal shrinking steps and maximum compatibility.

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

By the way termcolor has no place in a python3 embedded in Max!!

yes, I know 😄 I just tried to install a couple different small python packages and they all failed with that same message.

@shakfu
Copy link
Owner

shakfu commented Apr 10, 2022

Hi @omarcostahamido

I have a fix for pip-bug in relocatable-pkg which I have just pushed. You can now even install termcolor without issues! Looks like it was due to the removal of ctypes after all -- a pretty weird dependency for an interpreted language!

Again, it's in the 0.1 release section under py-js-relocatable-pkg-darwin-x86-3.9-688a4ba.zip

Hoping this one actually works for you.

@omarcostahamido
Copy link
Contributor Author

Hi @shakfu

Looks like it was due to the removal of ctypes after all -- a pretty weird dependency for an interpreted language!

haha 😆

Ok, let's see the new version:
Oh no...

$  Versions/3.9/bin/pip3 install pitchtools
Collecting pitchtools
  Using cached pitchtools-1.5.tar.gz (13 kB)
  Preparing metadata (setup.py) ... done
Building wheels for collected packages: pitchtools
  Building wheel for pitchtools (setup.py) ... done
  Created wheel for pitchtools: filename=pitchtools-1.5-py3-none-any.whl size=13087 sha256=64f64ce7d0a4b823f23106f9e817eb27a42b808933a34f7d002b43b197741140
  Stored in directory: /Users/omar/Library/Caches/pip/wheels/41/0d/56/c63ebf95e73004298965bf0eda2add8441b22b1ad55c8cd8ff
Successfully built pitchtools
Installing collected packages: pitchtools
Successfully installed pitchtools-1.5

It worked! 🎉

I'm a bit sad to say it, but this probably means that this thread is coming to a close, as you've completely addressed (in more ways than anyone could have anticipated) all the issues from the original post. This ability to work with the external packages was indeed the last point on that post!

So, I'm gonna miss our interactions here (*) but you should feel free to close this issue now.
And pat yourself on the back: you did it!

Thank you so much. It's been a pleasure.

OCH

(*) unless you keep tagging me somewhere else to share some good news about this project 😄

@shakfu
Copy link
Owner

shakfu commented Apr 11, 2022

@omarcostahamido

That's great, Omar. I'm pleased it finally worked for you. Thank you very much for your feedback throughout. Tt definitely spurred me forward, and kept me on my toes 😄

@shakfu shakfu closed this as completed Apr 11, 2022
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

2 participants