How can I give permissions in a basic makefile - linux

How do I add permissions to this simple make file?
all: shell ls cat groups
shell: shell.o cd.o
gcc shell.o cd.o -o shell
cat: cat.o
gcc -c cat.c -o cat
ls: ls.o header.h
gcc -c ls.c -o ls
groups: groups.o groups.h
gcc -c groups.c -o groups
shell.o: shell.c tlpi_hdr.h
gcc -c shell.c
cd.o: cd.c tlpi_hdr.h
gcc -c cd.c
cat.o: cat.c tlpi_hdr.h
gcc -c cat.c
ls.o: ls.c header.h
gcc -c ls.c
groups.o: groups.c groups.h
gcc -c groups.c
clean:
rm *.o shell cat ls groups
I need to run cat/ls/groups/cd within the shell that I created, but can't because it doesn't have permissions. How can I do this?

As an example, this rule:
groups: groups.o groups.h
gcc -c groups.c -o groups
tells GCC to produce an object file called groups (instead of the normal groups.o) because you included the -c option. Object files are not executables, so the compiler doesn't make them executable, hence your problem with the permissions. Note that the rule requires make to build groups.o, but then proceeds to ignore the object file because it recompiles the source code.
You wanted to write something more like:
groups: groups.o
gcc groups.o -o groups
groups.o: groups.h
You need to use a lot more macros — or you could leave the rules out of the makefile since make knows how to build groups from groups.c.
You should also be compiling with warning options. At minimum -Wall; preferably -Wall -Wextra -Werror (and I use still more options than these). You might want optimization (-O3); you might want debugging (-g). These are normally handled via setting macros and then using them in the commands.

Related

New versions of LD cannot take ELF files as input to link

