Force run MakeFile rule to run shell command - unix

I have the following rule in my make file which runs only a shell command
install:
$(shell insmod kdisk.ko)
but when I do > make install, it always says that make: 'install' is up to date.
How can I force it to run the shell command?

You probably want to declare the target as
.PHONY: install
install: kdisk.ko
insmod kdisk.ko
This tells the make program that:
the install target requires kdisk.ko before it can be started
the install target is a phony target and will not try to produce a install file, just to do something useful.
the recipe bound to install is insmod kdisk.ko.
With your declaration, the command insmod kdisk.ko will be processed as make reads the file and its output will be used as a recipe for the install target. Quite not what you want.

Related

does gmake automatically define $(INSTALL)?

gmake doesn't seem to have a value for $(INSTALL). is this supposed to be defined by the user?
$(CC) works fine. most sample Makefiles i went over didn't have an explicit definition of $(INSTALL)...
if it has to be defined by user, what are best practices (other than aliasing _PROGRAM and _DATA)? why prefer install over cp?
Makefile
helloworld:
echo 'hello, world' >helloworld
install:
$(INSTALL) ${HOME}/ helloworld
log
$ make helloworld
$ make install
/home/<username>/ helloworld
make: /home/kevins/: Permission denied
make: *** [Makefile:5: install] Error 127
version info
GNU Make 4.3
Built for x86_64-pc-linux-gnu
There is no default value defined for INSTALL. You can see all the default rules and variables by running:
make -p -f/dev/null
Whether install or cp is a better fit depends entirely on your use-case. install does a lot more than cp. But, you can run other commands in addition to cp to take care of those things, and install is not available on every system. So, it's what's best for you.

Why my codelite execute 'make -j 0'

I'm using cmake-GUI on windows, generating for codelite, to build a simple "hello world" project (https://github.com/jameskbride/cmake-hello-world). I'm trying to use cygwin compilers but when I run the build command, I got the following error:
C:\WINDOWS\system32\cmd.exe /C C:/cygwin64/bin/make.exe -j 0
----------Building project:[ Debugging - Debug ]----------
make: the '-j' option requires a positive integer argument
Usage: make [options] [target] ...
Why it is happening?!?
My cygwin folder is in PATH. In cygwin terminal the project works.
Your project was generated by CMake - this means that the project is set to custom project so the command to execute (in your case make -j0) is set in the Project Settings->Customize->Custom build page.
On that page you have several entries with different titles (Build, Clean etc)
Double click each entry so it will open in Edit mode and remove the -j0 option
This looks like a bug in CodeLite - CMake generator

Makefile for building an R package linked to an analysis

Suppose I have a project for which I have developed an R package. The hierarchy might look something like this.
/project
---Makefile
---workflow.R
---test.R
---/mypackage
---DESCRIPTION
---NAMESPACE
---/R
---func1.R
---func2.R
workflow.R depends on the latest version of mypackage being installed. However, I only want to re-build the package if any file inside of it has been modified.
Currently, in my Makefile, I have:
PACKAGE=$(wildcard mypackage/**/*)
all: install test workflow
install: $(PACKAGE)
R CMD INSTALL mypackage
workflow: install
Rscript workflow.R
test: install
Rscript test.R
However, this will re-install the package every time I run make test, even if nothing inside the package has changed. Is there a clean way to avoid this?
The install rule does not create a file named install in the current directory, so make tries to remake it each time. This looks like it should be a .PHONY target, but that itself won't fix the issue as it will still execute the recipes.
One solution is to have another rule that creates a stub file:
.PHONY: all install test workflow
all: install test workflow
install: install.done
install.done: $(PACKAGE)
R CMD INSTALL mypackage
touch $#
Or you could just make install the stub file itself and make it a non-.PHONY rule.
It sounds like you want to treat the installation as an intermediate step. You can do this by adding
.INTERMEDIATE: install
to your makefile.
The make manual explains (link):
If an ordinary file b does not exist, and make considers a target that depends on b, it invariably creates b and then updates the target from b. But if b is an intermediate file, then make can leave well enough alone. It won’t bother updating b, or the ultimate target, unless some prerequisite of b is newer than that target or there is some other reason to update that target.

Can I install a .deb during a BitBake Build?

