Difference between pages "Bash by Example, Part 3" and "Web Browsers"

(Difference between pages)
m
 
(Disadvantages)
 
Line 1: Line 1:
{{Article
+
Funtoo Linux offers a number of possibilities when it comes to Web browsers. This page is intended to give you an overview of what is available, their various trade-offs, and also provide tutorial-style instructions on how to set them up so they offer full functionality. Additionally, instructions are provided on how to set up the Oracle Java Runtime Environment for running Java applets.
|Subtitle=Exploring the ebuild system
+
|Summary=Few people know that the original version of Portage was an evolution of a simple script that I wrote for a bash tutorial. Here's the article that contains the first version of ebuild! Learn how to script by creating a minimal build script.
+
|Author=Drobbins
+
|Previous in Series=Bash by Example, Part 2
+
}}
+
=== Enter the ebuild system ===
+
I've really been looking forward to this third and final ''Bash by example'' article, because now that we've already covered bash programming fundamentals in [[Bash by example, Part1|Part 1]] and [[Bash by example, Part 2|Part 2]], we can focus on more advanced topics, like bash application development and program design. For this article, I will give you a good dose of practical, real-world bash development experience by presenting a project that I've spent many hours coding and refining: the Gentoo Linux ebuild system.
+
  
As the creator of Gentoo Linux and the guy behind Funtoo Linux, one of my primary responsibilities is to make sure that all of the operating system packages (similar to RPM packages) are created properly and work together. As you probably know, a standard Linux system is not composed of a single unified source tree (like BSD), but is actually made up of about 25+ (As of 2015, over 100! -Ed) core packages that work together. Some of the packages include:
+
==== Prerequisites ====
  
{{TableStart}}
+
Before installing a Web browser, ensure that you have a functioning X environment or desktop environment set up.
<tr><td class="active">Package</td><td class="active">Description</td></tr>
+
<tr><td>linux</td><td>The actual kernel</td></tr>
+
<tr><td>util-linux</td><td>A collection of miscellaneous Linux-related programs</td></tr>
+
<tr><td>e2fsprogs</td><td>A collection of ext2 filesystem-related utilities</td></tr>
+
<tr><td>glibc</td><td>The GNU C library</td></tr>
+
{{TableEnd}}
+
  
{{Note|Gentoo fans: the original text above used to say "I'm the chief architect of Gentoo Linux, a next-generation Linux OS currently in beta. One of my primary responsibilities is to make sure that all of the binary packages (similar to RPM packages) are created properly and work together." This is noteworthy due to the fact that the initial focus of Gentoo was to provide working binary packages.}}
+
== Google Chrome (binary) ==
  
Each package is in its own tarball and is maintained by separate independent developers, or teams of developers. To create a distribution, each package has to be separately downloaded, compiled, and packaged. Every time a package must be fixed, upgraded, or improved, the compilation and packaging steps must be repeated (and this gets old really fast). To help eliminate the repetitive steps involved in creating and updating packages, I created the ebuild system, written almost entirely in bash. To enhance your bash knowledge, I'll show you how I implemented the unpack and compile portions of the ebuild system, step by step. As I explain each step, I'll also discuss why certain design decisions were made. By the end of this article, not only will you have an excellent grasp of larger-scale bash programming projects, but you'll also have implemented a good portion of a complete auto-build system.
+
The Google Chrome (binary) ebuild is <tt>www-client/google-chrome</tt>. Google Chrome is a very good Web browser. This browser is a great option for those who want a full-featured browser up and running quickly without a lot of complication.
  
=== Why bash? ===
+
==== Advantages ====
Bash is an essential component of the Gentoo Linux ebuild system. It was chosen as ebuild's primary language for a number of reasons. First, it has an uncomplicated and familiar syntax that is especially well suited for calling external programs. An auto-build system is "glue code" that automates the calling of external programs, and bash is very well suited to this type of application. Second, Bash's support for functions allowed the ebuild system to have modular, easy-to-understand code. Third, the ebuild system takes advantage of bash's support for environment variables, allowing package maintainers and developers to configure it easily, on-the-fly.
+
  
