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

Should be easier to use, with dependencies from Homebrew and mimic build conf. Documentation enabled by default. #190

Closed
wants to merge 2 commits into from

Conversation

seivan
Copy link

@seivan seivan commented Mar 14, 2021

This will allow asdf-erlang & asdf-elixir to be used out of the box and be much easier for majority of macOS users.
Avoiding using esotoric configuration and environment variables to keep track for various plugins should be a focus.

So, at least for macOS users asdf-erlang should try to use as much as possible from Homebrew for building, with sane configuration defaults (mimic Homebrew) and make documentation enabled by default

  • Will use existing kerl from $PATH (like installed by Homebrew) or fetch specific version when setting ASDF_KERL_VERSION.

  • Will use git to clone kerl quitly and checkout versioned tags instead of downloading from Github CDN.

  • Enable shell docs out of the box by default and allow opt out using KERL_BUILD_DOCS="no" - technically any value will opt out, kerl just checks if it's set, and not its value. Since we're opting in by default, we will check != "yes" for opt out.

  • Will enable prebuilt binaries for macOS supporting (supported versions of Erlang will of course vary)

    • Yosemite
    • El Capitan
    • Sierra
    • High Sierra
    • Mojave
    • Catalina
    • Big Sur
    • ARM Big Sur

This allows installing Erlang in matter of seconds versus 10 minutes on slower machines.
Can optout of prebuilt binaries for macOS with ASDF_ERLANG_FROM_SOURCE=YES
These will also opt out:

  • ASDF_INSTALL_TYPE="ref"
  • KERL_CONFIGURE_OPTIONS
  • OTP_GITHUB_URL

Failing to find proper binaries will default to installing from source.

  • No longer symlinks binaries from globs, instead added a list-bin-paths that outputs all the directories with binaries. Preferably this should have been handled by asdf itself, but will have to do for now.

  • Will come with out of the box settings for KERL_CONFIGURE_OPTIONS:

    • --disable-debug
    • --disable-silent-rules
    • --enable-dynamic-ssl-lib
    • --enable-hipe
    • --enable-sctp
    • --enable-shared-zlib
    • --enable-smp-support
    • --enable-threads
    • --enable-wx
    • --without-javac
    • macOS only:
      • --with-ssl=$(brew --prefix openssl)
      • --enable-darwin-64bit
      • --enable-kernel-poll
      • --with-dynamic-trace=dtrace
  • macOS only: Unless custom KERL_CONFIGURE_OPTIONS, asdf-erlang will default to using Homebrew for following dependencies:

    • openssl
    • wxmac
    • Building from source:
      • autoconf
      • libtool

Keep in mind, this treats KERL_BASE_DIR and kerlc as ephemeral by keeping it in all in tmp.
You can override this by setting ASDF_KERL_BASE_DIR and it will set KERL_CONFIG=$ASDF_KERL_BASE_DIR/.kerlc

That being said, as a user of asdf-erlang, I'd assume you're not really opting to interact with it by default. So it would make sense to treat it as ephemeral resource more than a configuration to keep around.

Using default KERL_CONFIGURE_OPTIONS if unset.
For macOS this contains additional checks, where it depends on Homebrew and packages installed by it.

So if a macOS user wants to opt out of dependencies used by Homebrew, they would need to set their own KERL_CONFIGURE_OPTIONS.

This is similar to changes in asdf-vm/asdf-ruby#205 I am trying to keep the logic and folder organization the same, since I'm maintaining both of these forks for myself, hence moving utils.sh out to lib/utils.sh, also it feels cleaner not to have non-asdf commands under bin/

@seivan seivan force-pushed the feature/better_defaults branch 2 times, most recently from 6b7e67c to 2083bbc Compare March 14, 2021 21:25
@seivan seivan changed the title asdf-erlang should be easier to use, with documentation enabled by default. Should be easier to use, use dependencies from Homebrew and mimic build conf. Documentation enabled by default. Mar 14, 2021
@seivan seivan force-pushed the feature/better_defaults branch 2 times, most recently from 68ba649 to c258e08 Compare March 14, 2021 21:31
@seivan seivan changed the title Should be easier to use, use dependencies from Homebrew and mimic build conf. Documentation enabled by default. Should be easier to use, with dependencies from Homebrew and mimic build conf. Documentation enabled by default. Mar 14, 2021
@seivan
Copy link
Author

seivan commented Mar 16, 2021

