Gnu Make >$* and $* meaning - c

i stumbled upon a Makefile that look weird i couldn't understand it
here is the that Makefile
AS=as -32 -Iinclude
LD=ld -m elf_i386
CC=gcc -m32 -fno-pie -fno-stack-protector
CPP=gcc -E -nostdinc -Iinclude
CFLAGS=-W -nostdlib -Wno-long-long -I include -fomit-frame-pointer
.s.o:
${AS} -a $< -o $*.o >$*.map
all: boot setup
boot: boot.o
${LD} --oformat binary -N -e start -Ttext 0x0000 -o boot $<
setup: setup.o
${LD} --oformat binary -N -e start -Ttext 0x0000 -o setup $<
clean:
rm -f boot setup *.o *.map
the part that i didn't understand is this
.s.o:
${AS} -a $< -o $*.o >$*.map
what is the significance of .s.o in this case
and what this $*.o >$*.map trying to do.

.s.o: is a suffix rule that exists for compatibility with old versions of make. It is the same as the pattern rule %.o : %.s . $* is an automatic make variable containing the base of the source file name (in this case the filename without the extension .o).
The command generated for processing boot.s to boot.o would be:
as -32 -Iinclude -a boot.s -o boot.o >boot.map
GNU Assembler(AS) option -a generates a listing file to standard output. Standard output is being redirected by the *nix shell (via >) to a file name ending in .map. The end result in this example is that boot.s will be assembled to an object file called boot.o and standard output will be written to the file boot.map
Note: I personally would have redirected standard output to a file name with the extension .lst rather than the .map extension.

Related

no rule to make target needed by x.o NASM and producing .o file as output. What mean by tthis error -- How to correct it

I am getting error
No rule to make target 'kernel-entry.asm', needed by 'kernel-entry.o'. Stop.
Can .asm file containing assembly instructions get converted to .o file? I did not no
from this page
Makefile: no rule to make target '*.o', needed by '*'. Stop
its say I have to include $(CFLAGS)
After making chages My make file looks like this
# $# = target file
# $< = first dependency
# $^ = all dependencies
# First rule is the one executed when no parameters are fed to the Makefile
CFLAGS= -Wall -g
all: run
kernel.bin: kernel-entry.o kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
kernel-entry.o: kernel-entry.asm
nasm $(CFLAGS) $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $#
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: mbr.bin kernel.bin
cat $^ > $#
But the error No rule to make target 'kernel-entry.asm', needed by 'kernel-entry.o'. Stop. did not go away. What I am doing wrong?
How to correct the error. Thanks for help
Update
Yes my kernel-entry file was .c I made it .asm and removed -CFLAGS because I was getting invalid NASM flags on CFLAGES Now I am getting this error
warning: overriding recipe for target 'abc.bin'
Makefile:4: warning: ignoring old recipe for target 'abc.bin'
nasm kernel-entry.asm -f elf -o kernel-entry.bin
kernel-entry.asm:2: error: invalid directive line
make: *** [Makefile:11: kernel-entry.bin] Error 1
are -f elf -o in above line are directives? What they are used for. is above error saying that -f elf -o are invalid. what above even means?
This is my make file thats generating error after Update above
all: run
abc.bin:abc.asm
nasm $< -f bin -o $#
kernel.bin: kernel-entry.bin kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary
kernel-entry.bin: kernel-entry.asm
nasm $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $#
abc.bin: abc.asm
nasm $< -f bin -o $#
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: abc.bin mbr.bin kernel.bin
cat $^ > $#
run: os-image.bin
qemu-system-i386 -fda $<
clean:
$(RM) *.bin *.o *.dis
The problem is that, in line 13 of your Makefile you have:
kernel-entry.o: kernel-entry.asm
nasm $(CFLAGS) $< -f elf -o $#
which states how to create (by assembling it with nasm) kernel-entry.o from kernel-entry.asm. By the way, kernel-entry.o is needed to create kernel.bin above in your makefile. But as you don't have kernel-entry.asm, the make utility complains about not being able to create kernel-entry.o because there's no existing source file to generate it (and there is no rule to generate file kernel-entry.asm, in case it could be built automatically).
You lack a source file (an assembler file called kernel-entry.asm) and you have no kernel-entry.o either, so you cannot solve the problem without providing it.
Edit
You say you made an kernel-entry.asm file from your kernel-entry.c file (I cannot guess the reason to do that, but anyway it is not important here) but at some point you lost your kernel-entry.asm file. This is what make is telling you... that it doesn't find the source file (neither kernel-entry.asm nor kernel-entry.c, to generate kernel-entry.o needed to link the final program) You can use any, or even both rules, to generate the .asm file from the .c one, and then provide the C source code.
Anyway, apart of this... the default rule (the first one in your makefile, for target all) shows that it depends on target run, which is not defined anywhere, so if you run just:
make
you will get a similar message about no rule for target run. This is because you say all depends on run, and run depends on nothing, so make assumes run (or kernel-entry.asm) must be provided by the user, or the build will fail.
Another important thing is that if you build a rule for compiling (using gcc or whatever) and you declare a set of common options for compiling .c files, there's nothing special in variable CFLAGS that makes it to be used by the compiler, so you have to rewrite all rules' commands in which you compile C code to read as the one below:
kernel.o: kernel.c
gcc $(CFLAGS) -m32 -ffreestanding -c $< -o $#
or the -Wall and -g options will never be used on compiling (CFLAGS are, by convention, compiling flags, not assembling, so use instead ASFLAGS for assembling, as compiler flags probably will not be well received by nasm)