Problem Definition
I'm attempting to adapt these rosjava installation instructions so that I can include rosjava on a target image built by the BitBake build system. I'm using the jethro branch of Poky.
Implementation Attempt: Build From .deb with package_deb.bbclass
According to the installation instructions, all that really needs to be done to install rosjava is the following:
sudo apt-get install ros-indigo-rosjava
Which works perfectly fine on my build machine. I figured that if I can just point to a .deb and use the Poky metadata class package_deb, it would do all the heavy lifting for me, so I produced the following simple recipe adapted on this posting on the Yocto Project mailing list:
inherit package_deb
SRC_URI = "http://packages.ros.org/ros/ubuntu/pool/main/r/ros-indigo-rosjava/ros-indigo-rosjava_0.2.1-0trusty-20160207-031808-0800_amd64.deb"
SRC_URI[md5sum] = "2020ccc8b4a67dd918a9a2c426eece0b"
SRC_URI[sha256sum] = "ab9493fabe1285b0d21aab031348d0d733d116b0b2470bae90025709b303b649"
The relevant part of the errors I get during the above recipe's do_unpack are:
| no entry data.tar.gz in archive
|
| gzip: stdin: unexpected end of file
| tar: This does not look like a tar archive
| tar: Exiting with failure status due to previous errors
| DEBUG: Python function base_do_unpack finished
| DEBUG: Python function do_unpack finished
The following command produces the output below:
$ ar t python-rosdistro_0.4.5-1_all.deb
debian-binary
control.tar.gz
data.tar.xz
You can see here that there's a data.tar.xz, not data.tar.gz. What can I do to remedy this error and install from this particular .deb?
I've included package_deb in my PACKAGE_CLASSES variable and package-management in my IMAGE_FEATURES. I've tried other methods of installation which have all failed; I thought this method in particular would be very useful to know how to implement.
Update - 3/22
I'm attempting to circumvent the problems with the method above by doing my installation through a ROOTFS_POSTPROCESS_COMMAND which I've adapted from forum posts like this
install_rosjava() {
${STAGING_BINDIR_NATIVE}/dpkg \
--root=${IMAGE_ROOTFS}/ \
--admindir=${IMAGE_ROOTFS}/var/lib/dpkg/ \
-L /var/cache/apt/archives/ros-indigo-rosjava_0.2.1-0trusty-20160207-031808-0800_amd64.deb
}
ROOTFS_POSTPROCESS_COMMAND += " install_rosjava() ; "
However, this fails due to dpkg not being a command found within the ${STAGING_BINDIR_NATIVE} path. The Yocto Project Reference Manual states that:
STAGING_BINDIR_NATIVE Specifies the path to the /usr/bin subdirectory of the sysroot directory for the build host.
Taking a look inside this directory yields a lot of commands but not dpkg (The recipe depends on the dpkg package, and this command can be found in my target rootfs after the build is finished; I've also tried pointing to ${IMAGE_ROOTFS}/usr/bin/dpkg which yields the same results). From what I understand of the BitBake process, this command may be in another sysroot, but I must admit that this is where my understanding breaks down.
Can I adjust this method so that it works, or will I need to start from scratch on an installation from source?
Perhaps there's a different method entirely which I could consider?
If you really want to install their deb directly then your rootfs postprocess is one solution. It doesn't work because depending on dpkg will build you a dpkg for the target but you want a dpkg that will run on the host. Add a dependency on dpkg-native to your image.
Though personally I'd either inherit bin_package and extract the deb they provide then re-package it as a standard package in OE, or ideally write a proper recipe to build rosjava and submit it to meta-ros (https://github.com/bmwcarit/meta-ros).
package_deb is where the packaging machinery for deb packages is stored, it's not something you'd inherit in a recipe but should be listed in PACKAGE_CLASSES.
When you put a .deb in a SRC_URI the fetcher will try to unpack it so you can access the contents: the assumption is that you're going to repack the contents as a native Yocto recipe.
If that's what you want to do then first you'll need to fix the unpack logic (in bitbake/lib/bb/fetch2/__init__.py) to handle .debs with xz-compressed data. This is a bug in bitbake and a bug report and/or patch would be appreciated.
The alternative would be to use their deb directly but I don't recommend that as it's likely the dependencies don't match. The best long-term solution would be to build it from source directly instead of attempting to use a package for another distro.

run a "source" bash shell script in qmake

I want to use the intel compiler for Qt, but using the intel compiler implies running the script
$ source /opt/intel/bin/compilervars.sh intel64
Of course, I could add this to ~/.bashrc, but this would not run it in QtCreator, where it still complains about missing icpc. So I want it to be a part of the main mkspec qmake file.
How can I execute that full bash command in qmake?
Short Answer: Using QMAKE_EXTRA_TARGETS and PRE_TARGET_DEPS, you can execute source /opt/intel/bin/compilersvars.sh intel64, but simply sourcing them will not solve your issue.
Long Answer: The QMake file is converted into a Makefile. Make then executes the Makefile. The problem you will run into is that Make executes each command in its own shell. Thus, simply sourcing the script will only affect one command, the command that executes the script.
There are a couple of possible ways to make things work:
Execute the script before starting Qt-Creator. I've actually done this for some projects where I needed to have special environment variables setup. To make my life easier, I created a shell command to setup the environment and then launch Qt-Creator.
Within Qt-Creator, modify the Build Environment for the project I've also used this trick. In your case, simply look at the environment setup by the script and change the "Build Environment" settings under the project tab for your project to match those setup by the script.
It might also be possible to modify QMake's compiler commands, but I am not sure you can make it execute two commands instead of one (source the script then execute the compiler). Further more, this will make the project very un-transportable to other systems.
You can create a shell script that does more or less the following:
#! /usr/bin/env sh
# Remove the script's path from the PATH variable to avoid recursive calls
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export PATH=${PATH/$SCRIPT_DIR:/}
# Set the environment up
source /opt/intel/bin/compilervars.sh intel64
# Call make with the given arguments
make "$#"
Save it into a file named "make" in an empty directory somewhere, make it executable, then change the build environment in QT Creator to prepend PATH with the script's directory:
PATH=[dir-of-make-script]:${Env:PATH}
You can do this either in the project settings or once and for all in the kit settings.
Like this, QT Creator will be fooled into calling your make script which sets up your environment before calling the actual make binary. I use a similar technique under Windows with Linux cross-toolchains and it has been working well so far.

Resources