I think your CI is broken.
The macOS from source one fails because wxmac requirement which should be standard for macOS and the Linux one fails for some other reason even though the installation succeeded.
https://travis-ci.org/github/asdf-vm/asdf-erlang/jobs/762870648#L132

I've tested this locally and it works better than current implementation for macOS, Linux should be the same as it was before.

Copy link

@wojtekmach wojtekmach left a comment

Choose a reason for hiding this comment

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

This is great, I'm really looking forward to having this in asdf-erlang.

lib/utils.sh Show resolved Hide resolved
bin/install Outdated Show resolved Hide resolved
seivan added a commit to seivan/asdf-erlang that referenced this pull request Mar 28, 2021
seivan added a commit to seivan/asdf-erlang that referenced this pull request Mar 29, 2021
Just for testing purposes.
@wojtekmach
Copy link

We're gonna have to do similar workaround for wx, I got this error:

~/.asdf/installs/erlang/23.3/bin/erl
Erlang/OTP 23 [erts-11.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [dtrace]

Eshell V11.2  (abort with ^G)
1> observer:start().
=ERROR REPORT==== 30-Mar-2021::15:54:59.777145 ===
WX Failed loading "wxe_driver"@"/Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv"

{error,{{load_driver,"dlopen(/Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv/wxe_driver.so, 2): Library not loaded: @@HOMEBREW_PREFIX@@/opt/wxmac/lib/libwx_osx_cocoau_stc-3.0.dylib\n  Referenced from: /Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv/wxe_driver.so\n  Reason: image not found"},
        [{wxe_server,start,1,[{file,"wxe_server.erl"},{line,65}]},
         {wx,new,1,[{file,"wx.erl"},{line,115}]},
         {observer_wx,init,1,[{file,"observer_wx.erl"},{line,107}]},
         {wx_object,init_it,6,[{file,"wx_object.erl"},{line,404}]},
         {proc_lib,init_p_do_apply,3,
                   [{file,"proc_lib.erl"},{line,226}]}]}}

@seivan
Copy link
Author

seivan commented Mar 30, 2021

We're gonna have to do similar workaround for wx, I got this error:

~/.asdf/installs/erlang/23.3/bin/erl
Erlang/OTP 23 [erts-11.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [dtrace]

Eshell V11.2  (abort with ^G)
1> observer:start().
=ERROR REPORT==== 30-Mar-2021::15:54:59.777145 ===
WX Failed loading "wxe_driver"@"/Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv"

{error,{{load_driver,"dlopen(/Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv/wxe_driver.so, 2): Library not loaded: @@HOMEBREW_PREFIX@@/opt/wxmac/lib/libwx_osx_cocoau_stc-3.0.dylib\n  Referenced from: /Users/wojtek/.asdf/installs/erlang/23.3/lib/wx-1.9.3/priv/wxe_driver.so\n  Reason: image not found"},
        [{wxe_server,start,1,[{file,"wxe_server.erl"},{line,65}]},
         {wx,new,1,[{file,"wx.erl"},{line,115}]},
         {observer_wx,init,1,[{file,"observer_wx.erl"},{line,107}]},
         {wx_object,init_it,6,[{file,"wx_object.erl"},{line,404}]},
         {proc_lib,init_p_do_apply,3,
                   [{file,"proc_lib.erl"},{line,226}]}]}}

That's odd though, because that worked fine for me, crypto didn't until we changed linker flags, but :observer.start works as of now, and I didn't think it was dynamically linked either. Do you have any laptop that runs Catalina or Big Sur on x64?

Just to make sure, you done brew install wxmac?

@wojtekmach
Copy link

Yes, I have wxmac installed through brew. And yeah I can test it on a x64 machine, I'll try it later today.

@seivan
Copy link
Author

seivan commented Mar 30, 2021

@wojtekmach I think I found why it worked for me.

otool -L priv/wxe_driver.so 
priv/wxe_driver.so:
	/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
	/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 162.0.0)
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 23.0.0)
	/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox (compatibility version 1.0.0, current version 1000.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
	/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)

You don't have those on ARM_big_sur, but x64 Big Sur does.

So if we're updating linker flags for wxmac, it should just be for ARM.

@seivan
Copy link
Author

seivan commented Mar 30, 2021

@wojtekmach Latest push will do this

