Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-install packages from inside makefile

Goal: when the user types 'make packages', automatically search for the package libx11-dev (required for my program to compile) and, if not found, install it. Here's a stripped-down version of my makefile:

PACKAGES = $(shell if [ -z $(dpkg -l | grep libx11-dev) ]; then sudo apt-get install libx11-dev; fi)

[other definitions and targets]

packages: $(PACKAGES)

When I type 'make packages', I'm prompted for the super-user password. If entered correctly, it then hangs indefinitely.

Is what I'm trying to do even possible from within the makefile? If so, how?

Thanks so much.

like image 959
1'' Avatar asked May 15 '12 20:05

1''


People also ask

How do I compile and install a package using makefile?

To compile it run the command: This will compile the source output a lot of rubbish to your console. Just go ahead and let it finish. It should take about a minute or so. When it is done, you should be ready to install it. As root run: Make will now follow the instructions in the Makefile to install the compiled package.

How long does it take for makefile to install?

Just go ahead and let it finish. It should take about a minute or so. When it is done, you should be ready to install it. As root run: Make will now follow the instructions in the Makefile to install the compiled package. In most cases you should be done now.

What is a makefile?

And because all good things in the software world come from some engineer being too lazy to type in a few extra commands, Makefile was born. Makefile uses the make utility, and if we're to be completely accurate, Makefile is just a file that houses the code that the make utility uses. However, the name Makefile is much more recognizable.

Why do I need to install some dependencies before compiling?

Some packages requires you to have some dependencies installed in order to be compiled or to be run afterwards. When using apt or another package manager, it usually handles this for you. When compiling packages yourself you should always check the documentation, and make sure you have the required packages installed beforehand.


2 Answers

The problem is that the shell function acts like backticks in the shell: it takes the output to stdout and returns it as the value of the function. So, apt-get is not hanging, it's waiting for you to enter a response to some question. But you cannot see the question because make has taken the output.

The way you're doing this is not going to work. Why are you using shell instead of just writing it as a rule?

packages:
        [ -z `dpkg -l | grep libx11-dev` ] && sudo apt-get install libx11-dev
.PHONY: packages
like image 69
MadScientist Avatar answered Oct 19 '22 21:10

MadScientist


I figured out a better way, which avoids the problem of having unexpected arguments to the if statement:

if ! dpkg -l | grep libx11-dev -c >>/dev/null; then sudo apt-get install libx11-dev; fi

The -c flag on grep makes it return the number of lines in dpkg -l which contain the string libx11-dev, which will either be 0 (if uninstalled) or 1 (if installed), allowing

dpkg -l | grep libx11-dev -c  

to be treated like an ordinary boolean variable.

like image 39
1'' Avatar answered Oct 19 '22 21:10

1''