MAKEFILE using Library : Linker command failed

Hello I can't make my Makefile working with
$(CC) $(CFLAGS) $(INC) $(OBJS) $(MLX_LNK) -o $(NAME).
got a
clang -O3 -Wall -Wextra -Werror -I -I cub3d.h src/cub3d.o src/checks/argvcheck.o src/checks/parse_map.o src/libft/basics.o src/libft/basics_bis.o src/libft/get_next_line.o src/utils/errors.o -L minilibx_opengl -lmlx -framework OpenGL -framework AppKit -o cub3D
clang: error: cannot specify -o when generating multiple output files
make: *** [cub3D] Error 1
The command on terminal I do is "make test1"
I also tried with $(CC) $(CFLAGS) -I $(HEADER) $(OBJS) $(MLX_LNK) -o $(NAME).
but got
Compiling...
clang -O3 -Wall -Wextra -Werror -I cub3d.h src/cub3d.o src/checks/argvcheck.o src/checks/parse_map.o src/libft/basics.o src/libft/basics_bis.o src/libft/get_next_line.o src/utils/errors.o -L minilibx_opengl -lmlx -framework OpenGL -framework AppKit -o cub3D
Undefined symbols for architecture x86_64:
"_init_cube", referenced from:
_init_game in cub3d.o
"_write_errors", referenced from:
_verify_line in argvcheck.o
_ft_parse_cub in argvcheck.o
_my_get_next_line in get_next_line.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Many thanks for your help
Makefile here :
NAME = cub3D
HEADER = cub3d.h
CC = clang
CFLAGS = -O3 -Wall -Wextra -Werror
INC = -I $(MLX-DIR) -I $(HEADER)
MLX_DIR = minilibx_opengl
MLX_LNK = -L $(MLX_DIR) -lmlx -framework OpenGL -framework AppKit
SRCS = src/main.c \
src/checks/argvcheck.c \
src/libft/basics.c \
src/libft/get_next_line.c \
src/utils/errors.c \
OBJS = $(SRCS.c=.o)
all: $(NAME)
mlx: $(MLX-DIR)
#echo "\033[34m-= Making libX.a... =-"
#make -C $(MLX_DIR)
$(NAME): ${OBJS} mlx
$(CC) $(CFLAGS) $(INC) $(OBJS) $(MLX_LNK) -o $(NAME)
test1: $(NAME)
$(NAME) ; ./a.out maps/test1.cub
clean:
#echo "\033[0;31mCleaning..."
rm -f $(OBJS)
# + $(B_OBJ)
# + rm -f bitmap.bmp
#echo "\033[0m"
fclean: clean
#echo "\033[34m-= Cleaning mlx... =-"
#make clean -C $(MLX_DIR)
#echo "\033[0;31mRemoving executable..."
rm -f $(NAME)
#echo "\033[0m"
re: fclean all
.PHONY: all clean fclean re
````
Well, first of all this is wrong:
OBJS = $(SRCS.c=.o)
You're missing a : here, it should be $(SRCS:.c=.o) As a result, OBJS will be empty.
Next, this is not causing you problems at the moment but is not right: you should always use $(MAKE) never a raw command like make when invoking a sub-make.
Finally, the way you've written your question by embedding results into the middle of the makefile makes it very hard to read. Please put the makefile first, then separate sections for different attempts at recipes. And you need to include the command line that make printed out (cut and paste the exact line please!) for us to see what the command being run it (with all variables expanded). Typically it becomes VERY obvious what the problem is if you look at that.
For example in this case you'd see that there are actually no object files in the link line, so it should be clear that the $(OBJS) variable is not being set properly.
EDIT
OK, thanks for showing the command line. Now, you should look at it carefully and you will see your problem :). Look at this here:
clang -O3 -Wall -Wextra -Werror -I -I cub3d.h src/cub3d.o ...
Does that look right to you? Look specifically at -I -I cub3d.h... does that seem right?
What happens is that the compiler expects a pathname to come after the -I and there isn't one, so it treats the second -I as the pathname. Then the file cub3d.h is treated as a source file, and you can't link a source file with object files.
So why does this look like this? Look at your makefile:
INC = -I $(MLX-DIR) -I $(HEADER)
so the missing thing is where $(MLX-DIR) goes. What is that variable? Well you have this:
MLX_DIR = minilibx_opengl
but this is not the same thing because it uses an underscore whereas the reference uses a dash. So, make them the same.
Then you'll see that it's not valid to put a file as an argument to -I. That takes a directory to search for header files. If you want to include the header you have to add #include "cub3d.h" in your source code, not add it to the compile line.