Introducing macos_update_linked_path() that

  • Checks for @@HOMEBREW_PREFIX@@ on given paths - so far hardcoded to wxmac & crypto version-globs.
  • Runs otool -L to figure out what paths need to change.
  • Uses install_name_tool -change with $(brew --prefix)
  • Copies the file before running codesign because of bug
  • Moves file back.
  # Link Crypto to brew prefix
  macos_update_linked_path "$ASDF_DOWNLOAD_PATH/lib/erlang/lib/"crypto-*"/priv/lib/crypto.so"
  # Link Wxmac to brew prefix
  macos_update_linked_path "$ASDF_DOWNLOAD_PATH/lib/erlang/lib/"wx-*"/priv/wxe_driver.so"

Can make the paths given dynamic and recursive in the future if necessary but will be slower install since it would have to go through each binary and check linked flags. Maybe better if we can clear up what else needs to be linked - that being said it's pretty damn fast now with download and install under 15 seconds, that's 98% faster. :)

Anyway, I ran this on Catalina and it had no issues, so we'll just leave it in there for all macOS major versions, though I'm not sure if codesign and install_name_tool exists in older versions, if not, they won't need it anyway and we can skip those portions for older macOS.

@wojtekmach
Copy link

wojtekmach commented Mar 30, 2021

Great, I verified the latest changes and both crypto and observer is working for me well.

The output of all path updating and re-signing is quite verbose so my minor suggestion would be to print "Updating and re-signing shared libraries, set DEBUG=1 for full output" or something like that and otherwise hide the output. But I think it's totally fine to ship it as is, it's such a big improvement over compiling from source.

@seivan
Copy link
Author

seivan commented Mar 30, 2021

Great, I verified the latest changes and both crypto and observer is working for me well.

The output of all path updating and re-signing is quite verbose so my minor suggestion would be to print "Updating and re-signing shared libraries, set DEBUG=1 for full output" or something like that and otherwise hide the output. But I think it's totally fine to ship it as is, it's such a big improvement over compiling from source.

Yeah I agree, but they were inherently just for me to check, I'll check to see if ASDF as a debug var it uses and rely on that, otherwise I'll get rid of them.

I'm doing a small update to prepare for any future new binaries that need to change, so it could go straight to recursive checks if needed, but without implementing it now, give me a few minutes.

@seivan
Copy link
Author

seivan commented Mar 30, 2021

@wojtekmach
Ok so I removed a lot of logging.
Also , changed so we're only running install_name_tools once instead of looping over for each change.
This mean at most you should get two outputs

.asdf/downloads/erlang/23.3/lib/erlang/lib/crypto-4.9/priv/lib/crypto.so.backup: signed Mach-O thin (x86_64) [crypto.so]
.asdf/downloads/erlang/23.3/lib/erlang/lib/wx-1.9.3/priv/wxe_driver.so.backup: signed Mach-O thin (x86_64) [wxe_driver.so]

Ok, I think I'm done for now.
On my end, the only issue I had was Crypto, wxmac never needed any changes on my side, but even with new path updates and code sign it works.

@seivan
Copy link
Author

seivan commented Mar 30, 2021

@wojtekmach Are we done here?

@wojtekmach
Copy link

