Running a Makefile on Raspberry Pi3, installation problems - makefile

let me start off by saying this is an entirely new world to me so forgive any improper use of terminology.
The problem in a nutshell, I was given the file which is used to run a GUI for controlling a motor. The UI was created in Qt Creator. After numerous google searches and trial and error I learned how to run the Makefile on the Raspberry Pi3 device. This code is in working order and should not need any modifications to the code itself persay, it is just a matter of installing the right packages and typing the correct commands.
These are the steps I am getting to and the resulting output:
pi#raspberrypi:~/Documents/BasicInterface $ make
cp source/Collection.py build/Collection.py
cp source/main_release.py build/main_release.py
cp source/utilities.py build/utilities.py
cp source/Calibration.py build/Calibration.py
cp source/main_debug.py build/main_debug.py
cp source/archive.py build/archive.py
cp source/MotorControl.py build/MotorControl.py
cp source/MainCanvas.py build/MainCanvas.py
cp source/Report.py build/Report.py
cp source/MainWindow.py build/MainWindow.py
cp source/LoadCell.py build/LoadCell.py
cp source/Analysis.py build/Analysis.py
pyrcc5 resources/resources_rc.qrc -o build/resources_rc.py
pyuic5 resources/Ui_MainWindow.ui > build/Ui_MainWindow.py
pyuic5 resources/Ui_About.ui > build/Ui_About.py
python3 -m zipapp -p "/usr/bin/env python3" build -m main_release:main -o main_release.pyz
This is the Makefile file:
SRC = $(wildcard source/*.py)
OBJ = $(subst source,build,$(SRC))
OBJ += build/resources_rc.py
OBJ += build/Ui_MainWindow.py
OBJ += build/Ui_About.py
RCS = $(wildcard resources/embed/*)
RCS += $(wildcard resources/dynamic/*)
PYTHON = python3
FLAGS = -m zipapp -p "/usr/bin/env python3" build
all: release
release: main_release.pyz
debug: main_debug.pyz
install: main_release.pyz
.PRECIOUS: $(OBJ)
.PHONY: clean
.PHONY: install
%.pyz: $(OBJ)
$(PYTHON) $(FLAGS) -m $(basename $#):main -o $#
build/%.py: source/%.py
cp $< $#
build/%.py: resources/%.qrc $(RCS)
pyrcc5 $< -o $#
build/%.py: resources/%.ui
pyuic5 $< > $#
resources/dynamic/about.html: support/writeAbout.sh
./support/writeAbout.sh resources/dynamic/about.html
clean:
-rm $(OBJ)
-rm main_*.pyz
-rm -rf build/__pycache__
install:
mkdir -p $(HOME)/.irisEngineering
install main_release.pyz $(HOME)/.irisEngineering/AdhesionTester.pyz
install resources/embed/icon.svg $(HOME)/.irisEngineering/
envsubst <support/AdhesionTester.desktop >$(HOME)/Desktop/AdhesionTester.desktop
Basically it is not creating the directory (unless I'm looking in the wrong spot) and I do not see the application anywhere. I'm not sure if the information I have provided will suffice in helping me, but please let me know if any additional information is needed.

Related

Using make to compile several files of the same type which are under different subdirectories?

I just started learning make today. I have several assembly files that I want to compile and then join into a single file. For now I have two files in my tree but the makefile code should be able to handle more. So here is what the files look like.
Src/Boot/MBR.asm
Src/Boot/SecondStage/Bootloader.asm
I want to compile each of these files into the Bin/ directory that the makefile is located in, where the files should end up like this
Bin/MBR.bin
Bin/Bootloader.bin
then I will concentrate these two files into one single file os-image.img
So far I came up with the following
AS := nasm
ASFLAGS_BIN := -fbin
SRCDIR := Src
BINDIR := Bin
BOOTASM = $(shell find $(SRCDIR) -name '*.asm')
BOOTBIN = $(addprefix $(BINDIR)/, $(addsuffix .bin, $(basename $(notdir $(BOOTASM)))))
build: clean compile
cat $(BOOTBIN) > Bin/os-image.img
compile: $(BOOTBIN)
$(BOOTBIN) : $(BOOTASM)
$(AS) $(ASFLAGS_BIN) $< -o $#
clean:
rm -rf $(BINDIR)/%.bin
The output when I type make to shell is the following
rm -rf Bin/%.bin
nasm -fbin Src/Boot/second/Bootloader.asm -o Bin/Bootloader.bin
nasm -fbin Src/Boot/second/Bootloader.asm -o Bin/MBR.bin
cat Bin/Bootloader.bin Bin/MBR.bin > Bin/os-image.img
The expected output is:
rm -rf Bin/%.bin
nasm -fbin Src/Boot/second/Bootloader.asm -o Bin/Bootloader.bin
nasm -fbin Src/Boot/second/MBR.asm -o Bin/MBR.bin
cat Bin/Bootloader.bin Bin/MBR.bin > Bin/os-image.img
Obviously the problem is in here
$(BOOTBIN) : $(BOOTASM)
$(AS) $(ASFLAGS_BIN) $< -o $#
However I couldn't understand how I should be able to achieve what I want since I am pretty inexperienced at this.
So the question is:
How should I get each prerequisite that corresponds to the related target? or something similar to that.
Thanks in advance.
You can do this with VPATH --
BOOTASM = $(shell find $(SRCDIR) -name '*.asm')
BOOTBIN = $(addprefix $(BINDIR)/, $(addsuffix .bin, $(basename $(notdir $(BOOTASM)))))
VPATH=$(sort $(dir $(BOOTASM))
$(BOOTBIN) : %.bin : %.asm
$(AS) $(ASFLAGS_BIN) $< -o $#
But, read the third rule of makefiles before you got to far down the vpath road...
Another thing you should be aware of -- for
build: clean compile
cat $(BOOTBIN) > Bin/os-image.img
Then clean is not guaranteed to run before compile (and in fact, on a parallel system they might both try to run at the same time...). Obviously this would not be what you want. Either make compile depend on clean (but then it will clean every time you try to compile), or create a seperate clean_then_compile : clean target, which runs the compile command on its own.

Force make to look at files before conclude to a circular dependency

I have a circular dependency using make:
CC = gcc
IFLAGS = -Iinclude
CFLAGS = -Wall -g -c -fPIC -pedantic
AFLAGS = -shared
LFLAGS =
VERSION = $(shell cat desc/major).$(shell cat desc/minor).$(shell cat desc/patch)
DFLAGS = -D_XOPEN_SOURCE=700 -DLTKVER=\"$(VERSION)\"
OBJECTS = $(patsubst src/%.c,tmp/%.o, $(shell ls -1 src/*.c))
#OUTPUT = tmp/$(lastword $(subst /, ,$(shell pwd)))
OUT_BIN = install/usr/lib/libLTK.so
OUT_MAN = $(patsubst man/%,install/usr/share/man/%.gz, $(shell find man -type f))
PATH_INCLUDE = install/usr/include/LTK-$(VERSION)
OUT_INCLUDE = $(patsubst %,$(PATH_INCLUDE)/%, $(shell find include -type f -printf "%f\n"))
PC = %
all: $(OUT_BIN) $(OUT_MAN) $(OUT_INCLUDE)
# chmod 755 install/usr/lib/libLTK.so.$(VERSION)
ln -sf install/usr/lib/libLTK.so.$(VERSION) install/usr/lib/libLTK.so
# chmod 755 install/usr/include/LTK-$(VERSION)
# chmod 644 install/usr/include/LTK-$(VERSION)/*
ln -sf install/usr/include/LTK-$(VERSION) install/usr/include/LTK
$(OUT_BIN): $(OBJECTS)
mkdir -p $(shell dirname $#)
$(CC) $(AFLAGS) -o $#.$(VERSION) $^ $(LFLAGS)
tmp/%.o : src/%.c
mkdir -p $(shell dirname $#)
$(CC) $(CFLAGS) -o $# $< $(DFLAGS) $(IFLAGS)
install/usr/share/%.gz : %
mkdir -p $(shell dirname $#)
gzip -c $< > $#
.SECONDEXPANSION:
%.h : $$(patsubst $(PATH_INCLUDE)/$$(PC),include/$$(PC),$$#)
mkdir -p $(shell dirname $$#)
cp $< $$#
clean:
rm -rf tmp install
At second expansion header files, prerequisites are generated from second expansions.
But it's a header that generates another and this new one can be found on the disk.
But make rather prefers to consider a circular dependency and ignore it.
How can I force make to see that the file exists before it searches a target to generate it?
Circular dependences are completely independent of what exists on the disk or doesn't exist on the disk. When make runs it parses the makefile and constructs a graph representing the dependency relationship between targets. This graph must be acyclic, because make will walk the graph looking for whether targets are out of date. If there's a cycle in the graph, then make would recurse forever trying to walk the graph.
For example:
a: b ; touch $#
b: a ; touch $#
It doesn't matter whether these files exist or not: make still needs to be sure that "a" is newer than "b" to satisfy the first dependency, and that "b" is newer than "a" to satisfy the second dependency.
This cannot ever be true, obviously.
Finally resolved by substituing $(OUT_INCLUDE) to %.h.
The goal to auto copy include files is preserved.
Substitued this:
.SECONDEXPANSION:
$(OUT_INCLUDE) : $$(patsubst $(PATH_INCLUDE)/$$(PERCENT),include/$$(PERCENT),$$#)
mkdir -p $(shell dirname $#)
cp $< $#
For this:
.SECONDEXPANSION:
%.h : $$(patsubst $(PATH_INCLUDE)/$$(PC),include/$$(PC),$$#)
mkdir -p $(shell dirname $$#)
cp $< $$#
But I'm still asking myself on "is there anything to force file before dependency".
After looking at the code it looks like no, unless I omit something.

Buidling a new package for buildroot: hub-ctrl

I'm trying to build a new package for using in buildroot this useful program to power on/off the different USB ports from the raspberry pi.
The GIT repository is on this site:
https://github.com/codazoda/hub-ctrl.c
And this is the hub-ctrl.mk I've built:
################################################################################
#
# hub-ctrl
#
################################################################################
HUB_CTRL_VERSION = 42095e522859059e8a5f4ec05c1e3def01a870a9
HUB_CTRL_SITE = https://github.com/codazoda/hub-ctrl.c
HUB_CTRL_SITE_METHOD = git
HUB_CTRL_LICENSE = GPLv2+
define HUB_CTRL_BUILD_CMDS
$(TARGET_MAKE_ENV) $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(#D)
endef
define HUB_CTRL_INSTALL_TARGET_CMDS
# Install predictead application
$(INSTALL) -m 4755 -D $(#D)/hub-ctrl $(TARGET_DIR)/usr/sbin/hub-ctrl;
endef
$(eval $(generic-package))
Up to now, everything is ok. But I realize that the repository it doesn't have a Makefile, so I decided to build one on my own, but I have errors. I don't know how to link the include and library folder. I'm not an expert building makefiles so I need some help. This is my Makefile:
PROJECT_ROOT = .
OUTDIR = $(PROJECT_ROOT)/bin
BASE_NAME = hub-ctrl
NAME = $(BASE_NAME)$(D)
OBJ = $(BASE_NAME).o
INC =
LIBS = -lusb
MKDIR = mkdir -p
MV = mv
# Master rule
.PHONY: all
all: $(NAME)
# Output binary
$(NAME): $(OBJ)
$(CC) $(CFLAGS) $(INC) $(OBJ) -o $(BASE_NAME) $(LIBS)
-#$(MV) $(BASE_NAME) $(OUTDIR)/$(BASE_NAME)
rm *.o
# Intermediate object files
$(OBJ): %.o: %.c
#$(MKDIR) $(OUTDIR)
$(CC) $(CFLAGS) $(LIBS) $(INC) -c $<
# Cleanup intermediate objects
.PHONY: clean_obj
clean_obj:
rm -f $(OBJ)
#echo "obj cleaned up!"
# Cleanup everything
.PHONY: clean
clean: clean_obj
rm -rf $(OUTDIR)/$(BASE_NAME)
#echo "all cleaned up!"
This is the error I've got:
hub-ctrl.c:12:17: fatal error: usb.h: No such file or directory
#include
^
compilation terminated.
Any suggestion?
Best regards.
I've followed the indications of Peter Korsgaard. I'm using the package uhubctl from buildroot-2017.11-rc1 and I've added this package to my buildroot-2016.02 custom platform. Everything is working fine, and I'm able to power off the usb ports in my HW platform.
Thank you very much to Peter Korsgaard for his advice.

How to install own app on Ubuntu

I created an app on my Windows machine and now I want to install it on my Linux machine. It has several headers and source files so I thought it is best to upload it on Github. I did that and I also created a Makefile, but I get a lot of errors when I try to install it directly from the folder.
Given the fact that it is for personal use only, is there a way to manually compile each file and then run it as a whole?
Makefile:
.PHONY: all debug profile install uninstall clean
all: $(PROG)
$(PROG): $(FILES)
$(CC) $(CCFLAGS) -o $(PROG) $(FILES) $(LIBS)
debug: $(FILES)
$(CC) $(DEBUGFLAGS) -o $(PROG) $(FILES) $(LIBS)
profile: $(FILES)
$(CC) $(CCFLAGS) -pg -o $(PROG) $(FILES) $(LIBS)
install: $(PROG)
cp -f $(PROG) /usr/sbin/
cp -f $(PROG).1 /usr/man/man1/ || cp -f $(PROG).1 /usr/local/man/man1/
uninstall:
rm -f /usr/sbin/$(PROG)
rm -f /usr/man/man1/$(PROG).1 || rm -f /usr/local/man/man1/$(PROG).1
clean:
rm -f $(PROG)
While your basic approach is fine, you are missing a couple of details, and you are breaking a few conventions that were established for a reason.
Details:
Your definitions for $(PROG), $(FILES) and $(LIBS) aren't included.
You try to copy a file to a directory without ensuring its existence. The install utility is often used instead of cp to handle stuff like this.
Conventions:
You don't appear to use root privileges only when necessary. Compile as a regular user; only run make install as root, e.g. using sudo; or better, avoid even that.
You're trying to place files into /usr/bin/ and /usr/man, where the package management system installs files, so you risk confusing it. Don't. If you need to make third-party software, such as your own, available to all users on the system, just install to /usr/local/ or /opt, which exist for this purpose. Adjust $PATH and $MANPATH accordingly. If it's just for your own personal use, you can install to directories under $HOME.
Make the top level target directory to install to a variable in your Makefile. It is often called $(DESTDIR).

My makefile builds dependency files when not required - why?

I'm trying to create a generic makefile to build static libraries that my project uses. I've used the expertise on this site, as well as the GNU Make manual to help write the following makefile. It is working well apart from one annoying problem.
# Generic makefile to build/install a static library (zlib example)
ARCH = linux
CFLAGS = -O3 -Wall
# List of source code directories
SOURCES = src test utils
# List of header files to install
INCLUDES = src/zlib.h src/zconf.h
# Library to create
LIBNAME = libz.a
############################################################
BUILD_DIR = build/$(ARCH)
# Full path to the built library
TARGET = $(BUILD_DIR)/$(LIBNAME)
prefix = ../..
exec_prefix = prefix
libdir = $(prefix)/lib/$(ARCH)
includedir = $(prefix)/include
INSTALL_PROGRAM = install -D
INSTALL_DATA = $(INSTALL_PROGRAM) -m 644
CFILES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.c))
OBJECTS := $(addprefix $(BUILD_DIR)/,$(CFILES:.c=.o))
DEPENDS := $(OBJECTS:.o=.d)
.PHONY: all installdirs install uninstall clean
# Default
all: $(DEPENDS) $(TARGET)
# Build the dependency files
# (GNU Make Manual 4.14 Generating Prerequisites Automatically)
$(BUILD_DIR)/%.d: $(BUILD_DIR)
#echo "build dep for $*.c as $#"
#$(CC) -M $(CFLAGS) $*.c > $#.tmp
#sed s~.*:~"$(BUILD_DIR)/$*.o $#:"~ $#.tmp > $#
#rm $#.tmp
# Link all changed object files into static library
$(TARGET): $(OBJECTS)
$(AR) -rc $(TARGET) $?
# Compile C source to object code
$(BUILD_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
# Create the necessary directory tree for the build
$(BUILD_DIR):
#for p in $(SOURCES); do mkdir -p $(BUILD_DIR)/$$p; done
# Create the necessary directory tree for installation
installdirs:
#mkdir -p $(libdir)
#mkdir -p $(includedir)
# Install the library and headers
install: all installdirs
$(INSTALL_DATA) $(TARGET) $(libdir)
for p in $(INCLUDES); do $(INSTALL_DATA) $$p $(includedir); done
# Remove the library and headers
uninstall:
rm -f $(libdir)/$(LIBNAME)
for p in $(notdir $(INCLUDES)); do rm -f $(includedir)/$$p; done
# Remove all build files
clean:
rm -fr $(BUILD_DIR)
# Pull in the dependencies if they exist
# http://scottmcpeak.com/autodepend/autodepend.html
-include $(DEPENDS)
The problem is that the dependency files are built when they don't need to be. e.g. make install shown below rebuilds the .d files before installing.
$make --version
GNU Make 3.81
$make
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
...
{ continues on making the other .d files, then the .o files }
...
cc -O3 -Wall -c src/zutil.c -o build/linux/src/zutil.o
cc -O3 -Wall -c test/test.c -o build/linux/test/test.o
cc -O3 -Wall -c utils/utils.c -o build/linux/utils/utils.o
ar rc { ... .o files ... }
All good up to this point! But a 'make install' now will rebuild the .d files
$make install
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
{ ... }
install -D -m 644 build/linux/libz.a ../../lib/linux
for p in src/zlib.h src/zconf.h; do install -D -m 644 $p ../../include; done
I tried to 'touch' the .d files when the objects are built, so the update time is newer than the .o files, but that had no effect. What's wrong with my makefile?
The problem is that you include the dependency files (whatever.d), and you also have a rule for building these files. So every time you use this makefile, no matter what target you specify, it will rebuild them, include them, and execute again.
Try this for an approach to dependency handling that solves this problem. Basically, you don't need a separate rule for foo.d, just make it a side effect of the foo.o rule (it takes some thought to realize that this will work).

Resources