AVR GCC - Use static library - undefined reference errors

I'm currently trying to read values from a temperature sensor (Dallas ds18b20) with an AVR atmega328p. In order to read values, I need to import an external library (using this one). I have used the Makefile in the external repository to create a static library (libds18b20.a in lib directory). I also added the header files to my own source. I have the following Makefile:
PORT_ID=/dev/ttyACM0
MCU=atmega328p
F_CPU=1200000
CC=avr-gcc
PROGRAMMER_ID=stk500v1
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=main.c
BAUD_RATE=19200
PATH_DS18B20=./lib
all:
${CC} -L ${PATH_DS18B20} ${CFLAGS} -o ${TARGET}.bin ${SRCS}
${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex
flash:
avrdude -v -P ${PORT_ID} -b ${BAUD_RATE} -c ${PROGRAMMER_ID} -p ${MCU} -U flash:w:${TARGET}.hex
clean:
rm -f *.bin *.hex
However, when I try to run this Makefile I got the following errors (output partially omitted):
/main.c:(.text.startup+0x2e): undefined reference to `ds18b20convert'
/main.c:60: undefined reference to `ds18b20read'
These functions are defined in the headers files. I'm expecting that the static library is not properly linked. What am I doing wrong here?
I managed to get this working by omitting the -L flag and put the path directly behind the ${SRCS}-variable including the name of the static library:
PORT_ID=/dev/ttyACM0
MCU=atmega328p
F_CPU=1200000
CC=avr-gcc
PROGRAMMER_ID=stk500v1
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=main.c
BAUD_RATE=19200
PATH_DS18B20=./lib/libds18b20.a
all:
${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS} ${PATH_DS18B20}
${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex
flash:
avrdude -v -P ${PORT_ID} -b ${BAUD_RATE} -c ${PROGRAMMER_ID} -p ${MCU} -U flash:w:${TARGET}.hex
clean:
rm -f *.bin *.hex

Makefile undefined reference to library

I know this is a very common question, but no matter where I looked I couldn't find a solution that worked.
I am writing an OS, and am also writing my own version of the c standard library, purely as a general interest type thing. I have my c standard library, which currently consists only of an incomplete string.h, in the sb_libc folder in the kernel's main directory. I can't use make to actually make the kernel if it includes my string.h header. I keep getting "undefined reference to strcpy". In order to test if I could include anything, I wrote two additional files, io.c and io_asm.s, and put their *.o files into the kernel's main directory. I can link those with the kernel just fine. Clearly, my library search paths are wrong in my make file. I'll post it below. If anyone can give me an idea on what I'm doing wrong, that would be great.
OBJECTS = loader.o io.o io_asm.o kmain.o ./sb_libc/string.o
CC = gcc
CFLAGS = -e kmain -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs -Wall -Wextra -Werror -c -I./sb_libc/ -L./sb_libc/
LDFLAGS = -T link.ld -melf_i386 -I./sb_libc/ -L./sb_libc/
AS = nasm
ASFLAGS = -f elf
all: kernel.elf
kernel.elf: $(OBJECTS)
ld $(LDFLAGS) $(OBJECTS) -o kernel.elf
os.iso: kernel.elf
cp kernel.elf iso/boot/kernel.elf
genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -A os -input-charset utf8 -quiet -boot-info-table -o os.iso iso
run: os.iso
bochs -f bochsrc.txt -q
%.o: %.c
$(CC) $(CFLAGS) $< -o $#
%.o: %.s
$(AS) $(ASFLAGS) $< -o $#
clean:
rm -rf *.o kernel.elf os.iso

Is it possible to compile svdlibc on a mac (64 bit)?

I'm trying to compile svdlibc on a 64 bit mac. Running the make file returns the error message:
main.c:1: error: CPU you selected does not support x86-64 instruction set
main.c:1: error: CPU you selected does not support x86-64 instruction set
make: *** [main.o] Error 1
Which doesn't make much sense.
The make file is:
# Linux or Windows:
CC = gcc -Wall -O4 -march=i486
# CC = icc -w1 -O3 -march=i486
# Macintosh:
ifeq ($(HOSTTYPE),powerpc)
CC = cc -pipe -O3 -Wall -fno-common -arch ppc
endif
LIBS=-lm
OBJ=svdlib.o svdutil.o las2.o
svd: Makefile main.o libsvd.a
${CC} ${CFLAGS} -o svd main.o libsvd.a ${LIBS}
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
main.o: Makefile main.c svdlib.h
${CC} ${CFLAGS} -c main.c
libsvd.a: ${HOSTTYPE} ${OBJ}
rm -f $# ${HOSTTYPE}/$#
ar cr $# ${OBJ}
ranlib $#
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
svdlib.o: Makefile svdlib.h svdlib.c
${CC} ${CFLAGS} -c svdlib.c
svdutil.o: Makefile svdutil.c svdutil.h
${CC} ${CFLAGS} -c svdutil.c
las2.o: Makefile las2.c svdlib.h svdutil.h
${CC} ${CFLAGS} -c las2.c
clean:
rm *.o
$(HOSTTYPE):
if test ! -d $(HOSTTYPE); \
then mkdir $(HOSTTYPE); fi
Editing the make file to alter the -march flag lets the compilation proceed but apparently the linking fails with:
ld: lto: could not merge in main.o because Invalid ALLOCA record for
architecture x86_64
Has anyone done this? Or is there a different svd library that I should use instead? (For large sparse matrices?)
EDIT: porneL seems to have found the problem. Changing the top line in the makefile to:
CC = gcc -Wall -O3 -march=x86-64
compilation work. Haven't tested the results yet, but looks very promising.
-O4 causes this for some reason. Use -O3 instead.
You could try with port ( http://www.macports.org/ ) it seems it s availablee :
svdlibc #1.34 (math, science)
SVDLIBC is a C library to perform singular value decomposition
Basically you ll install macports then , sudo port install svdlibc.

Resources