~% asdf install erlang 23.3
Looking for prebuilt erlang 23.3 on arm64_big_sur.
Checking Homebrew for dependencies.
Downloading https://bintray.com/homebrew/bottles/download_file?file_path=erlang-23.3.arm64_big_sur.bottle.tar.gz.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  101M  100  101M    0     0  31.8M      0  0:00:03  0:00:03 --:--:-- 50.0M
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: warning: changes being made to the file will invalidate the code signature in: /Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/crypto-4.9/priv/lib/crypto.so
/Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/crypto-4.9/priv/lib/crypto.so.backup: replacing existing signature
/Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/crypto-4.9/priv/lib/crypto.so.backup: signed Mach-O thin (arm64) [crypto.so]
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: warning: changes being made to the file will invalidate the code signature in: /Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/wx-1.9.3/priv/wxe_driver.so
/Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/wx-1.9.3/priv/wxe_driver.so.backup: replacing existing signature
/Users/wojtek/.asdf/downloads/erlang/23.3/lib/erlang/lib/wx-1.9.3/priv/wxe_driver.so.backup: signed Mach-O thin (arm64) [wxe_driver.so]
~% ~/.asdf/installs/erlang/23.3/bin/erl
cryErlang/OTP 23 [erts-11.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [dtrace]

Eshell V11.2  (abort with ^G)
1> crypto:version().
"4.9"
2> observer:start().
ok

👍

… fetch specific version when setting `ASDF_KERL_VERSION`.

* Will use git to clone `kerl` quitly and checkout versioned tags instead of downloading from Github CDN.

* Enable shell docs out of the box by default and allow opt out using `KERL_BUILD_DOCS="no" - technically any value will opt out, kerl just checks if it's set, and not its value. Since we're opting in by default, we will check `!= "yes"` for opt out.

* Will come with out of the box settings for `KERL_CONFIGURE_OPTIONS` with additional settings for macOS that matches `Homebrew`
	* `--disable-debug`
	* `--disable-silent-rules`
	* `--enable-dynamic-ssl-lib`
	* `--enable-hipe`
	* `--enable-sctp`
	* `--enable-shared-zlib`
	* `--enable-smp-support`
	* `--enable-threads`
	* `--enable-wx`
	* `--without-javac`
	* macOS only:
		* `--with-ssl=$(brew --prefix openssl)`
		* `--enable-darwin-64bit`
		* `--enable-kernel-poll`
		* `--with-dynamic-trace=dtrace`

* macOS only: Unless custom `KERL_CONFIGURE_OPTIONS`, asdf-erlang will default to using Homebrew for following dependencies:
	- `autoconf`
 	- `libtool`
 	- `openssl`
 	- `wxmac`

This will allow `asdf-erlang` & `asdf-elixir` to be used out of the box and be much easier for majority of macOS users.
Avoiding using esotoric configuration and environment variables to keep track for various plugins should be a focus.
Allowing someone to just put a plugin in, and pick a version without sifting through massive documentation and configuration is beneficial.
@seivan seivan force-pushed the feature/better_defaults branch 3 times, most recently from b451201 to de8c070 Compare March 31, 2021 07:12
…RCE=YES.

Removed uninstall, asdf current uninstall will suffice.
Added list-bin-paths so we can skip symlinking glob dirs.
ASDF should preferably handle globs, it sorta does it for checking executables, but not when creating shims.
@seivan seivan closed this Apr 2, 2021
@seivan seivan deleted the feature/better_defaults branch April 2, 2021 03:28
@wojtekmach
Copy link

@seivan what happened? :)

@seivan seivan restored the feature/better_defaults branch April 6, 2021 12:21
@seivan
Copy link
Author

seivan commented Apr 6, 2021

@wojtekmach
TLDR; I am no longer using main asdf. I appreciate your help and feedback!
I restored the branch if you need it.

I am doing prebuilt (macOS) support for more languages, and a lot of this logic would do better outside of the plugins.
Went from copying code, to using submodules and eventually settled on setting the logic outside of plugins for prebuilts to use on other languages like Ruby, Node, & etc.

@wojtekmach
Copy link

wojtekmach commented Apr 6, 2021

Out of curiosity, by keeping logic outside of the plugins you mean inside asdf core or outside asdf? In any case, I and I'm sure many people really appreciate your effort and showing the way to implement this, thank you!

@seivan
Copy link
Author

seivan commented Apr 6, 2021

Out of curiosity, by keeping logic outside of the plugins you mean inside asdf core or outside asdf?

That's the part that bothers me, so right now it's a submodule used by ruby, node and erlang.
It has a lot shared components to curl tarballs, extract, replace linked libs, replace code sign and etc.

Core does not afaik(!) know deal with submodules, and I'm on the fence wether or not it's a bad idea, but that's the approach I am going with now.

There's also silly util functions like getting plugin dir, check for necessary dependencies and (for macOS) offer an approach to fetch them -using using Homebrew. Similar to how ruby-install does it.

In any case, I and I'm sure many people really appreciate your effort and showing the way to implement this, thank you!

We'll see when it's done and I can I can show it.

So far all three languages work fine, even Ruby's quirk of hard coding gem loading paths in the binary (based on Brew), by using exec-env it can be pointed to the right path but right now it's hard-coded for macOS.

It will remain hard-coded for macOS as that's the only platform I support for pre-built as of today, but will obviously check it's macOS before doing so later on.

There's a lot of inertia and low hanging fruit here.

@wojtekmach
Copy link

Gotcha, makes sense to share the behaviour somehow so that plugins can easily use it.

@Stratus3D
Copy link
Member

@seivan @wojtekmach I am applying some of these changes in #276. The main Homebrew changes here won't be accepted - at least for now - but I figured I'd let you know some of this is going to end up in master.

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

Successfully merging this pull request may close these issues.

None yet

3 participants