--- title: Install system programs author: "Laurent Modolo" output: rmdformats::downcute: self_contain: true use_bookdown: true default_style: "light" lightbox: true css: "./www/style_Rmd.css" --- ```{r include = FALSE} if (!require("fontawesome")) { install.packages("fontawesome") } if (!require("klippy")) { install.packages("remotes") remotes::install_github("rlesur/klippy") } library(fontawesome) knitr::opts_chunk$set(echo = TRUE) knitr::opts_chunk$set(comment = NA) klippy::klippy( position = c('top', 'right'), color = "white", tooltip_message = 'Click to copy', tooltip_success = 'Copied !') ``` [](http://creativecommons.org/licenses/by-sa/4.0/) Objective: Learn how to install programs in GNU/Linux As we have seen in the [4 unix file system](http://perso.ens-lyon.fr/laurent.modolo/unix/4_unix_file_system.html#lib-and-usrlib) session, programs are files that contain instruction for the computer to do things. Those files can be in binary or text format (with a [shebang](http://perso.ens-lyon.fr/laurent.modolo/unix/9_batch_processing.html#shebang)). Any of those files, present in a folder of the [**PATH**](http://perso.ens-lyon.fr/laurent.modolo/unix/9_batch_processing.html#path) variable are executable anywhere by the user. For system wide installation, the program files are copied within shared folder path containained in the [**PATH**](http://perso.ens-lyon.fr/laurent.modolo/unix/9_batch_processing.html#path) variable. Developers don’t want to reinvent the wheel each time they want to write complex instruction in their programs, this is why they use shared library of pre-written complex instruction. This allows for quicker development, fewer bugs (we only have to debug the library once and use it many times), and also [better memory management](http://perso.ens-lyon.fr/laurent.modolo/unix/6_unix_processes.html#processes-tree) (we only load the library once and it can be used by different programs). # Package Manager However, interdependencies between programs and libraries can be a nightmare to handle manually this is why most of the time when you install a program you will use a [package manager](https://en.wikipedia.org/wiki/Package_manager). [Package manager](https://en.wikipedia.org/wiki/Package_manager) are system tools that will handle automatically all the dependencies of a program. They rely on **repositories** of programs and library which contains all the information about the trees of dependence and the corresponding files (**packages**). System-wide installation steps: - The user asks the package manager to install a program - The **package manager** queries its repository lists to search for the most recent **package** version of the program (or a specific version) - The **package manager** construct the dependency tree of the program - The **package manager** check that the new dependency tree is compatible with every other installed program - The **package manager** install the program **package** and all it’s dependencies **packages** in their correct version The main difference between GNU/Linux distribution is the package manager they use - Debian / Ubuntu: [apt](https://en.wikipedia.org/wiki/APT_(Debian)) - CentOS / RedHat: [yum](https://en.wikipedia.org/wiki/YUM_(software)) - ArchLinux: [pacman](https://en.wikipedia.org/wiki/Pacman_(Arch_Linux)) - SUSE / OpenSUSE: [zypper](https://en.wikipedia.org/wiki/Zypper) - Gentoo: [portage](https://en.wikipedia.org/wiki/Portage_(software)) - Alpine: [apk](https://wiki.alpinelinux.org/wiki/Alpine_newbie_apk_packages) Packages manager install the packages in **root** owned folders, you need **root** access to be able to use them. <details><summary>Solution</summary> <p> ```sh docker run -it --volume /:/root/chroot alpine sh -c "chroot /root/chroot /bin/bash -c 'usermod -a -G sudo etudiant'" && su etudiant ``` </p> </details> ## Installing R **R** is a complex program that relies on loots of dependencies. Your current VM run on Ubuntu, so we are going to use the `apt` tool (`apt-get` is the older version of the `apt` command, `synaptic` is a graphical interface for `apt-get`) You can check the **r-base** package dependencies on the website [packages.ubuntu.com](https://packages.ubuntu.com/focal/r-base). Not too much dependency ? Check the sub-package **r-base-core**. You can check the **man**ual of the `apt` command to install **r-base-core**. <details><summary>Solution</summary> <p> ```sh sudo apt install r-base-core ``` </p> </details> What is the **R** version that you installed ? Is there a newer version of **R** ? ## Adding a new repository You can check the list of repositories that `apt` checks in the file `/etc/apt/sources.list`. You can add the official cran repository to your repositories list: ```sh sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu <release_name>-cran40/' ``` You can use the command `lsb_release -sc` to get your **release name**. Then you must add the public key of this repository: ```sh sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 ``` ## Updating the repository list You can now use `apt` to update your repository list dans try to reinstall **r-base-core** <details><summary>Solution</summary> <p> ```sh sudo apt update ``` </p> </details> The command gives you a way to list all the upgradable **packages**, which version of **R** can you install now ? You can upgrade all the upgradable **packages**. <details><summary>Solution</summary> <p> ```sh sudo apt upgrade ``` </p> </details> With the combination of `update` and `upgrade` you can keep your whole system up to date the even the kernel files is just another package. You can use `apt` to search for the various versions of the `linux-image`. <details><summary>Solution</summary> <p> ```sh sudo apt search linux-image ``` </p> </details> ## Language specific package manager If it’s not a good idea to have different **package manager** on the same system (they don’t know how the dependencies are handled by the other’s manager). You will also encounter language specific package manager: - `ppm` for Perl - `pip` for Python - `npm` for JavaScript - `cargo` for Rust - `install.packages` for R - ... These **package managers** allows your to make installation local to the user, which is advisable to avoid any conflict with the **packages manager** of the system. For example, you can use the following command to install `glances` system wide with `pip` ```sh sudo pip3 install glances ``` You can now try to install `glances` with `apt` What is the `glances` version installed with `apt`, what is the one installed with `pip` ? What is the version of the `glances` of your **PATH** ? Next-time use `pip` with the `--user` switch. # Manual installation Sometimes, a specific tool that you want to use will not be available through a **package manager**. If you are lucky, you will find a **package** for your distribution. For `apt` the **package** are `.deb` files. For example, you can download `simplenote` version 2.7.0 for your architecture [here](https://github.com/Automattic/simplenote-electron/releases/tag/v2.7.0). <details><summary>Solution</summary> <p> ```sh wget https://github.com/Automattic/simplenote-electron/releases/download/v2.7.0/Simplenote-linux-2.7.0-amd64.deb ``` </p> </details> You can then use `apt` to install this file. # From sources If the program is open source, you can also [download the sources](https://github.com/Automattic/simplenote-electron/archive/v2.7.0.tar.gz) and build them. <details><summary>Solution</summary> <p> ```sh wget https://github.com/Automattic/simplenote-electron/archive/v2.7.0.tar.gz ``` </p> </details> You can use the command `tar -xvf` to extract this archive When you go into the `simplenote-electron-2.7.0` folder, you can see a `Makefile` this means that you can use the `make` command to build Simplenote from those files. `make` Is a tool that read recipes (`Makefiles`) to build programs. You can try to install `node` and `npx` with `apt`. What happened ? <details><summary>Solution</summary> <p> ```sh sudo apt install nodejs ``` </p> </details> You can use the [https://packages.ubuntu.com/](https://packages.ubuntu.com/) to search the name of the package containing the `libnss3.so` file. <details><summary>Solution</summary> <p> ```sh sudo apt install libnss3 ``` </p> </details> What now ? Installing dependencies manually is an iterative process... <details><summary>Solution</summary> <p> ```sh sudo apt install libnss3 libatk1.0-dev libatk-bridge2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 libgbm1 ``` </p> </details> Yay we should have every lib ! What now ? A nodejs dependency is missing... After, some query on the internet we can find the solution... <details><summary>Solution</summary> <p> ```sh sudo apt install libnss3 libatk1.0-dev libatk-bridge2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 libgbm1 npm install --save-dev electron-window-state ``` </p> </details> And now you understand why program packaging takes time in a project, and why it’s important ! You can finalize the installation with the command `make install`. Usually the command to build a tool is available in the `README.md` file of the project. Read the `README` file of the [fastp](https://github.com/OpenGene/fastp) program to see which methods of installation are available. > We have used the following commands: > > - apt to install packages on Ubuntu > - pip3 to install Python packages > - npm to install Nodejs packages > - make to build programs from sources Installing programs and maintain different versions of a program on the same system, is a difficult task. In the next session, we will learn how to use [virtualization](./12_virtualization.html) to facilitate our job.