Can't compile simple code with SDCC for pic on debian - makefile

I'm trying to compile the following code with SDCC, in Debian using only VIM and a Makefile:
void main(void) {
}
Yes, that simple, it's not working yet. I'm using a Makefile like this :
# GNU/Linux specific Make directives.
# Declare tools.
SHELL = /bin/sh
CC = sdcc
LD = gplink
ECHO = #echo
MCU = 16f88
ARCH = pic14
CFLAGS = -m$(ARCH) -p$(MCU)
LDFLAGS = -c -r -w -m I /usr/share/sdcc/lib/$(ARCH)/
EXECUTABLE = t1
SOURCES = test2.c
OBJECTS = $(SOURCES:.c=.o)
CLEANFILES = test2.o test2.asm test2.map test2.lst
.SUFFIXES: .c .o
.PHONY: clean
# Compile
all: $(EXECUTABLE)
.c.o:
$(AT) $(CC) $(CFLAGS) -o $*.o -c $<
$(EXECUTABLE): $(OBJECTS)
$(AT) $(LD) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
clean:
$(AT) rm -rf $(CLEANFILES)
After all of this the output after running the makefile is:
sdcc -mpic14 -p16f88 -o test2.o -c test2.c
gplink -c -r -w -m I /usr/share/sdcc/lib/pic14/ test2.o -o t1
make: *** [t1] Segmentation fault
I have tried more complex code with the same result,
I can't see what's wrong, anyone ?

I see several things that can be causing you problems:
When you compile for PICs using SDCC, you need the option --use-non-free because some PIC header files have a special Microchip Licence which is not GPL compatible. Furthermore, --use-non-free might not be available on Debian because of their freedom policy if you installed SDCC from repositories. You would need to install the latest SDCC from the official website.
On the linking stage, you should include the PIC libraries needed to run. Try executing sdcc -mpic14 -p16f88 --use-non-free -V test2.c. This way, SDCC links automatically and With -V (verbose) you can see the calls to assembler and linker and can see the libraries that are added on linkage.

Related

GCC ERROR: Cannot Execute Binary File [GCC Compiled from Source]

