开源软件名称(OpenSource Name):phusion/traveling-ruby开源软件地址(OpenSource Url):https://github.com/phusion/traveling-ruby开源编程语言(OpenSource Language):Shell 85.7%开源软件介绍(OpenSource Introduction):Traveling Ruby: self-contained, portable Ruby binariesTraveling Ruby is a project which supplies self-contained, "portable" Ruby binaries: Ruby binaries that can run on any Linux distribution and any macOS machine. It also has Windows support (with some caveats). This allows Ruby app developers to bundle these binaries with their Ruby app, so that they can distribute a single package to end users, without needing end users to first install Ruby or gems. Introduction in 2 minutes MotivationRuby is one of our favorite programming languages. Most people use it for web development, but Ruby is so much more. I've been using Ruby for years for writing sysadmin automation scripts, developer command line tools and more. Heroku's Toolbelt and Chef have also demonstrated that Ruby is an excellent language for these sorts of things. However, distributing such Ruby apps to inexperienced end users or non-Ruby-programmer end users is problematic. If users have to install Ruby first, or if they have to use RubyGems, they can easily run into problems. Even if they already have Ruby installed, they can still run into problems, e.g. by having the wrong Ruby version installed. The point is, it's a very real problem that could harm your reputation. One solution is to build OS-specific installation packages, e.g. DEBs, RPMs, .pkgs, etc. However, this has two disadvantages:
This is exactly the approach that Chef has chosen. They built Omnibus, an automation system which spawns an army of VMs for building platform-specific packages. It works, but it's heavyweight and a big hassle. You need a big build machine for that if you want to have reasonable build time. And be prepared to make 20 cups of coffee. But there is another — much simpler — solution. Way of the Traveling RubyThe solution that Traveling Ruby advocates, is to distribute your app as a single self-contained tar.gz/zip package that already includes a precompiled Ruby interpreter for a specific platform (that the Traveling Ruby project provides), as well as all gems that your app depends on. This eliminates the need for heavyweight tooling:
This makes the release process much simpler. Instead of having to create almost 10 packages using a fleet of VMs, you just create 3 packages quickly and easily from your developer laptop. These 3 packages cover all the major platforms that your end users are on:
However, distributing a precompiled Ruby interpreter that works for all end users, is more easily said than done. Read this section to learn why it's difficult. Traveling Ruby aims to solve the problem of supplying precompiled Ruby 2.4 binaries that work for all end users. Getting startedBegin with the tutorials:
Once you've finished the tutorials, read the guides for intermediate to advanced topics: There are also some real-world examples of how people used Traveling Ruby to package their Ruby tools:
CaveatsNative extensions:
Windows support:
Building binariesThe Traveling Ruby project supplies binaries that application developers can use. These binaries are built using the build systems in this repository. As an application developer, you do not have to use the build system. You only have to use the build systems when contributing to Traveling Ruby, when trying to reproduce our binaries, or when you want to customize the binaries. For the Linux build system, see linux/README.md. For the macOS build system, see osx/README.md. Future work
FAQWhy it is difficult to supply a precompiled Ruby interpreter that works for all end users?Chances are that you think that you can compile a Ruby binary on a certain OS, and that users using that same OS can use your Ruby binary. Not quite. Not even when they run the same OS version as you do. Basically, there are two problems that can prevent a binary from working on another system:
Assuming that your binary doesn't use any libraries besides the C standard library, binaries compiled on a newer Linux system usually do not work on an older Linux system, even if you do not use newer APIs. This is because of glibc symbols. Each function in glibc - or symbol as C/C++ programmers call it - actually has multiple versions. This allows the glibc developers to change the behavior of a function without breaking backwards compatibility with apps that happen to rely on bugs or implementation-specific behavior. During the linking phase, the linker "helpfully" links against the most recent version of the symbol. The thing is, glibc introduces new symbol versions very often, resulting in binaries that will most likely depend on a recent glibc. There is no way to tell the compiler and linker to use older symbol versions unless you want to manually specify the version for each and every symbol, which is an undoable task. The only sane way to get around the glibc symbol problem, and to prevent accidental linking to unwanted libraries, is to create a tightly controlled build environment. On Linux, this build environment with come with an old glibc version. This tightly controlled build environment is sometimes called a "holy build box". The Traveling Ruby project provides such a holy build box. Why not just statically link the Ruby binary?First of all: easier said than done. The compiler prefers to link to dynamic libraries. You have to hand-edit lots of Makefiles to make everything properly link statically. You can't just add Second: Ruby is incompatible with static linking. On Linux systems, executables which are statically linked to the C library cannot dynamically load shared libraries. Yet Ruby extensions are shared libraries, and a Ruby interpreter that cannot load Ruby extensions is heavily crippled. So in Traveling Ruby we've taken a different approach. Our Ruby binaries are dynamically linked against the C library, but only uses old symbols to avoid glibc symbol problems. We also ship carefully-compiled versions of dependent shared libraries, like OpenSSL, ncurses, libedit, etc. Why is it problematic for end users if I don't bundle a Ruby interpreter?First of all, users just want to run your app as quickly as possible. Requiring them to install Ruby first is not only a distraction, but it can also cause problems. Here are a few examples of such problems:
One way to solve this is for you to "hold the user's hand", by going through the trouble of supplying 4 or 5 different platform-specific installation instructions for installing Ruby. These instructions must be continuously kept up-to-date. That's a lot of work and QA on your part, and I'm sure you just want to concentrate on building your app. And let's for the sake of argument suppose that the user somehow has Ruby correctly installed. They still need to install your app. The most obvious way to do that is through RubyGems. But that will open a whole new can of worms:
The point is, there's a lot of opportunity for end users to get stuck, confused and frustrated. You can deal with all these problems by supplying excellent documentation that handles all of these cases (and probably more, because there are infinite ways to break things). That's exactly what we've done for Phusion Passenger. Our RubyGems installation instructions spell out exactly how to install Ruby for each of the major operating systems, how to find out whether they need to run Or you can just use Traveling Ruby and be done with it. We can't do it for Phusion Passenger because by its very nature it has to work with an already-installed Ruby, but maybe you can for writing your next command line tool. The problems sound hypothetical. Is it really that big of a deal for end users?Yes. These problems can put off your users from installing your app at all and can give you a bad reputation. Especially Chef has suffered a lot from this. A lot of people have had bad experience in the past with installing Chef through RubyGems. Chef has solved this problem for years by supplying platform-specific packages for years (DEBs, RPMs, etc), but the reputation stuck: there are still people out there who shun Chef because they think they have to install Ruby and use RubyGems. I target macOS, which already ships Ruby. Should I still bundle a Ruby interpreter?Yes. Different macOS versions ship different Ruby versions. There can be significant compatibility differences between even minor Ruby versions. One of the biggest issues is the keyword argument changes introduced in Ruby 2.7 and later. Only by bundling Ruby can you be sure that OS upgrades won't break your app. Does Traveling Ruby support Windows?How big is a hello world packaged with Traveling Ruby?It's about 6 MB compressed. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论