make of de makefile haalt niks op, de files die in de makefile staan moeten lokaal aanwezig zijn. De makefile is een script om een project bestaande uit tig source files te compilen/linken tot een executable. main.c gebruikt functies uit die andere .c files, daarom zijn ze nodig.

Maar ik ga zoeken naar de ontbrekende files in de link die jij gaf.
Ik moet eerlijk zeggen dat ik zelf zo nooit een project zou publiceren, mijn voorkeur gaat uit naar complete projecten. Het komt wel overeen met zijn werkwijze, de hardware (schema's) was ook een zoektocht...

Na heel kort ernaar gekeken te hebben is mijn indruk dat de auteur het gestructureerd heeft opgezet. Algemene/herbruikbare functies (7-seg display aansturen) in aparte source files gescheiden van de specifieke functies van het project zelf. Dat is "volgens het boekje". Als je zijn complete library download zullen al zijn projecten vlekkeloos gecompiled kunnen worden verwacht ik.

Op vrijdag 29 maart 2024 14:39:08 schreef rew:
[...]In het onderhavige geval blijkt ie allerlei lib dingen te gebruiken waarvan ik niet weet waar die vandaan komen. Dus hier stopt het voor mij om het te proberen te compileren. Geen tijd om er verder in te steken.

@Rob: er was bij die auteur ergens op zijn computer een directory waarin een subdirectory AVR is en dan een file lib_clk.c

Het makefile vertelt je hoe dat ding heeft geheten op zijn systeem.

Hoe ie daaraan gekomen is... dat weet ik niet.

https://github.com/jamesfowkes/Code-Library/tree/master

In dit plaatje ontbreekt inderdaad nog steeds iets.

Het commando make wordt hier netjes uitgevoerd. Het eerste wat het make commando doet is zoeken naar met het commando meegestuurde commando's, switches en opties. Dat zijn in principe alle dingen die achter het commando make worden gezet.

Alles wordt gewoon op de command lijn gedaan zoals bij oude DOS systemen vroeger. Het commando make is eigenlijk een soort van batch controller die een hele reeks opdrachten die je anders met de hand zou moeten intypen vereenvoudigd naar het geven van een enkel commando. Alleen is make specifiek gemaakt voor commando's waarmee iets gecreëerd wordt. Het wordt dan ook veel gebruikt om software te maken. Het commando is "dat weet ik niet zeker" dacht ik afkomstig uit de multiuser unix wereld en vandaar via linux uiteindelijk ook op het aangevreten fruit en het kleinENzacht terecht gekomen toen die van single user naar multi-user overgingen.

Elk commando heeft ook input en output files. Een van de eerste dingen die bijvoorbeeld gedaan worden als je je pascal, C, of phyton programma wilt compileren is bijvoorbeeld een syntax check.
Je dan dit:

gcc Mijnnetnieuwgemaakteprogramma.c Optie1 optie2 switch1

Gcc (Is de standaard c compiler die altijd aanwezig is) start dan op, gaat zoeken naar Mijnnetnieuwgemaakteprogramma.c en gaat het als eerste lezen en controleren of er geen fouten zijn. Heb je wel fouten gemaakt dan verschijnt er een lijst foutmeldingen. De dingen als optie optie 1 switch 1 enzo zijn mogelijkheden op de compiler te vertellen wat hij met zijn zijn output moet doen. Alles op scherm dumpen is meestal standaard maar helemaal niet handig. Jij kun het niet zo snel allemaal lezen en onthouden. Je kunt dan ook je schrijffouten niet herstellen. Dus alle foutmeldingen wegschrijven naar een bestand is handiger. In de opties en switchen kun je dan opgeven hoe het error bestand moet gaan heten en in welke directory ze weggeschreven moeten worden.

En bij linux systemen en waarschijnlijk andere systemen ook. Bij dos was het minder belangrijk, is de hoofdletter gevoeligheid. In het plaatje van de TS is het waarschijnlijk fout gegaan omdat makefillert met kleine letters word aangeroepen en terwijl in de directory het bestand makefilleRT staat met twee hoofdletters aan het eind.

Arduino is eigenlijk een soort van grafische makefile. Onderhuids kun je nog steeds de compiler, linker, listprogramma enz. vinden. De output van de diverse programma's kun je nog altijd zien in het kleine zwarte schermpje onder in beeld. Vroeger zat in de arduino gui het programma avrdude verstopt dat werd aangeroepen op het moment dat men op de run knop drukte. Maar andere compilers kon je er ook in stoppen.

Alles wordt gewoon op de command lijn gedaan zoals bij oude DOS systemen vroeger.
Elk commando heeft ook input en output files.

Overigens mooie uitleg maar wel daar wel iets aan toevoegen.
Het zijn geen commando's maar gewoon programma's.
Als je bv files wil kopiëren dan doe je dat met het programma copy.
In dit geval gebruik je het programma make.

Heel vroeger stonden stonden die stukje programma in een eeporm en moest je dat oproepen met een adres. In moderne software zoals linux en windows bestaan veel val dat soort programma's nog steeds maar zie je daar bijna niets meer van.

Op vrijdag 29 maart 2024 15:36:41 schreef Ex-fietser:
[bijlage]

In dit plaatje ontbreekt inderdaad nog steeds iets.

Het commando make wordt hier netjes uitgevoerd. Het eerste wat het make commando doet is zoeken naar met het commando meegestuurde commando's, switches en opties. Dat zijn in principe alle dingen die achter het commando make worden gezet.

Alles wordt gewoon op de command lijn gedaan zoals bij oude DOS systemen vroeger. Het commando make is eigenlijk een soort van batch controller die een hele reeks opdrachten die je anders met de hand zou moeten intypen vereenvoudigd naar het geven van een enkel commando. Alleen is make specifiek gemaakt voor commando's waarmee iets gecreëerd wordt. Het wordt dan ook veel gebruikt om software te maken. Het commando is "dat weet ik niet zeker" dacht ik afkomstig uit de multiuser unix wereld en vandaar via linux uiteindelijk ook op het aangevreten fruit en het kleinENzacht terecht gekomen toen die van single user naar multi-user overgingen.

Elk commando heeft ook input en output files. Een van de eerste dingen die bijvoorbeeld gedaan worden als je je pascal, C, of phyton programma wilt compileren is bijvoorbeeld een syntax check.
Je dan dit:

gcc Mijnnetnieuwgemaakteprogramma.c Optie1 optie2 switch1

Gcc (Is de standaard c compiler die altijd aanwezig is) start dan op, gaat zoeken naar Mijnnetnieuwgemaakteprogramma.c en gaat het als eerste lezen en controleren of er geen fouten zijn. Heb je wel fouten gemaakt dan verschijnt er een lijst foutmeldingen. De dingen als optie optie 1 switch 1 enzo zijn mogelijkheden op de compiler te vertellen wat hij met zijn zijn output moet doen. Alles op scherm dumpen is meestal standaard maar helemaal niet handig. Jij kun het niet zo snel allemaal lezen en onthouden. Je kunt dan ook je schrijffouten niet herstellen. Dus alle foutmeldingen wegschrijven naar een bestand is handiger. In de opties en switchen kun je dan opgeven hoe het error bestand moet gaan heten en in welke directory ze weggeschreven moeten worden.

En bij linux systemen en waarschijnlijk andere systemen ook. Bij dos was het minder belangrijk, is de hoofdletter gevoeligheid. In het plaatje van de TS is het waarschijnlijk fout gegaan omdat makefillert met kleine letters word aangeroepen en terwijl in de directory het bestand makefilleRT staat met twee hoofdletters aan het eind.

Arduino is eigenlijk een soort van grafische makefile. Onderhuids kun je nog steeds de compiler, linker, listprogramma enz. vinden. De output van de diverse programma's kun je nog altijd zien in het kleine zwarte schermpje onder in beeld. Vroeger zat in de arduino gui het programma avrdude verstopt dat werd aangeroepen op het moment dat men op de run knop drukte. Maar andere compilers kon je er ook in stoppen.

De Make file komt ook uit een Linux omgeving. DOS kent geen "rm" commando

Ik heb aan de werkwijze nog niets veranderd, om te zien of ik vooruitgang boekte.
Ik heb de complete library van JamesF binnengezogen en in mijn map gezet.
De make file aangepast zoals ik denk dat hij moet zijn, maar nog steeds weigert makefileRT iets te gaan doen. :-(

Het is blijkbaar niet case sensitive.
Dit is hoe de makefileRT er nu uitziet:

NAME=test

AVR_DIR=C:/Compiler/bin

CC=$(AVR_DIR)/avr-gcc
MCU_TARGET=attiny84
LIBS_DIR = C:/Software_FM/JamesF_library/

OPT_LEVEL=3

ERROR_FILE="error.txt"

INCLUDE_DIRS = \
	-I$(LIBS_DIR)/AVR \
	-I$(LIBS_DIR)/Common \
	-I$(LIBS_DIR)/Devices \
	-I$(LIBS_DIR)/Generics \
	-I$(LIBS_DIR)/Utility

MAIN_FILE = main.c
CFILES = \
	$(LIBS_DIR)/AVR/lib_clk.c \
	$(LIBS_DIR)/AVR/lib_fuses.c \
	$(LIBS_DIR)/AVR/lib_tmr8.c \
	$(LIBS_DIR)/AVR/lib_tmr8_tick.c \
	$(LIBS_DIR)/AVR/lib_io.c \
	$(LIBS_DIR)/AVR/lib_shiftregister.c \
	$(LIBS_DIR)/Devices/lib_tlc5916.c \
	$(LIBS_DIR)/Generics/memorypool.c \
	$(LIBS_DIR)/Generics/ringbuf.c \
	$(LIBS_DIR)/Generics/seven_segment_map.c
	
CFILES += $(MAIN_FILE)

OPTS = \
	-g \
	-Wall \
	-Wextra \
	-DF_CPU=8000000 \

LDFLAGS = \
	-Wl

OBJDEPS=$(CFILES:.c=.o)

all: init $(NAME).elf errors

process:
	$(CC) -E $(INCLUDE_DIRS) $(MAIN_FILE)
	
init:
	@rm -f $(ERROR_FILE)
	
$(NAME).elf: $(OBJDEPS)
	$(CC) $(INCLUDE_DIRS) $(OPTS) $(LDFLAGS) -O$(OPT_LEVEL) -mmcu=$(MCU_TARGET) -o $@ $^

%.o:%.c
	$(CC) $(INCLUDE_DIRS) $(OPTS) -O$(OPT_LEVEL) -mmcu=$(MCU_TARGET) -c $< -o $@ 2>>$(ERROR_FILE)

errors:
	@echo "Errors and Warnings:"
	@cat $(ERROR_FILE)
clean:
	rm -rf $(NAME).elf
	rm -rf $(OBJDEPS)

Ziet iemand nog iets wat niet klopt? Paden heb ik volgens mij zo goed staan...

Op vrijdag 29 maart 2024 17:22:32 schreef rob040:

De make file aangepast zoals ik denk dat hij moet zijn, maar nog steeds weigert makefileRT iets te gaan doen. :-(
[bijlage]
Het is blijkbaar niet case sensitive.

Sorry.

make <iets>

probeert dat "iets" te maken. Make kijkt standaard in het file genaamed "Makefile" als dat niet bestaat in "makefile". Als je dat makefile anders wil noemen dan is het iets als "make -f makefilert" (*).

Zoals jij het (sorry op mijn aanraden)( doet vraag je make om de aanwijzingen in makefile te volgen om het bestand makefilert te maken. Make rapporteert vrolijk: Heb ik niets voor hoeven doen!

Wat het nut is van het makefile anders noemen snap ik niet. Zinloze actie die het alleen maar moeilijk maakt.

(*) Als dat het niet is dan is het met -F . Ik gebruik het vrijwel nooit.

"make clean"

Dan zal hij alle reeds gecompileerde bestanden en error bestanden verwijderen en alles opnieuw compileren en linken.

"make all"

Zou alles moeten compileren.
Maar wat ik al zei , DOS kent geen rm commando

Op vrijdag 29 maart 2024 17:31:52 schreef rew:
[...]Sorry.

make <iets>

probeert dat "iets" te maken. Make kijkt standaard in het file genaamed "Makefile" als dat niet bestaat in "makefile". Als je dat makefile anders wil noemen dan is het iets als "make -f makefilert" (*).

Zoals jij het (sorry op mijn aanraden)( doet vraag je make om de aanwijzingen in makefile te volgen om het bestand makefilert te maken. Make rapporteert vrolijk: Heb ik niets voor hoeven doen!

Wat het nut is van het makefile anders noemen snap ik niet. Zinloze actie die het alleen maar moeilijk maakt.

(*) Als dat het niet is dan is het met -F . Ik gebruik het vrijwel nooit.

Ik heb bovenstaande een aantal keer gelezen en snap er niks van. :?
Laat ik een poging doen mijn onbegrip uit te leggen. ;-)

Het renamen was puur omdat de file makefile (het origineel) al bestond. makefileRT was met door mij aangepaste paden.
Ik zou denken dat de naam niet uitmaakt, piet, jan, klaas, start, ...
Met het commando "make" vertel ik de computer wat het moet doen en dan <filename> welk bestand hij moet pakken om aan de slag te gaan. Denkfout blijkbaar...
Staat in make.exe dat hij makefile moet pakken?

Ik hoopte duidelijkheid te krijgen door wat dingen te proberen, eerst makefileRT hernoemd naar makefile.
Dan make makefile ingetoetst.
Zelfde resultaat...

Dan make -f makefile geprobeerd. Dat reageert anders:

Ook nog even hetzelfde gedaan met make -f makefileRT, maar dat geeft hetzelfde.

Dan nog met een hoofdletter F (make -F makefile). Dan komt er een foutmelding:

Nu lees ik de opmerking van Bram, rm commando's gaan mis. Toch maar de tip van Sparky uitproberen, MPlab X installeren.

Ik dacht het langzaam te begrijpen, maar het kwartje is nog niet gevallen...

Make zoekt naar een bestand "Makefile" , dus de naam maakt wel uit.
Je geeft als parameter niet mee welke makefile maar wat de makefile moet doen.

Oké, dan is dat duidelijk.
Maar dan snap ik nog niet dat als ik de file eerst rename naar makefile en ik dan make makefile intoets het nog geen jota uitmaakt...

Met het commando "make" vertel ik de computer wat het moet doen en dan <filename> welk bestand hij moet pakken om aan de slag te gaan. Denkfout blijkbaar...

Het complete commando make zal iets zijn als Make inputfile outputfile plus wat schakel opties tenmiste dat maak ik op uit wat rew zegt.

Jij denk nu dat je een inputfile heb opgegeven maar misschien heb je nu enkel de outputfile opgegeven. En ja die bestaat al dus hoeft make niets te doen.

Om meer te weten over de opties van make type eens Make -? of Make ? make h(elp) of make -h(elp). Dan geeft make heel veel info over alle mogelijkheden en opties als ook welke inputfile en outputfile het verwacht.

Hier een uitgebreide beschrijving van GNUmake.
https://www.gnu.org/software/make/manual/make.html

Bij punt 9> How to run make

By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile, makefile and Makefile.

The way to specify the name of the makefile is with the ‘-f’ or ‘--file’ option (‘--makefile’ also works). For example, ‘-f altmake’ says to use the file altmake as the makefile.

Met andere woorden als je een andere naam als makefile opgeeft dan moet je
Make -f makefileRT gebruiken.
De optie -f of --file is voor make om aan te geven wat daarna volgt dat hij dat als de makefile moet gebruiken.

Outputfile hoef je verder niet op te geven dat staat allemaal al in de makefileRT

[Bericht gewijzigd door benleentje op (30%)]

Zoals rew al zei : als je de makefile als parameter wilt opgeven dan moet je daar "-f" voorzetten.

Dus commando "make" start de make utility en gebruikt de default file Makefile als script.

Of "make -f makefileRT" gebruikt makefileRT als script.

In die makefile staat dan wat er moet gebeuren:

all: init $(NAME).elf errors

Dat betekent dat 'all' gebouwd moet worden en dat daarvoor eerst 'init', de .elf en errors gebouwd moeten worden.

Dus eerst init bouwen: Daarvoor is de regel

init:
	@rm -f $(ERROR_FILE)

Dus om init te bouwen moet het commando rm uitgevoerd worden.
Maar dat is een linux commando en die bestaat niet in windows. Dus die moet je vervangen door het windows 'del' commando:

init:
	@del $(ERROR_FILE)

rm is dan remove? En ja dat betekend verwijderen en dus delete is del

[Bericht gewijzigd door benleentje op (61%)]

Het complete commando make zal iets zijn als Make inputfile outputfile plus wat schakel opties tenmiste dat maak ik op uit wat rew zegt.

Fout. Het commando is normaal 'make target' waarbij target aangeeft wat er gebouwd moet worden. Zoals bprosman hierboven al aangaf, dat is bijv "make all" of "make clean".

De make utility gaat dan in de makefile zoeken hoe die target gebouwd moet worden. Als je een alternatieve makefile wilt gebruiken dan moet je dat aangeven middels een '-f' optie.

Dank allen weer voor de uitleg. Ik ga dat rustig 'processen'. ;-)

Op vrijdag 29 maart 2024 19:40:42 schreef deKees:
<knip>
Dus eerst init bouwen: Daarvoor is de regel

init:
	@rm -f $(ERROR_FILE)

Dus om init te bouwen moet het commando rm uitgevoerd worden.
Maar dat is een linux commando en die bestaat niet in windows. Dus die moet je vervangen door het windows 'del' commando:

init:
	@del $(ERROR_FILE)

rm vervangen door del is easy. Maar je pakt en passant de -f ook mee...
Verderop in de makefile staat ook ergens

clean:
	rm -rf $(NAME).elf
	rm -rf $(OBJDEPS)

Hier dan ook -rf meepakken?

Er begint wat te werken...
rm (-f) vervangen door del.
Daarna opnieuw make -f makefile ingegeven op de command line.
Hele rits foutmeldingen. Die kon ik herleiden, er kwam 2x // te staan, één weggehaald en nu nog een heel kort lijstje met errors:

C:/Compiler/bin/avr-gcc -IC:/Software_FM/JamesF_library/AVR -IC:/Software_FM/JamesF_library/Common -IC:/Software_FM/JamesF_library/Devices -IC:/Software_FM/JamesF_library/Generics -IC:/Software_FM/JamesF_library/Utility -g -Wall -Wextra -DF_CPU=8000000  -O3 -mmcu=attiny84 -c C:/Software_FM/JamesF_library/Generics/memorypool.c -o C:/Software_FM/JamesF_library/Generics/memorypool.o 2>>"error.txt"
make: *** [makefile:58: C:/Software_FM/JamesF_library/Generics/memorypool.o] Error 1

In de error.txt file staat:

C:/Software_FM/JamesF_library/Generics/memorypool.c:14:2: error: #error "MEMORY_POOL_BYTES must be defined!"
 #error "MEMORY_POOL_BYTES must be defined!"
  ^~~~~
C:/Software_FM/JamesF_library/Generics/memorypool.c:17:21: error: 'MEMORY_POOL_BYTES' undeclared here (not in a function); did you mean '_MEMORYPOOL_H_'?
 static uint8_t pool[MEMORY_POOL_BYTES];
                     ^~~~~~~~~~~~~~~~~
                     _MEMORYPOOL_H_
C:/Software_FM/JamesF_library/Generics/memorypool.c: In function 'MEMPOOL_GetUsed':
C:/Software_FM/JamesF_library/Generics/memorypool.c:52:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
At top level:
C:/Software_FM/JamesF_library/Generics/memorypool.c:17:16: warning: 'pool' defined but not used [-Wunused-variable]
 static uint8_t pool[MEMORY_POOL_BYTES];
                ^~~~

Iemand een idee?

rm -rf is niet helemaal 1:1 om te zetten naar een eenvoudige "DEL"

De -rf is :
f = "Forced" dus geen moelijke vragen stellen, gewoon doen.
r = recursive, dus als het een directory is , alles onderliggend ook weg gooien.

In DOS doe je dat met :

del /f /s <filenaam> (of directory).
(Overigens mag "erase" ook ipv DEL)

Wat die libraries betreft, je zult vast ergens moeten definieren wat MEMORY_POOL_BYTES is. (hoeveel).

Oké, del /f /s nog even aangepast.

Wat die libraries betreft, je zult vast ergens moeten definieren wat MEMORY_POOL_BYTES is. (hoeveel).

Chips, ik had gehoopt dat met het regeltje

MCU_TARGET=attiny84

voor de compiler duidelijk zou zijn wat te doen.
Ik heb werkelijk geen idee waar ik die informatie zou moeten vinden. Ik voel me alsof ik midden in de Sahara sta op zoek naar een moertje. :?

In de eerste regel van de van de make file staat een verwijzing naar WinAVR, heb je deze al geïnstalleerd?

AVR_DIR=C:/WinAVR-20100110/bin

https://sourceforge.net/projects/winavr/

Misschien helpt dat?

Tja, de melding is toch duidelijk genoeg?


C:/Software_FM/JamesF_library/Generics/memorypool.c:14:2: error: #error "MEMORY_POOL_BYTES must be defined!"
 #error "MEMORY_POOL_BYTES must be defined!"

Dus de compiler gaat compileren. En tijdens compileren van memorypool.c loopt de compiler vast omdat er een MEMORY_POOL_BYTES wordt gebruikt die niet bestaat.

Blijkbaar heeft de schrijver van de module een optie ingebouwd om die variabele per project in te kunnen vullen. Die moet je dan in je project makefile definieren. Dus toevoegen aan de OPTS in de makefile:


OPTS = \
	-g \
	-Wall \
	-Wextra \
	-DF_CPU=8000000 \
	-DMEMORY_POOL_BYTES=200 \

Ik zet de waarde hier op 200. Geen idee of dat in de buurt komt van wat er nodig is. Maar het lijkt erop dat het hier gaat om een memory management module die een soort van free-space memory beheert. En dan is 200 bytes wel weinig, maar een Tiny84 heeft niet meer dan 512 totaal beschikbaar.

Ha deKees,

De waarde ontbrak inderdaad in de makefile. Dat zijn dingen die ik echt niet weet.
Dank voor deze aanvulling! :-)

Ik krijg nu geen error.txt rapport meer. Maar nog wel een dingetje:

C:\Software_FM>make -f makefile
make: *** No rule to make target 'C:/Software_FM/JamesF_library/Generics/ringbuf.o', needed by 'makefile.elf'.  Stop.

Waar moet die ontbrekende rule worden neergezet en hoe ziet die er uit?

Nog een vraagje, als de compiler klaar is en er zijn geen problemen meer, waar zet hij dan de output (file die ik nodig heb om in de tiny84 te downloaden) neer?
Of is dat nou net de ringbuf.o?

ringbuf.o is de gecompileerde versie van ringbuf.c. De o staat voor object code, dat is machine code maar nog geen (complete) executable. Die ontstaat na het linken van alle .o files. Dat is dan de .elf file, die kan je in je Tiny flashen.

Ik weet die dingen ook niet. Maar ik lees de foutmelding en trek mijn conclusies. Dan zoek ik de fout op de aangegeven locatie en zie dat er een #define gebruikt wordt die geen waarde heeft.

Er is een algemene rule die zegt dat een .o file moet worden aangemaakt door de corresponderende .c file te compileren.
Die werkt blijkbaar niet voor die ringbuf.o dus het lijkt erop dat die ringbuf.c ontbreekt.

De hex code voor de target zit verstopt in de .elf file. Sommige programmers kunnen de code rechtstreeks uit die .elf file halen. Andere programmers hebben een .hex file nodig. Die kun je zelf uit de .elf halen dmv een obj_copy commando:


   avr-objcopy -O ihex -R .eeprom test.elf test.hex

Dank weer voor de uitleg.
De ringbuf.c is inderdaad in de hele library niet terug te vinden. :-(
Alleen ringbuf.cpp en ringbuf.h.
Kan ik de ringbuf.c 'maken' uit of met behulp van één van bovenstaande files?

Het renamen van ringbuf.cpp naar ringbuf.c werkt niet (dat was te makkelijk).