I am writing an Operating System. I am currently stuck at not being able to compile C code into output files, then further linking them with ld
When I run my make file, this error pops up:
/usr/local/i386elfgcc/bin/i386-elf-gcc -g -ffreestanding -c kernel/kernel.c -o kernel/kernel.o
/usr/local/i386elfgcc/bin/i386-elf-gcc: /usr/local/i386elfgcc/bin/i386-elf-gcc: cannot execute binary file
make: *** [kernel/kernel.o] Error 126
This is the makefile
C_SOURCES = $(wildcard kernel/*.c drivers/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o}
# Change this if your cross-compiler is somewhere else
CC = /usr/local/i386elfgcc/bin/i386-elf-gcc
GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb
LD = /usr/local/i386elfgcc/bin/i386-elf-ld
# -g: Use debugging symbols in gcc
CFLAGS = -g
# First rule is run by default
os-image.bin: boot/boot.bin kernel.bin
cat $^ > os-image.bin
# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernelStart32.o ${OBJ}
${LD} -o $# -Ttext 0x1000 $^ --oformat binary
# Used for debugging purposes
kernel.elf: boot/boot_32bit_kernel_entry.o ${OBJ}
${LD} -o $# -Ttext 0x1000 $^
run: os-image.bin
qemu-system-i386 -fda os-image.bin
# Open the connection to qemu and load our kernel-object file with symbols
debug: os-image.bin kernel.elf
qemu-system-i386 -s -fda os-image.bin &
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
# Generic rules for wildcards
# To make an object, always compile from its .c
%.o: %.c ${HEADERS}
${CC} ${CFLAGS} -ffreestanding -c $< -o $#
%.o: %.asm
nasm $< -f elf -o $#
%.bin: %.asm
nasm $< -f bin -o $#
clean:
rm -rf *.bin *.dis *.o os-image.bin *.elf
rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o
I have built GCC etc to the path: /usr/local/i386-elf-gcc
I am on macOS Monterey 12.4 (Intel - x86_64) and have all dependencies installed
I have tried looking everywhere for this problem, trying different flags and everything, however the problem still persisted
It means that the compiler you built doesn't run on the system you are running it on. You have to decide whether you want to do native compiling in which case you would build a compiler that runs on the target and also generates output for the target. This is how the compilers you usually use always work.
If you create that kind of compiler then you have to run make on the target since that's where you build the compiler to run.
Or, you can create a cross-compiler. A cross-compiler runs on your local system, but builds output that runs on the target system.
In your case, if you want to compile code on your MacOS system but generate binary files that run on a different system, you need a cross-compiler.

C++: Including an external library in Makefile

So, I have some trouble including the ncurses-library in a C++ program.
It seems my Makefile isn't set correctly and the library-functions can't be found.
I installed the library with "sudo apt-get install libncurses5-dev libncursesw5-dev" and I'm able to compile my code manually via "g++ -o output src/main.cpp -lncurses".
The compiler settings in my Makefile looked like this:
CC = g++
CXXFLAGS = -std=c++11 -Wall`
LDFLAGS =
LDLIBS = -lncurses
I'm using the "C/C++ Makefile Project" Plugin within Visual Studios Code on ubuntu.
Edit: As MadScientist explained, the second option follows the convention.
So, I found two solutions and I'm not sure which one or if any of them is the desired way of doing it:
Set LDFLAGS = -lncurses
Add $(LDLIBS) to a line in the Makefile:
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS) $(LDLIBS)

Compiling SDL project on Raspberry Pi

I am trying to build a project with make (gcc on Raspbian)
Here is the makefile (I removed some unnecessary parts):
objects = 3d.o Affichage.o [...]
cflags = -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2
poly : %(objects)
gcc $(cflags) $(objects) -o poly
($objects) : types.h
[...]
When running Make, I got:
cc -c -o Affichage.o Affichage.c
fatal error: SDL.h: No such file or directory
#include <SDL.h>
I checked the folders, everything seems ok. SDL.h is indeed in /usr/local/include/SDL2. I tried to remove options one by one in cflags, no luck...
What am I missing?
Make told you exact command it tried to execute:
cc -c -o Affichage.o Affichage.c
This don't have -I path, which is the source of an error.
You have target for your resulting executable but not for object files. Make have builtin rule to compile object files from C sources, but it isn't aware of your cflags variable. So far your options are:
Define your own pattern rule
e.g:
%.o: %.c
gcc $(cflags) -c $< -o $#
However, your cflags contains -lSDL2, which is linking flag, which should be specified only on linking phase (so technically it isn't cflag). Move it to separate variable (usually LIBS, which may then be enfolded into make's semi-standard LDFLAGS).
Use variables that make is aware of
In that case, it is CFLAGS:
CC:=gcc
CFLAGS:=-I/usr/local/include/SDL2
LIBS:=-lSDL2
LDFLAGS:=-L/usr/local/lib $(LIBS)
objects:=3d.o Affichage.o
poly: $(objects)
$(CC) $^ -o $# $(LDFLAGS)
$(objects): types.h
The rest will be done by implicit rules.

Make compiler options

I am running a 32 bit machine with Ubuntu 14.04. I want to execute sudo make to generate a C++ compiled file (gcc-4.8.4). My Makefile is
Makefile (edited based on comments from ddumbugie):
CDefines = -DLINUXGXX
COMPFLAGS =
FlameManCC = gcc
FlameManCCOpts = -O3
OBJECTS = alligator.o
COpts = $(COMPFLAGS) $(FlameManCCOpts) $(CDefines)
CC = $(FlameManCC)
alligator.o: alligator.c
$(CC) $(COpts) -c $< -o $#
Executing
make -n
gives me
gcc -O3 -DLINUXGXX -c alligator.c -o alligator.o
But
sudo make -n
gives me
DLINUXGXX -c alligator.c -o alligator.o
Definitely command DLINUXGXX is not understood. However, I need to remain a super-user for a subsequent command executed by make. How can I resolve this?
CDefines = -DLINUXGXX
COpts = -O3 $(CDefines)
alligator.o: alligator.c
$(CC) $(COpts) -c $< -o $#
It requires -o compiler options.
$# means the target. That is alligator.o.
$< means the dependency. That is alligator.c.

extra CFLAGs with Makefile

I'm reading through Foundations of GTK+ and in so doing decided to write a simple makefile that would let me run "make " to compile the example program I'd just written. I also stumbled upon a list of compiler directives here that the Gnome team specified will help moving from GTK2 to GTK3, so I wanted to include those.
I'm a make noob for all intents and purposes, so this is what I came up with:
CC = gcc
CFLAGS += -Wall
GTK_DFLAGS = -DGTK_DISABLE_SINGLE_INCLUDES -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE
GTK_CFLAGS = $(shell pkg-config --cflags gtk+-3.0)
GTK_LDFLAGS = $(shell pkg-config --libs gtk+-3.0)
%.o: %.c
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) -c -o $# $<
%: %.o
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) $(GTK_LDFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f *.o *~
And as you might guess, it doesn't work quite right. I know running pkg-config from inside the makefile isn't an ideal solution, but this is for my small-scale learning projects and not for deployment of any sort. That said, the output is weird to me; it seems like make just ignores any variables after CFLAGS.
Something like:
[patrick#blackbox ch2]$ make helloworld
gcc -Wall helloworld.c -o helloworld
helloworld.c:1:21: fatal error: gtk/gtk.h: No such file or directory
#include <gtk/gtk.h>
^
compilation terminated.
<builtin>: recipe for target 'helloworld' failed
make: *** [helloworld] Error 1
If I add have the contents of GTK_DFLAGS simply tacked onto the end of CFLAGS, they appear on the command line, but the pkg-config variables are still missing.
It's obvious to me that I messed something simple up, but after an hour of vaguely worded Googling, I'm fresh out of ideas as to what it is.
Found the answer, and of course the vocabulary I was missing when asking this question/doing earlier searches.
CC = gcc
CFLAGS += -Wall -std=c11
GTK_DFLAGS = -DGTK_DISABLE_SINGLE_INCLUDES -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE
GTK_CFLAGS := $(shell pkg-config --cflags gtk+-3.0)
GTK_LDFLAGS := $(shell pkg-config --libs gtk+-3.0)
%: %.c
$(CC) $(CFLAGS) $(GTK_DFLAGS) $(GTK_CFLAGS) $(GTK_LDFLAGS) -o $* $*.c
.PHONY: clean
clean:
rm -f *~
This does what I want, which is to compile a single .c file of any name into a program of the same name with the GTK flags I was looking to use.
Thanks to those who contributed!
You need a target for helloworld in your Makefile. Something like this:
helloworld: helloworld.o
$(CC) -o helloworld helloworld.o $(LDFLAGS) $(GTK_LDFLAGS)

Resources