I have been working on a 32-bit operating system project written in C using GNU LD version 2.34 as the linker.
As part of the build process, I use the following command:
ld -m elf_i386 -nostdlib -T ld/loader.ld build/bootloader/loader.o build/bootloader/loader.elf -o loader_full.elf
When using GNU LD version 2.34, this command succeeds. However, when I use a version higher than this, I get the following error:
ld: cannot use executable file 'build/bootloader/loader.elf' as input to a link
If necessary, here is the full Makefile script:
CC_FLAGS = -g -m32 -ffreestanding -nostartfiles -nostdlib -fno-stack-protector
LD_FLAGS = -m elf_i386 -nostdlib
CC := gcc ${CC_FLAGS}
LD := ld ${LD_FLAGS}
BOOTLOADER_DRIVERS = kernel/drivers/disk/ata.c kernel/drivers/io/screen.c kernel/drivers/utils/mem.c kernel/drivers/utils/ports.c
raw: prep os-image.bin
convert_vmdk: os-image.vmdk
all: prep os-image.bin
ESFS_raw_write: ESFS_raw_write.c
gcc $^ -o $#
# run OS in QEMU
run:
qemu-system-i386 -drive format=raw,file=os-image.bin
# assemble boot sector
build/bootloader/boot_sect.bin: boot/boot_sect.asm
nasm $^ -f bin -o $#
# compile second stage bootloader
build/bootloader/loader_2.o build/drivers/*.o: boot/*.c ${BOOTLOADER_DRIVERS}
${CC} -c $^
mv loader.o build/bootloader/loader_2.o
mv *.o build/drivers/
# link object files into kernel loader
build/bootloader/loader.elf: build/bootloader/loader_2.o build/drivers/*.o
${LD} -T ld/loader.ld $^ -o $#
rm build/bootloader/loader_2.o
# assemble first stage bootloader
build/bootloader/loader.o: boot/loader.asm
nasm $^ -f elf -o $#
# link first and second stage bootloaders
build/bootloader/loader_full.elf: build/bootloader/loader.o build/bootloader/loader.elf
${LD} -T ld/loader.ld $^ -o $#
# make bootloader binary file
build/bootloader/loader.bin: build/bootloader/loader_full.elf
objcopy $^ -O binary $#
./scripts/pad_loader.sh
# clean up unnecessary files
# rm build/bootloader/*.o build/bootloader/*.elf build/drivers/*.o
build/kernel/interrupt.o: kernel/cpu/interrupt.asm
nasm $^ -f elf -o $#
# compile kernel & write to 10MB raw drive image
build/kernel/hdd.bin: kernel/drivers/*/*.c kernel/cpu/*.c kernel/libc/*.c build/kernel/interrupt.o kernel/*.c
${CC} $^ -o build/kernel/kernel.o -T ld/kernel.ld
./scripts/write_kernel_to_drive.sh
# concat 3 boot stages into os-image file
os-image.bin: build/bootloader/boot_sect.bin build/bootloader/loader.bin build/kernel/hdd.bin
cat $^ > $#
os-image.vmdk:
VBoxManage convertfromraw os-image.bin os-image.vmdk --format VMDK
VBoxManage internalcommands sethduuid /home/tim/Dev/OSDev/os-image.vmdk 6372c00a-a62e-4241-9a21-90fa4c22f019
# prepare directory structure for build process
prep:
mkdir -p build/bootloader
mkdir -p build/drivers
mkdir -p build/kernel
# clean up build files and os-image binary
clean:
-rm -rf build/
-rm *.bin *.vmdk
-rm ESFS_raw_write
The project is also on GitHub, so you can build it for yourself:
http://github.com/TimCve/OSDev.git
I have just come up with a similar problem.
It seems ld version GNU ld (GNU Binutils) 2.36.1 links the file into an executable format.
To fix it, add -r in your ld command to output a relocatable format file.
From the ld manual:
-r
--relocateable
Generate relocatable output--i.e., generate an output file that can in turn serve as input to ld. This is often called partial linking. As a side effect, in environments that support standard Unix magic numbers, this option also sets the output file's magic number to OMAGIC. If this option is not specified, an absolute file is produced. When linking C++ programs, this option will not resolve references to constructors; to do that, use -Ur. This option does the same thing as -i.
It's not that ld can't take ELF files as input. It's that it won't take executable files as input. The error is:
ld: cannot use executable file '...' as input to a link
See https://sourceware.org/bugzilla/show_bug.cgi?id=26223
Does it work to simply use chmod -x $# after building the .elf file?
In my (eclipse-based) multicore MCUXpresso project, I had to add this line to my post-build steps to modify a byte inside of the generated "*.o" file so the linker step which used that file wouldn't complain anymore. This happened after I updated to version 11.6 which includes the LD version mentioned previously. I originally found this on the forums for NXP MCUXpresso, but I assume it will work similarly for just about anyone:
dd if=/dev/zero of="${BuildArtifactFileName}.o" bs=1 seek=16 conv=notrunc count=2
NXP MCUXpresso fix

I'm trying to use XROTOR, need to use a Makefile but ifort: command not found

I am about 3 hours new to Linux/Cygwin/virtually anything even borderline computer science. I have been tasked with installing a program for rotors/propellers for research (XROTOR), but I cannot figure out how to run the program. It seems to have been developed in Fortran (maybe?), and came with a README. The README is asking me to build the file, but I have no clue what that means. I have downloaded Cygwin, and have gotten as far as the "make libPLT.a" line. I then cd'ed to the bin folder, and typed in "make xrotor" like the README states, but I keep getting the following error:
$ make
ifort -c -I../src -O -static ../src/xrotor.f
sh: ifort: command not found
make: *** [Makefile:147: xrotor.o] Error 127
I've included the README as well. I don't know what I'm doing, and I figured this was a decent place to start. Any help is GREATLY appreciated!!!
EDIT: Left the README out for whatever reason, sorry. I've written it out here:
General
XROTOR and its plot library should compile on any Unix system
with normal Fortran-77, C, and X-Windows support. So far,
XROTOR has been tested on the following systems:
DEC-5000
Alpha
SGI
* Sun
* RS/6000
* HP-9000
* Pentium/Linux
The systems marked with "*" have peculiar features which require slight
modifications to the Makefiles in the plotlib/ and bin/ directories.
Examine these Makefiles before building the plot library and Xrotor.
Build Sequence
To install, first build the plot library in ./plotlib ...
% cd plotlib
% make libPlt.a
Then build the programs in ./bin ...
% make xrotor
% make jplot
The README is missing some details, but you need to compile the program from sources,
and to do so you need to adjust some variables in the Makefile's
As prerequisite for compiling you need gcc-fortran,make and library libX11-devel
plus the X11 system for the graphic. Installing xinit is a good start.
$ tar -xf Xrotor7.55.tar.tgz
$ cd Xrotor
$ cd plotlib
than modify config.make to set PLTLIB = libPlt.a
I used my preferred editor, but other are also ok
$ vim config.make
To build:
$ make libPlt.a
gfortran -c -O2 -fdefault-real-8 plt_base.f
gfortran -c -O2 -fdefault-real-8 plt_font.f
gfortran -c -O2 -fdefault-real-8 plt_util.f
gfortran -c -O2 -fdefault-real-8 plt_color.f
gfortran -c -O2 -fdefault-real-8 set_subs.f
gfortran -c -O2 -fdefault-real-8 gw_subs.f
gfortran -c -O2 -fdefault-real-8 ps_subs.f
gcc -c -O2 -DUNDERSCORE Xwin.c
gfortran -c -O2 -fdefault-real-8 plt_old.f
gfortran -c -O2 -fdefault-real-8 plt_3D.f
ar r libPlt.a plt_base.o plt_font.o plt_util.o plt_color.o set_subs.o gw_subs.o ps_subs.o Xwin.o plt_old.o plt_3D.o
ar: creating libPlt.a
ranlib libPlt.a
Than moving to program build directory
$ cd ../bin
again modify Makefile.gfortran to set PLTOBJ = ../plotlib/libPlt.a and LIBS = -L/usr/lib -lX11
$ vim Makefile.gfortran
and build all program in one shot
$ make -f Makefile.gfortran
gfortran -c -I../src -O ../src/xrotor.f
gfortran -c -I../src -O ../src/xoper.f
gfortran -c -I../src -O ../src/xdesi.f
gfortran -c -I../src -O ../src/xmodi.f
...
gfortran -c -I../src -O ../src/plotdata.f
gfortran -o xrotor xrotor.o xoper.o xdesi.o xmodi.o xaero.o xjmap.o xio.o xnoise.o xrotpl.o xcasepl.o xbend.o xinte.o xutils.o jputil.o plutil.o modify.o srclin.o spline.o userio.o vortex.o plotdata.o ../plotlib/libPlt.a -L/usr/lib -lX11
gfortran -c -I../src -O ../src/jplot.f
../src/jplot.f:107:72:
PAUSE 'Hit return to see J values'
1
Warning: Deleted feature: PAUSE statement at (1)
../src/jplot.f:112:72:
PAUSE 'Hit return to see CP values'
1
Warning: Deleted feature: PAUSE statement at (1)
gfortran -o jplot jplot.o xutils.o jputil.o userio.o ../plotlib/libPlt.a -L/usr/lib -lX11
gfortran -c -I../src -O ../src/jplote.f
gfortran -o jplote jplote.o xutils.o jputil.o userio.o ../plotlib/libPlt.a -L/usr/lib -lX11
The Warning means that the PAUSE command does not exist anymore so the progran will
likely not pause on the expected locations.
This could explain why it is not working as expected, but probably as the code is very old some code assumptions about the Unix system are not anymore valid.
Running it after starting the Xwindow graphic system from inside a Xterm
$ ./xrotor
=========================
XROTOR Version 7.55
=========================
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
STOP COLORSPECTRUM: Non-monotonic color axis. Check COLWIDTH.
Need to edit the COLORSPECTRUMTRP subroutine xrotor/plotlib/plt_color.f. Add the following after line 508
COLWIDTH=(/1.0,1.20000005,0.5,1.4,1.0,1.20000005,1.5/)

<command-line>:0:1: error: macro names must be identifiers ........ Solution for this error?

I am trying to interface ssd1963 LCD with Raspberry Pi3 model B+, by following this guide on Github.
https://github.com/matusnovak/rpi-tftgl
While trying to install the makefile provided for rpi-tftgl in rpi-tftgl/tftgl directory I am getting this error when I run make command.
Here is the link of my captured image of pi terminal window showing the exact error:
Following is the error i recieved when I execute make command :
gcc -c src/tftgl.c -o src/tftgl.o -I/opt/vc/include -I. -Iinclude -D:0 -O3
<command-line>:0:1: error: macro names must be identifiers
Makefile:18: recipe for target 'src/tftgl.o' failed
make: *** [src/tftgl.o] Error 1
Can I get a solution for this or any recommendation for any other source or links which I can follow to interface ssd1963 LCD with touch enabled with Raspberrypi3.
Adding the makefile,
CC=gcc
AR=ar
DISPLAY?=ERROR
CFLAGS=-I/opt/vc/include -I. -Iinclude -D$(DISPLAY) -O3
prefix?=/usr/local
.PHONY: default all clean
default: tftgl
all: default
tftgl: libtftgl.a
libtftgl.a: src/tftgl.o
$(AR) rcs libtftgl.a src/tftgl.o
src/tftgl.o: src/tftgl.c src/tftgl_ssd1963.h src/tftgl_ads7843.h
$(CC) -c src/tftgl.c -o src/tftgl.o $(CFLAGS)
install: tftgl
install -m 0755 libtftgl.a $(prefix)/lib
install -m 0644 include/tftgl.h $(prefix)/include
clean:
-rm -f src/*.o
-rm -f libtftgl.a
I am providing here link to tftgl.c,
https://github.com/matusnovak/rpi-tftgl/blob/master/tftgl/src/tftgl.c
The (writer of) the Makefile doesn't take into account that the environment variable DISPLAY can be defined to something else than a macro definition. As it's not documented whether and how you'd need to define it, the best you can do is to make with the variable unset:
(unset DISPLAY; make)
If you prefer to change the makefile, just remove the ? from DISPLAY?=ERROR, leaving DISPLAY=ERROR.

Swap unix compiler flags with a shorter one

I've been running ns3 sumulations in linux and every time I compiled I had to type
g++ -Wall -o simulacija simulacija.cc -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE `pkg-config --libs --cflags
libns3.16-core-debug libns3.16-network-debug libns3.16-applications-debug libns3.16-internet-debug
libns3.16-point-to-point-debug libns3.16-point-to-point-layout-debug libns3.16-csma-debug
libns3.16-csma-layout-debug libns3.16-topology-read-debug libns3.16-wifi-debug`
Is there a way to shorten the flags to eg:
g++ -Wall simulacija.cc -o simulacija -my_params
Thank you
The GCC compiler supports the # notation to embed a sequence of arguments inside a file. Read near end of GCC overall options page.
So you could put in some file params.args the following lines
-Wall
-I /usr/local
-DNS3_ASSERT_ENABLE
-DNS3_LOG_ENABLE
-O
and just invoke
g++ #params.args simulacija.cc -o simulacija
You could have a Makefile rule to build that params.args (e.g. with pkg-config etc...)
Actually, it is time to learn how to use GNU make.
Notice that the # option is not understood by some other compilers like GCC handles it.
You can create a shell script myparams.sh that outputs your parameters:
#!/bin/sh
echo -n "-DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE"
pkg-config --libs --cflags libns3.16-core-debug [...]
Now you can run
g++ -Wall simulacija.cc -o simulacija `./myparams.sh`
(Don't forget to chmod +x myparams.sh)

Can't seem to install id3v2 on linux, doesn't seem to be any errors

I'm tryin to follow the direction to install id3v2. I installed id3lib and did not receive any errors. I now try to do "make" and then "make install" as they suggest that I do.
I get the following responses when I go through the process.
I was under the assumption that I would be able to use the program by typing "id3v2 ....."
However, it seems that the system doesn't find the command. Does that mean the program was not installed? If so, how would I try to find a solution?
[root#ip-xxx-xxx-xxx-xxx id3v2-0.1.12]# make
g++ -Wall -I/opt/local/include/ -DVERSION="\"0.1.12\"" -c -o convert.o convert.cpp
g++ -Wall -I/opt/local/include/ -DVERSION="\"0.1.12\"" -c -o list.o list.cpp
g++ -Wall -I/opt/local/include/ -DVERSION="\"0.1.12\"" -c -o id3v2.o id3v2.cpp
g++ -Wall -I/opt/local/include/ -DVERSION="\"0.1.12\"" -c -o genre.o genre.cpp
g++ -L/opt/local/lib/ -pedantic -Wall -g -o id3v2 convert.o list.o id3v2.o genre.o -lz -lid3
[root#ip-xxx-xxx-xxx-xxx id3v2-0.1.12]# make install
install -c -s id3v2 /opt/local/bin/id3v2
nroff -man id3v2.1 > /opt/local/share/man/man1/id3v2.1
[root#ip-xxx-xxx-xxx-xxx id3v2-0.1.12]# id3v2
-bash: id3v2: command not found
I've looked at the make file itself and it says:
install: all
install -c -s id3v2 ${PREFIX}/bin/id3v2
nroff -man id3v2.1 > ${PREFIX}/share/man/man1/id3v2.1
The Prefix hard coded into the make file is:
/opt/local
Now I think it must be true that it is installing it in the wrong directory. Is it normal to adjust the Makefile? am I barking up the wrong tree?
Most likely path where you installed is not in $PATH. You can either call it with the full path:
/opt/local/bin/id3v2
or add this path to your $PATH:
export $PATH=$PATH:/opt/local/bin
To make it permanent append this line to $HOME/.profile

Resources