=== Build process review ===
+
* It's very fast to install, because it does not need to be built from source.  
Before we look at the ebuild system, let's review what's involved in getting a package compiled and installed. For our example, we will look at the "sed" package, a standard GNU text stream editing utility that is part of all Linux distributions. First, download the source tarball ('''sed-3.02.tar.gz''') (see [[#Resources|Resources]]). We will store this archive in '''/usr/src/distfiles''', a directory we will refer to using the environment variable <span style="color:green">$DISTDIR</span>. <span style="color:green">$DISTDIR</span> is the directory where all of our original source tarballs live; it's a big vault of source code.
+
* It includes support for Adobe Flash and PDF viewing built-in, which works right away with no additional configuration.  
 +
* It works well with [[PulseAudio]] with no additional configuration required.
 +
* Overall, the browser looks fantastic and is very fast.
  
Our next step is to create a temporary directory called '''work''', which houses the uncompressed sources. We'll refer to this directory later using the <span style="color:green">$WORKDIR</span> environment variable. To do this, change to a directory where we have write permission and type the following:
+
==== Disadvantages ====
<source lang="bash">
+
$ mkdir work
+
$ cd work
+
$ tar xzf /usr/src/distfiles/sed-3.02.tar.gz
+
</source>
+
The tarball is then decompressed, creating a directory called '''sed-3.02''' that contains all of the sources. We'll refer to the '''sed-3.02''' directory later using the environment variable <span style="color:green">$SRCDIR</span>. To compile the program, type the following:
+
<source lang="bash">
+
$ cd sed-3.02
+
$ ./configure --prefix=/usr
+
(autoconf generates appropriate makefiles, this can take a while)
+
  
$ make
+
* Included Flash does not support Amazon Video on Demand, which requires older DRM support. See Firefox as an option for this.
 +
* It's based on a binary for Debian systems, and sometimes depends on outdated versions of ebuilds to run.
 +
* The stable Google build of Google Chrome (<tt>www-client/google-chrome</tt>) has a bug where the text in the address bar "wiggles" as you type. This is fixed in later versions, but not in the reliable "stable" binary that Google is currently shipping. If you are a perfectionist, having a browser that is so close to perfect but with this one fatal flaw will gnaw on your soul until you replace it with something else (like Chromium with the classic theme.)
  
(the package is compiled from sources, also takes a bit of time)
+
=== Google Chrome Installation ===
</source>
+
We're going to skip the "make install" step, since we are just covering the unpack and compile steps in this article. If we wanted to write a bash script to perform all these steps for us, it could look something like this:
+
<source lang="bash">
+
#!/usr/bin/env bash
+
  
if [ -d work ]
+
As root, you first need to accept the Google Chrome license, as follows:
then
+
# remove old work directory if it exists
+
      rm -rf work
+
fi
+
mkdir work
+
cd work
+
tar xzf /usr/src/distfiles/sed-3.02.tar.gz
+
cd sed-3.02
+
./configure --prefix=/usr
+
make
+
</source>
+
  
=== Generalizing the code ===
+
<console>
Although this autocompile script works, it's not very flexible. Basically, the bash script just contains the listing of all the commands that were typed at the command line. While this solution works, it would be nice to make a generic script that can be configured quickly to unpack and compile any package just by changing a few lines. That way, it's much less work for the package maintainer to add new packages to the distribution. Let's take a first stab at doing this by using lots of different environment variables, making our build script more generic:
+
# ##i##emerge google-chrome --autounmask-write
<source lang="bash">
+
</console>
#!/usr/bin/env bash
+
  
# P is the package name
+
Now, run <tt>etc-update</tt> and accept the changes made to <tt>/etc/portage/package.license</tt>. Now, emerge:
  
P=sed-3.02
+
<console>
 +
# ##i##emerge -a google-chrome
 +
</console>
  
# A is the archive name
+
== Chromium ==
  
A=${P}.tar.gz
+
Chromium (<tt>www-client/chromium</tt>) is the from-source version of Google Chrome, and is a very good option for people who like Google Chrome but who want to build from source. Like most modern Web browsers, it does take a '''very long''' time to build -- up to ''several hours'' on a dual-core system, and about an hour on a 4-6 core system.  
  
export ORIGDIR=`pwd`
+
After emerging, it requires a special helper package <tt>www-plugins/chrome-binary-plugins</tt> for Adobe Flash as well as PDF viewing support.
export WORKDIR=${ORIGDIR}/work
+
export SRCDIR=${WORKDIR}/${P}
+
  
if [ -z "$DISTDIR" ]
+
==== Advantages ====
then
+
# set DISTDIR to /usr/src/distfiles if not already set
+
        DISTDIR=/usr/src/distfiles
+
fi
+
export DISTDIR
+
  
if [ -d ${WORKDIR} ]
+
* It is built from source, so it has fewer issues with dependencies than Google Chrome, yet it is very similar in functionality.
then   
+
* It looks great, and works well.
# remove old work directory if it exists
+
* With an easy emerge of <tt>www-plugins/chrome-binary-plugins</tt>, it provides identical functionality to Chrome in regards to Adobe Flash and PDF support.
        rm -rf ${WORKDIR}
+
fi
+
  
mkdir ${WORKDIR}
+
==== Disadvantages ====
cd ${WORKDIR}
+
tar xzf ${DISTDIR}/${A}
+
cd ${SRCDIR}
+
./configure --prefix=/usr
+
make
+
</source>
+
We've added a lot of environment variables to the code, but it still does basically the same thing. However, now, to compile any standard GNU autoconf-based source tarball, we can simply copy this file to a new file (with an appropriate name to reflect the name of the new package it compiles), and then change the values of <span style"color:green:>$A</span> and <span style"color:green:>$P</span> to new values. All other environment variables automatically adjust to the correct settings, and the script works as expected. While this is handy, there's a further improvement that can be made to the code. This particular code is much longer than the original "transcript" script that we created. Since one of the goals for any programming project should be the reduction of complexity for the user, it would be nice to dramatically shrink the code, or at least organize it better. We can do this by performing a neat trick -- we'll split the code into two separate files. Save this file as '''sed-3.02.ebuild''':
+
<source lang="bash">
+
#the sed ebuild file -- very simple!
+
P=sed-3.02
+
A=${P}.tar.gz
+
</source>
+
Our first file is trivial, and contains only those environment variables that must be configured on a per-package basis. Here's the second file, which contains the brains of the operation. Save this one as "ebuild" and make it executable:
+
<source lang="bash">
+
#!/usr/bin/env bash
+
  
 +
* It takes a very long time to build, even on a modern system, so be prepared to wait.
  
if [ $# -ne 1 ]
+
=== Installing Chromium ===
then
+
        echo "one argument expected."
+
        exit 1
+
fi
+
  
if [ -e "$1" ]
+
To install Chromium, you will need to enable the <tt>minizip</tt> USE flag for <tt>sys-libs/zlib</tt>, and I also recommend enabling <tt>aura</tt> for Chromium itself, which is a new GPU-accelerated architecture. Add the following lines to  <tt>/etc/portage/package.use</tt>:
then
+
        source $1
+
else
+
        echo "ebuild file $1 not found."
+
        exit 1
+
fi
+
  
export ORIGDIR=`pwd`
+
<pre>
export WORKDIR=${ORIGDIR}/work
+
sys-libs/zlib minizip
export SRCDIR=${WORKDIR}/${P}
+
www-client/chromium aura
 +
</pre>
  
if [ -z "$DISTDIR" ]
+
Okay, now it's time to emerge Chromium:
then
+
        # set DISTDIR to /usr/src/distfiles if not already set
+
        DISTDIR=/usr/src/distfiles
+
fi
+
export DISTDIR
+
  
if [ -d ${WORKDIR} ]
+
<console>
then   
+
# ##i## emerge -a www-client/chromium
        # remove old work directory if it exists
+
</console>
        rm -rf ${WORKDIR}
+
fi
+
  
mkdir ${WORKDIR}
+
This will take a long time to complete. After you're done, emerge Chrome helper programs to enable Adobe Flash and PDF viewing support. First, review and accept the license:
cd ${WORKDIR}
+
tar xzf ${DISTDIR}/${A}
+
cd ${SRCDIR}
+
./configure --prefix=/usr
+
make
+
</source>
+
Now that we've split our build system into two files, I bet you're wondering how it works. Basically, to compile sed, type:
+
<source lang="bash">
+
$ ./ebuild sed-3.02.ebuild
+
</source>
+
When "ebuild" executes, it first tries to "source" variable <span style="color:green">$1</span>. What does this mean? From my previous article, recall that <span style="color:green">$1</span> is the first command line argument -- in this case, '''sed-3.02.ebuild'''. In bash, the "source" command reads in bash statements from a file, and executes them as if they appeared immediately in the file the "source" command is in. So, "source ${1}" causes the "ebuild" script to execute the commands in '''sed-3.02.ebuild''', which cause <span style="color:green">$P</span> and <span style="color:green">$A</span> to be defined. This design change is really handy, because if we want to compile another program instead of sed, we can simply create a new '''.ebuild''' file and pass it as an argument to our "ebuild" script. That way, the '''.ebuild''' files end up being really simple, while the complicated brains of the ebuild system get stored in one place -- our "ebuild" script. This way, we can upgrade or enhance the ebuild system simply by editing the "ebuild" script, keeping the implementation details outside of the ebuild files. Here's a sample ebuild file for <span style="color:green">gzip</span>:
+
<source lang="bash">
+
#another really simple ebuild script!
+
P=gzip-1.2.4a
+
A=${P}.tar.gz
+
</source>
+
  
=== Adding functionality ===
+
<console>
OK, we're making some progress. But, there is some additional functionality I'd like to add. I'd like the ebuild script to accept a second command-line argument, which will be <span style="color:green">compile</span>, <span style="color:green">unpack</span>, or <span style="color:green">all</span>. This second command-line argument tells the ebuild script which particular step of the build process to perform. That way, I can tell ebuild to unpack the archive, but not compile it (just in case I need to inspect the source archive before compilation begins). To do this, I'll add a case statement that will test variable <span style="color:green">$2</span>, and do different things based on its value. Here's what the code looks like now:
+
# ##i##emerge www-plugins/chrome-binary-plugins --autounmask-write
<source lang="bash">
+
</console>
#!/usr/bin/env bash
+
  
if [ $# -ne 2 ]
+
Now, run <tt>etc-update</tt> and accept the changes that it made to <tt>/etc/portage/package.license</tt>. Now, emerge the plugins for real:
then
+
        echo "Please specify two args - .ebuild file and unpack, compile or all"
+
        exit 1
+
fi
+
  
 +
<console>
 +
# ##i##emerge www-plugins/chrome-binary-plugins
 +
</console>
  
if [ -z "$DISTDIR" ]
+
=== Making Chromium Look Sexier ===
then
+
# set DISTDIR to /usr/src/distfiles if not already set
+
        DISTDIR=/usr/src/distfiles
+
fi
+
export DISTDIR
+
  
ebuild_unpack() {
+
If you like the default "blue" look of Chrome, and want Chromium to look like that, go to the "3 bar" menu in the upper right, go to '''Settings''', and under '''Appearance''', click  '''Use Classic theme'''. Flash some gang signs to imaginary onlookers, and you are done.
        #make sure we're in the right directory
+
        cd ${ORIGDIR}
+
       
+
        if [ -d ${WORKDIR} ]
+
        then   
+
                rm -rf ${WORKDIR}
+
        fi
+
  
        mkdir ${WORKDIR}
+
== Firefox (binary) ==
        cd ${WORKDIR}
+
        if [ ! -e ${DISTDIR}/${A} ]
+
        then
+
            echo "${DISTDIR}/${A} does not exist.  Please download first."
+
            exit 1
+
        fi   
+
        tar xzf ${DISTDIR}/${A}
+
        echo "Unpacked ${DISTDIR}/${A}."
+
        #source is now correctly unpacked
+
}
+
  
 +
The Firefox binary Web browser, <tt>www-client/firefox-bin</tt> is another good option. It is more feature-rich as opposed to the "lean and mean" Chrome/Chromium.
  
ebuild_compile() {
+
==== Advantages ====
       
+
        #make sure we're in the right directory
+
        cd ${SRCDIR}
+
        if [ ! -d "${SRCDIR}" ]
+
        then
+
                echo "${SRCDIR} does not exist -- please unpack first."
+
                exit 1
+
        fi
+
        ./configure --prefix=/usr
+
        make   
+
}
+
  
export ORIGDIR=`pwd`
+
* Firefox is a great, full-featured Web browser.
export WORKDIR=${ORIGDIR}/work
+
* It is quick to install, because it is a binary.
  
if [ -e "$1" ]
+
==== Disadvantages ====
then
+
        source $1
+
else
+
        echo "Ebuild file $1 not found."
+
        exit 1
+
fi
+
  
export SRCDIR=${WORKDIR}/${P}
+
* It works well with [[ALSA]] by default, but requires tweaks to get working with [[PulseAudio]].
 +
* A separate merge of <tt>www-plugins/adobe-flash</tt> is required for Adobe Flash support.
  
case "${2}" in
+
=== Installing Firefox ===
        unpack)
+
                ebuild_unpack
+
                ;;
+
        compile)
+
                ebuild_compile
+
                ;;
+
        all)
+
                ebuild_unpack
+
                ebuild_compile
+
                ;;
+
        *)
+
                echo "Please specify unpack, compile or all as the second arg"
+
                exit 1
+
                ;;
+
esac
+
</source>
+
We've made a lot of changes, so let's review them. First, we placed the compile and unpack steps in their own functions, and called <span style="color:green:>ebuild_compile()</span> and <span style="color:green">ebuild_unpack()</span>, respectively. This is a good move, since the code is getting more complicated, and the new functions provide some modularity, which helps to keep things organized. On the first line in each function, I explicitly <span style="color:green">cd</span> into the directory I want to be in because, as our code is becoming more modular rather than linear, it's more likely that we might slip up and execute a function in the wrong current working directory. The <span style="color:green">cd</span> commands explicitly put us in the right place, and prevent us from making a mistake later -- an important step -- especially if you will be deleting files inside the functions.
+
  
Also, I added a useful check to the beginning of the <span style="color:green">ebuild_compile()</span> function. Now, it checks to make sure the <span style="color:green">$SRCDIR</span> exists, and, if not, it prints an error message telling the user to unpack the archive first, and then exits. If you like, you can change this behavior so that if <span style="color:green">$SRCDIR</span> doesn't exist, our ebuild script will unpack the source archive automatically. You can do this by replacing <span style="color:green">ebuild_compile()</span> with the following code:
+
First, emerge Firefox itself. This is quick:
<source lang="bash">
+
ebuild_compile() {
+
        #make sure we're in the right directory
+
        if [ ! -d "${SRCDIR}" ]
+
        then
+
                ebuild_unpack
+
        fi
+
        cd ${SRCDIR}
+
        ./configure --prefix=/usr
+
        make   
+
}
+
</source>
+
One of the most obvious changes in our second version of the ebuild script is the new case statement at the end of the code. This case statement simply checks the second command-line argument, and performs the correct action, depending on its value. If we now type:
+
<source lang="bash">
+
$ ebuild sed-3.02.ebuild
+
</source>
+
We'll actually get an error message. ebuild now wants to be told what to do, as follows:
+
<source lang="bash">
+
$ ebuild sed-3.02.ebuild unpack
+
</source>
+
or:
+
<source lang="bash">
+
$ ebuild sed-3.02.ebuild compile
+
</source>
+
or:
+
<source lang="bash">
+
$ ebuild sed-3.02.ebuild all
+
</source>
+
  
{{fancyimportant|If you provide a second command-line argument, other than those listed above, you get an error message (the * clause), and the program exits.}}
+
<console>
 +
# ##i## emerge www-client/firefox-bin
 +
</console>
  
=== Modularizing the code ===
+
By default, Firefox does not support Adobe Flash. Let's fix this:
Now that the code is quite advanced and functional, you may be tempted to create several more ebuild scripts to unpack and compile your favorite programs. If you do, sooner or later you'll come across some sources that do not use autoconf (<span style="color:green">./configure</span>) or possibly others that have non-standard compilation processes. We need to make some more changes to the ebuild system to accommodate these programs. But before we do, it is a good idea to think a bit about how to accomplish this.
+
  
One of the great things about hard-coding <span style="color:green">./configure --prefix=/usr; make</span> into our compile stage is that, most of the time, it works. But, we must also have the ebuild system accommodate sources that do not use autoconf or normal Makefiles. To solve this problem, I propose that our ebuild script should, by default, do the following:
+
<console>
 +
# ##i## emerge www-plugins/adobe-flash --autounmask-write
 +
</console>
  
# If there is a configure script in <span style="color:green">${SRCDIR}</span>, execute it as follows: <span style="color:green">./configure --prefix=/usr</span>. Otherwise, skip this step.
+
Now, run <tt>etc-update</tt> and accept the changes that Portage made to <tt>/etc/portage/package.license</tt>. Now, let's get Flash installed:
# Execute the following command: make
+
  
Since ebuild only runs configure if it actually exists, we can now automatically accommodate those programs that don't use autoconf and have standard makefiles. But what if a simple "make" doesn't do the trick for some sources? We need a way to override our reasonable defaults with some specific code to handle these situations. To do this, we'll transform our <span style="color:green">ebuild_compile()</span> function into two functions. The first function, which can be looked at as a "parent" function, will still be called <span style="color:green">ebuild_compile()</span>. However, we'll have a new function, called <span style="color:green">user_compile()</span>, which contains only our reasonable default actions:
+
<console>
<source lang="bash">
+
# ##i## emerge www-plugins/adobe-flash
user_compile() {
+
</console>
        #we're already in ${SRCDIR}
+
        if [ -e configure ]
+
        then
+
                #run configure script if it exists
+
                ./configure --prefix=/usr
+
        fi
+
        #run make
+
        make
+
}             
+
  
ebuild_compile() {
+
Firefox is now installed!
        if [ ! -d "${SRCDIR}" ]
+
 
        then
+
=== Firefox and Audio ===
                echo "${SRCDIR} does not exist -- please unpack first."
+
 
                exit 1
+
{{Note|This doesn't seem to be required anymore with Firefox and recent versions of PulseAudio, which can use an ALSA sink to funnel audio automagically into PulseAudio.}}
        fi
+
 
        #make sure we're in the right directory
+
By default, Firefox will try to use an ALSA device for audio. To get Firefox to use PulseAudio, create an <tt>.asoundrc</tt> file in your Firefox user's home directory that looks like this:
        cd ${SRCDIR}
+
 
        user_compile
+
<pre>
 +
pcm.!default
 +
{   type pulse
 +
    hint.description "Default Audio Device"
 
}
 
}
</source>
+
ctl.!default {
It may not seem obvious why I'm doing this right now, but bear with me. While the code works almost identically to our previous version of ebuild, we can now do something that we couldn't do before -- we can override <span style="color:green">user_compile()</span> in '''sed-3.02.ebuild'''. So, if the default <span style="color:green:>user_compile()</span> function doesn't meet our needs, we can define a new one in our '''.ebuild''' file that contains the commands required to compile the package. For example, here's an ebuild file for <span style="color:green">e2fsprogs-1.18</span>, which requires a slightly different <span style="color:green">./configure</span> line:
+
    type pulse
<source lang="bash">
+
#this ebuild file overrides the default user_compile()
+
P=e2fsprogs-1.18
+
A=${P}.tar.gz
+
+
user_compile() {
+
      ./configure --enable-elf-shlibs
+
      make
+
 
}
 
}
</source>
+
</pre>
Now, <span style="color:green">e2fsprogs</span> will be compiled exactly the way we want it to be. But, for most packages, we can omit any custom <span style="color:green">user_compile()</span> function in the '''.ebuild''' file, and the default user_compile() function is used instead.
+
  
How exactly does the ebuild script know which user_compile() function to use? This is actually quite simple. In the ebuild script, the default <span style="color:green">user_compile()</span> function is defined before the '''e2fsprogs-1.18.ebuild''' file is sourced. If there is a <span style="color:green">user_compile()</span> in '''e2fsprogs-1.18.ebuild''', it overwrites the default version defined previously. If not, the default <span style="color:green">user_compile()</span> function is used.
+
This will route ALSA to PulseAudio by default -- I believe you may need to restart your X session to get these changes to apply.  
  
This is great stuff; we've added a lot of flexibility without requiring any complex code if it's not needed. We won't cover it here, but you could also make similar modifications to <span style="color:green">ebuild_unpack()</span> so that users can override the default unpacking process. This could come in handy if any patching has to be done, or if the files are contained in multiple archives. It is also a good idea to modify our unpacking code so that it recognizes bzip2-compressed tarballs by default.
+
I also recommend emerging <tt>media-sound/pavucontrol</tt> -- the PulseAudio Volume Control app. Some casual tweaking in here to set the output device for Firefox should result in audio working for you.
 +
<!--
 +
== dwb - a webkit browser ==
  
=== Configuration files ===
+
The dwb Web browser, <tt>www-client/dwb</tt>, is one of the minimal browsers utilizing webkit-gtk and gtk+. It can be operated by vim-style keyboard shortcuts.
We've covered a lot of sneaky bash techniques so far, and now it's time to cover one more. Often, it's handy for a program to have a global configuration file that resides in '''/etc'''. Fortunately, this is easy to do using bash. Simply create the following file and save it as '''/etc/ebuild.conf''':
+
<source lang="bash">
+
# /etc/ebuild.conf: set system-wide ebuild options in this file
+
  
# MAKEOPTS are options passed to make
+
==== Advantages ====
MAKEOPTS="-j2"
+
</source>
+
In this example, I've included just one configuration option, but you could include many more. One of the beautiful things about bash is that this file can be parsed by simply sourcing it. This is a design trick that works with most interpreted languages. After '''/etc/ebuild.conf''' is sourced, <span style="color:green">$MAKEOPTS</span> is defined inside our ebuild script. We'll use it to allow the user to pass options to make. Normally, this option would be used to allow the user to tell ebuild to do a parallel make. This is explained below.
+
  
{{fancynote|'''What is a parallel make?''' <nowiki>To speed compilation on multiprocessor systems, make supports compiling a program in parallel. This means that instead of compiling just one source file at a time, make compiles a user-specified number of source files simultaneously (so those extra processors in a multiprocessor system are used). Parallel makes are enabled by passing the -j # option to make, as follows: make -j4 MAKE="make -j4". This code instructs make to compile four programs simultaneously. The MAKE="make -j4" argument tells make to pass the -j4 option to any child make processes it launches.</nowiki>}}
+
* very clean interface with maxed-out screen estate for the actual website content
 +
* plugin system for forms, userscripts, adblock, speeddial etc.
 +
* vim-style control
 +
* choose between gtk2 and gtk3 (useflag)
 +
* configuration through web interface (setting: Ss; keyboard: Sk)
  
Here's the final version of our ebuild program:
+
==== Disadvantages ====
<source lang="bash">
+
#!/usr/bin/env bash
+
  
if [ $# -ne 2 ]
+
* the webkit-gtk engine crashes occasionally
then
+
* takes long time to build webkit-gtk
        echo "Please specify ebuild file and unpack, compile or all"
+
* A separate merge of <tt>www-plugins/adobe-flash</tt> is required for Adobe Flash support.
        exit 1
+
fi
+
  
source /etc/ebuild.conf
+
=== Installing dwb ===
  
if [ -z "$DISTDIR" ]
+
It is suggested to use www-client/dwb-9999 to stay ahead of development.
then
+
<console>
        # set DISTDIR to /usr/src/distfiles if not already set
+
# ##i## echo "=www-client/dwb-9999 **" >> /etc/portage/package.keywords
        DISTDIR=/usr/src/distfiles
+
# ##i## emerge www-client/dwb
fi
+
</console>
export DISTDIR
+
  
ebuild_unpack() {
+
By default, dwb does not support Adobe Flash. Let's fix this:
        #make sure we're in the right directory
+
        cd ${ORIGDIR}
+
       
+
        if [ -d ${WORKDIR} ]
+
        then   
+
                rm -rf ${WORKDIR}
+
        fi
+
  
        mkdir ${WORKDIR}
+
<console>
        cd ${WORKDIR}
+
# ##i## emerge www-plugins/adobe-flash --autounmask-write
        if [ ! -e ${DISTDIR}/${A} ]
+
</console>
        then
+
                echo "${DISTDIR}/${A} does not exist.  Please download first."
+
                exit 1
+
        fi
+
        tar xzf ${DISTDIR}/${A}
+
        echo "Unpacked ${DISTDIR}/${A}."
+
        #source is now correctly unpacked
+
}
+
  
user_compile() {
+
Now, run <tt>etc-update</tt> and accept the changes that Portage made to <tt>/etc/portage/package.license</tt>. Now, let's get Flash installed:
        #we're already in ${SRCDIR}
+
        if [ -e configure ]
+
        then
+
                #run configure script if it exists
+
                ./configure --prefix=/usr
+
        fi
+
        #run make
+
        make $MAKEOPTS MAKE="make $MAKEOPTS" 
+
}
+
  
ebuild_compile() {
+
<console>
        if [ ! -d "${SRCDIR}" ]
+
# ##i## emerge www-plugins/adobe-flash
        then
+
</console>
                echo "${SRCDIR} does not exist -- please unpack first."
+
 
                exit 1
+
dwb is now installed!
        fi
+
-->
        #make sure we're in the right directory
+
 
        cd ${SRCDIR}
+
== Oracle Java Runtime Environment ==
        user_compile
+
 
}
+
Enabling a Java Runtime Environment isn't a must-have for everyone, but it's nice to have installed in case you need it. And some of us have a need to run a Java app now and again, so let's look at getting it installed. It's quite easy to get going.
 +
 
 +
First, let's accept the Oracle Java SE License:
 +
 
 +
<console>
 +
# ##i##emerge dev-java/oracle-jre-bin --autounmask-write
 +
</console>
 +
 +
Now, run <tt>etc-update</tt> and accept the changes it made to <tt>/etc/portage/package.license</tt>. Now, let's emerge the Oracle JRE:
 +
 
 +
{{fancyimportant|1=
 +
Please ensure that the <tt>nsplugin</tt> USE flag is enabled when you run <tt>emerge</tt>, below. This enables the Web browser plugin.}}
 +
 
 +
<console>
 +
# ##i##emerge -a dev-java/oracle-jre-bin</console>
 +
 
 +
The Oracle JRE is now installed.
 +
 
 +
=== Running Java Applets ===
  
export ORIGDIR=`pwd`
+
If your Web browser prompts you for an application to run <tt>.jnlp</tt> files, instruct it to use <tt>/opt/oracle-jre-bin-1.7.0.51/bin/javaws</tt> (also known as "Java Web Start".) You can also use <tt>javaws</tt> to run <tt>.jnlp</tt> files from an xterm.
export WORKDIR=${ORIGDIR}/work
+
  
if [ -e "$1" ]
+
=== Java and Security ===
then
+
        source $1
+
else
+
        echo "Ebuild file $1 not found."
+
        exit 1
+
fi
+
  
export SRCDIR=${WORKDIR}/${P}
+
Starting with Oracle JRE 1.7.0.51 and higher, Java has enhanced security settings and may refuse to run some Java applets. Normally, this is fine and good, unless you absolutely need to run an app and Java is refusing to run it. To get around this, open up an xterm as your browser user and go to the Java bin dir, and run <tt>ControlPanel</tt> as follows:
  
case "${2}" in
+
<console>
        unpack)
+
$ ##i##cd /opt/oracle-jre-bin-1.7.0.51/bin
                ebuild_unpack
+
$ ##i##./ControlPanel
                ;;
+
</console>
        compile)
+
                ebuild_compile
+
                ;;
+
        all)
+
                ebuild_unpack
+
                ebuild_compile
+
                ;;
+
        *)
+
                echo "Please specify unpack, compile or all as the second arg"
+
                exit 1
+
                ;;
+
esac
+
</source>
+
Notice '''/etc/ebuild.conf''' is sourced near the beginning of the file. Also, notice that we use <span style="color:green">$MAKEOPTS</span> in our default <span style="color:green">user_compile()</span> function. You may be wondering how this will work -- after all, we refer to <span style="color:green">$MAKEOPTS</span> before we source '''/etc/ebuild.conf''', which actually defines <span style="color:green">$MAKEOPTS</span> in the first place. Fortunately for us, this is OK because variable expansion only happens when <span style="color:green">user_compile()</span> is executed. By the time <span style="color:green">user_compile()</span> is executed, '''/etc/ebuild.conf''' has already been sourced, and <span style="color:green">$MAKEOPTS</span> is set to the correct value.
+
  
=== Wrapping it up ===
+
Now, go to the '''Security''' tab and click the '''Edit Site List...''' button. Add a URL for the site from which you are downloading the Java Applet. Now click '''OK''' and save your changes, and try running the Java applet again. It should now be allowed to run.
We've covered a lot of bash programming techniques in this article, but we've only touched the surface of the power of bash. For example, the production Gentoo Linux ebuild system not only automatically unpacks and compiles each package, but it can also:
+
  
* Automatically download the sources if they are not found in $DISTDIR
+
=== "Java Not Allowed" in Chrome-Based Browsers ===
* Verify that the sources are not corrupted by using MD5 message digests
+
If you load a Web page with a Java applet on it, you may see a Java logo with text underneath that says "Java not allowed". To resolve this issue, visit the following URL in your browser:
* If requested, install the compiled application into the live filesystem, recording all installed files so that the package can be easily uninstalled at a later date.
+
* If requested, package the compiled application in a tarball (compressed the way you like it) so that it can be installed later, on another computer, or during the CD-based installation process (if you are building a distribution CD)
+
  
In addition, the production ebuild system has several other global configuration options, allowing the user to specify options such as what optimization flags to use during compilation, and whether optional support for packages like GNOME and slang should be enabled by default in those packages that support it.
+
<code>chrome://plugins</code>
  
It's clear that bash can accomplish much more than what I've touched on in this series of articles. I hope you've learned a lot about this incredible tool, and are excited about using bash to speed up and enhance your development projects.
+
This will display a list of all plugins enabled in Chrome. You should see a plugin called something like this:
  
== Resources ==
+
<code>Java(TM) - Version: 10.45.2 </code>
  
* Download the source tarball ('''sed-3.02.tar.gz''') from ftp://ftp.gnu.org/pub/gnu/sed.
+
<code>Next Generation Java Plug-in 10.45.2 for Mozilla browsers</code>
* Read [[Bash by Example, Part 1]].
+
* Read [[Bash by Example, Part 2]].
+
* Check out the [http://www.gnu.org/software/bash/manual/bash.html bash online reference manual].
+
  
__NOTOC__
+
Check the "Always Enable" checkbox and then reload the page with the Java applet, and it should load properly.[[Category:First Steps]]
[[Category:Linux Core Concepts]]
+
[[Category:Tutorial]]
[[Category:Articles]]
+
[[Category:Desktop]]
{{ArticleFooter}}
+

Revision as of 16:07, March 5, 2015

Funtoo Linux offers a number of possibilities when it comes to Web browsers. This page is intended to give you an overview of what is available, their various trade-offs, and also provide tutorial-style instructions on how to set them up so they offer full functionality. Additionally, instructions are provided on how to set up the Oracle Java Runtime Environment for running Java applets.

Prerequisites

Before installing a Web browser, ensure that you have a functioning X environment or desktop environment set up.

Google Chrome (binary)

The Google Chrome (binary) ebuild is www-client/google-chrome. Google Chrome is a very good Web browser. This browser is a great option for those who want a full-featured browser up and running quickly without a lot of complication.

Advantages

  • It's very fast to install, because it does not need to be built from source.
  • It includes support for Adobe Flash and PDF viewing built-in, which works right away with no additional configuration.
  • It works well with PulseAudio with no additional configuration required.
  • Overall, the browser looks fantastic and is very fast.

Disadvantages

  • Included Flash does not support Amazon Video on Demand, which requires older DRM support. See Firefox as an option for this.
  • It's based on a binary for Debian systems, and sometimes depends on outdated versions of ebuilds to run.
  • The stable Google build of Google Chrome (www-client/google-chrome) has a bug where the text in the address bar "wiggles" as you type. This is fixed in later versions, but not in the reliable "stable" binary that Google is currently shipping. If you are a perfectionist, having a browser that is so close to perfect but with this one fatal flaw will gnaw on your soul until you replace it with something else (like Chromium with the classic theme.)

Google Chrome Installation

As root, you first need to accept the Google Chrome license, as follows:

# emerge google-chrome --autounmask-write

Now, run etc-update and accept the changes made to /etc/portage/package.license. Now, emerge:

# emerge -a google-chrome

Chromium

Chromium (www-client/chromium) is the from-source version of Google Chrome, and is a very good option for people who like Google Chrome but who want to build from source. Like most modern Web browsers, it does take a very long time to build -- up to several hours on a dual-core system, and about an hour on a 4-6 core system.

After emerging, it requires a special helper package www-plugins/chrome-binary-plugins for Adobe Flash as well as PDF viewing support.

Advantages

  • It is built from source, so it has fewer issues with dependencies than Google Chrome, yet it is very similar in functionality.
  • It looks great, and works well.
  • With an easy emerge of www-plugins/chrome-binary-plugins, it provides identical functionality to Chrome in regards to Adobe Flash and PDF support.

Disadvantages

  • It takes a very long time to build, even on a modern system, so be prepared to wait.

Installing Chromium

To install Chromium, you will need to enable the minizip USE flag for sys-libs/zlib, and I also recommend enabling aura for Chromium itself, which is a new GPU-accelerated architecture. Add the following lines to /etc/portage/package.use:

sys-libs/zlib minizip
www-client/chromium aura

Okay, now it's time to emerge Chromium:

#  emerge -a www-client/chromium

This will take a long time to complete. After you're done, emerge Chrome helper programs to enable Adobe Flash and PDF viewing support. First, review and accept the license:

# emerge www-plugins/chrome-binary-plugins --autounmask-write

Now, run etc-update and accept the changes that it made to /etc/portage/package.license. Now, emerge the plugins for real:

# emerge www-plugins/chrome-binary-plugins

Making Chromium Look Sexier

If you like the default "blue" look of Chrome, and want Chromium to look like that, go to the "3 bar" menu in the upper right, go to Settings, and under Appearance, click Use Classic theme. Flash some gang signs to imaginary onlookers, and you are done.

Firefox (binary)

The Firefox binary Web browser, www-client/firefox-bin is another good option. It is more feature-rich as opposed to the "lean and mean" Chrome/Chromium.

Advantages

  • Firefox is a great, full-featured Web browser.
  • It is quick to install, because it is a binary.

Disadvantages

  • It works well with ALSA by default, but requires tweaks to get working with PulseAudio.
  • A separate merge of www-plugins/adobe-flash is required for Adobe Flash support.

Installing Firefox

First, emerge Firefox itself. This is quick:

#  emerge www-client/firefox-bin

By default, Firefox does not support Adobe Flash. Let's fix this:

#  emerge www-plugins/adobe-flash --autounmask-write

Now, run etc-update and accept the changes that Portage made to /etc/portage/package.license. Now, let's get Flash installed:

#  emerge www-plugins/adobe-flash

Firefox is now installed!

Firefox and Audio

Note

This doesn't seem to be required anymore with Firefox and recent versions of PulseAudio, which can use an ALSA sink to funnel audio automagically into PulseAudio.

By default, Firefox will try to use an ALSA device for audio. To get Firefox to use PulseAudio, create an .asoundrc file in your Firefox user's home directory that looks like this:

pcm.!default 
{    type pulse
    hint.description "Default Audio Device"
}
ctl.!default {
    type pulse
}

This will route ALSA to PulseAudio by default -- I believe you may need to restart your X session to get these changes to apply.

I also recommend emerging media-sound/pavucontrol -- the PulseAudio Volume Control app. Some casual tweaking in here to set the output device for Firefox should result in audio working for you.

Oracle Java Runtime Environment

Enabling a Java Runtime Environment isn't a must-have for everyone, but it's nice to have installed in case you need it. And some of us have a need to run a Java app now and again, so let's look at getting it installed. It's quite easy to get going.

First, let's accept the Oracle Java SE License:

# emerge dev-java/oracle-jre-bin --autounmask-write

Now, run etc-update and accept the changes it made to /etc/portage/package.license. Now, let's emerge the Oracle JRE:

Important

Please ensure that the nsplugin USE flag is enabled when you run emerge, below. This enables the Web browser plugin.

# emerge -a dev-java/oracle-jre-bin

The Oracle JRE is now installed.

Running Java Applets

If your Web browser prompts you for an application to run .jnlp files, instruct it to use /opt/oracle-jre-bin-1.7.0.51/bin/javaws (also known as "Java Web Start".) You can also use javaws to run .jnlp files from an xterm.

Java and Security

Starting with Oracle JRE 1.7.0.51 and higher, Java has enhanced security settings and may refuse to run some Java applets. Normally, this is fine and good, unless you absolutely need to run an app and Java is refusing to run it. To get around this, open up an xterm as your browser user and go to the Java bin dir, and run ControlPanel as follows:

$ cd /opt/oracle-jre-bin-1.7.0.51/bin
$ ./ControlPanel

Now, go to the Security tab and click the Edit Site List... button. Add a URL for the site from which you are downloading the Java Applet. Now click OK and save your changes, and try running the Java applet again. It should now be allowed to run.

"Java Not Allowed" in Chrome-Based Browsers

If you load a Web page with a Java applet on it, you may see a Java logo with text underneath that says "Java not allowed". To resolve this issue, visit the following URL in your browser:

chrome://plugins

This will display a list of all plugins enabled in Chrome. You should see a plugin called something like this:

Java(TM) - Version: 10.45.2

Next Generation Java Plug-in 10.45.2 for Mozilla browsers

Check the "Always Enable" checkbox and then reload the page with the Java applet, and it should load properly.