Oppure

Loading
03/08/16 8:00
Bonnox
Buongiorno ancora, mi spiace postare un sacco di domande ma non mi hanno mai preparato a dovere su questi argomenti...

volevo testare un semplice makefile, compilando un programma di 2 file (per stare sul semplice).

I file sono main.c , libreria.c, libreria.h e makefile. Sono tutti nella stessa cartella, diversa da quella del compilatore.

#include <stdio.h>
#include "libreria.h"

int main()
{
	mio();
	return 0;
}


#include "libreria.h"
#include <stdio.h>

void mio()
{
    printf("ciao make!");
}


#ifndef LIBRERIA_H_INCLUDED
#define LIBRERIA_H_INCLUDED

void mio ();

#endif // LIBRERIA_H_INCLUDED


ho usato codeblocks per scriverli, e di suo gestisce automaticamente i programmi con più file. ho guardato il build log e i comandi erano come me li aspettavo dopo aver letto il libro di King.
Ho provato dunque a fare da me:

hellomake: hellomake.o libreria.o
	D:\Sviluppo\mingw\bin\gcc -o "D:\programmazione\cose C\testmake\hellomake.o" "D:\programmazione\cose C\testmake\libreria.o"
hellomake.o: hellomake.c libreria.h
	D:\Sviluppo\mingw\bin\gcc -c "D:\programmazione\cose C\testmake\hellomake.c" -o "D:\programmazione\cose C\testmake\hellomake.o"
libreria.o: libreria.c libreria.h
	D:\Sviluppo\mingw\bin\gcc -c "D:\programmazione\cose C\testmake\libreria.c" -o "D:\programmazione\cose C\testmake\libreria.o"


se vado nella cartella dei sorgenti e invoco mingw32-make (è nel path) mi da questo (non uso il tag code perchè ho visto che lo colora in un modo che non si capisce niente):

D:\Sviluppo\mingw\bin\gcc -c "D:\programmazione\cose C\testmake\hellomake.c" -o "D:\programmazione\cose C\testmake\hellomake.o"
D:\Sviluppo\mingw\bin\gcc -o "D:\programmazione\cose C\testmake\hellomake.o" "D:\programmazione\cose C\testmake\libreria.o"
/sviluppo/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../…(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status
makefile:2: recipe for target 'hellomake' failed
mingw32-make: *** [hellomake] Error 1

parla di un winmain, ma io sto facendo una console application :S

poi provo a fare prima i singoli o e a metterli insieme... anche lì nessun risultato.

poi mi accorgo che il nome del primo target era diverso dai nomi del file main, così rinomino tutti i "main" nel file con "hellomake", per giungere al code che ho scritto, ma che comunque non funziona.

non riesco a capire dove sta l'errore... :d

EDIT: ho provato a mettere i percorsi assoluti anche sulle dipendenze, ma mi becco un bell'errore "multiple target patterns".
Ultima modifica effettuata da Bonnox 03/08/16 8:32
aaa
03/08/16 8:47
lumo
Per qualche motivo sembra che il tuo progetto sia impostato come win32 application, è l'unico motivo per cui il linker può richiedere WinMain.
Controlla bene, magari crea di nuovo il progetto.
aaa
03/08/16 19:56
Bonnox
ti ringrazio per avermi dedicato del tempo!


nella mia mente malata avevo pensato che "se lo rifaccio con linux funzionerà sicuramente, il gcc è già incluso" e altre robe che farebbero rivoltare stallman.

e invece continuavo a ottenere gli stessi, e nuovi, errori, ma stavolta in italiano (che bello!!)

poi ho avuto un lampo di genio: sbagliavo il primo comando. dopo -o ci va il nome dell'eseguibile, che io dimenticavo, mentre pensavo fosse una cosa come "guarda che devi trasformare questi -oggetti in un eseguibile" lol :rofl:
e infatti ora va.
non so se sentirmi entusiasta o idiota.

scusate per il post inutile :_doubt:
Ultima modifica effettuata da Bonnox 03/08/16 19:58
aaa
04/08/16 9:15
Roby94
Beh allora diamo un senso al topic, potresti migliorare il valore del tuo makefile. Primo tra tutti avere percorsi assoluti in un makefile non ha molto senso, un vantaggio non indifferente del make è di poter ricompilare su sistemi diversi con modifiche minime al make, senza dover essere legato ad un progetto di qualche IDE.

Una regola clean raramente manca.
clean:
	rm -f "Release/*.o" || true

Il classico "pulisci la soluzione".

è comodo dichiarare una regola fittizia che dipende dai file finali che vorrai vedere come output
release: Release\hellomake.exe

Che non presenta altro che dipendenze, nessuna regola di compilazione.

Un altra precisazione è di dichiarare come phony tutte le regole che non si riferiscono direttamente a file.
.PHONY: release clean

Questo evita problemi in caso siano presenti erroneamente file con questi nomi nella directory di riferimento.

Ora indipendentemente dal progetto per compilare è sufficiente un "make release", e per pulire "make clean".
aaa
04/08/16 15:55
Bonnox
Postato originariamente da Roby94:

Beh allora diamo un senso al topic, potresti migliorare il valore del tuo makefile. Primo tra tutti avere percorsi assoluti in un makefile non ha molto senso, un vantaggio non indifferente del make è di poter ricompilare su sistemi diversi con modifiche minime al make, senza dover essere legato ad un progetto di qualche IDE.



Sì esatto, infatti ho visto su internet alcuni semplici makefile e ho imparato le variabili CC e CFLAGS!
Praticamente qualuque parola in maiuscolo seguita da = diventa una variabile stringa che puoi espandere con $(), ho capito bene?

Una regola clean raramente manca.
clean:
	rm -f "Release/*.o" || true

Il classico "pulisci la soluzione".



Ok il clean l'ho già visto, tuttavia non mi sono chiari dei punti:
cosa significa " || true " ? or true? che effetto ha sul terminale?
e cosa si intende con soluzione?
(scusa la mia nabbezza)

Un altra precisazione è di dichiarare come phony tutte le regole che non si riferiscono direttamente a file.
.PHONY: release clean

Questo evita problemi in caso siano presenti erroneamente file con questi nomi nella directory di riferimento.


Ora indipendentemente dal progetto per compilare è sufficiente un "make release", e per pulire "make clean".


quindi qualunque regola che non crea file oggetto deve essere dichiarata dopo questo phony? o solo alcune regole? e poi dicendo make seguito dal nome posso eseguirla.

che tipo di problemi possono sorgere?

tuttavia non capisco a cosa serva la regola "release". se il faccio il make è perchè voglio compilare il programma, non mi importa se per la release o per il debug. anzi, quello lo regolerò con un #define, no?

grazie anche a te per l'intervento, credo che leggerò il manuale del make (o anche del gcc, nella prossima vita aha) :k:
aaa
05/08/16 18:51
Roby94
Postato originariamente da Bonnox:
Sì esatto, infatti ho visto su internet alcuni semplici makefile e ho imparato le variabili CC e CFLAGS!
Praticamente qualuque parola in maiuscolo seguita da = diventa una variabile stringa che puoi espandere con $(), ho capito bene?

Non per forza maiuscolo.
Ok il clean l'ho già visto, tuttavia non mi sono chiari dei punti:
cosa significa " || true " ? or true? che effetto ha sul terminale?
e cosa si intende con soluzione?
(scusa la mia nabbezza)

Alcuni IDE a un return false associano un errore, in caso non vi siano file da cancellare rm restituisce false, con || true evito possibili errori di questo genere.
quindi qualunque regola che non crea file oggetto deve essere dichiarata dopo questo phony? o solo alcune regole? e poi dicendo make seguito dal nome posso eseguirla.

Si, ogni regola che non genera direttamente un file andrebbe dichiarata come PHONY per evitare ambiguità, quello che è dichiarato come PHONY è SEMPRE una regola che non si riferisce ad un file, quindi il make non andrà a ricercarlo come file nella directory.
tuttavia non capisco a cosa serva la regola "release". se il faccio il make è perchè voglio compilare il programma, non mi importa se per la release o per il debug. anzi, quello lo regolerò con un #define, no?

Non vi è uno standard per make, se no avrebbe poco senso permettere cosi tanta libertà, io lo uso per la getsione sia di debug che release, e sono abbastanza contrario all'uso della define DEBUG, uso make in ambito AVR dove il debug RT è eseguibile solo con codici non ottimizzati, quindi mi fa comodo poter compilare librerie anche in modalità debug senza modificare il codice C.
Ti mostro un esempio
ATMEGA_INCLUDE="C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.0.91\include"
MCU_INCLUDE="C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.0.91\gcc\dev\atmega328p"
MCU="atmega328p"

STANDARD_OPTIONS=-x c -std=gnu99 -I $(ATMEGA_INCLUDE) -mmcu=$(MCU) -B $(MCU_INCLUDE)
ADDITIONAL_OPTIONS=-ffunction-sections -fdata-sections -fpack-struct -fshort-enums
DEBUG=-DDEBUG -O1
RELEASE=-DNDEBUG -Os
OPTIONS=$(STANDARD_OPTIONS) $(ADDITIONAL_OPTIONS)

.PHONY: all debug release clean

all: debug release

debug: Debug\libI2C.a

release: Release\libI2C.a


Debug\I2C.o: I2C.h I2C.c
	test -d "Debug" || mkdir "Debug"
	avr-gcc.exe -c $(OPTIONS) $(DEBUG) -o "Debug\I2C.o" "I2C.c"

Debug\libI2C.a: Debug\I2C.o
	avr-ar.exe -r -o "Debug\libI2C.a" "Debug\I2C.o"

Release\I2C.o: I2C.h I2C.c
	test -d "Release" || mkdir "Release"
	avr-gcc.exe -c $(OPTIONS) $(RELEASE) -o "Release\I2C.o" "I2C.c"

Release\libI2C.a: Release\I2C.o
	avr-ar.exe -r -o "Release\libI2C.a" "Release\I2C.o"


clean:
	rm -f "Debug/*.o" || true
	rm -f "Release/*.o" || true

credo che leggerò il manuale del make (o anche del gcc, nella prossima vita aha) :k:

Il make file hanno molte potenzialità ma è la classica situazione dove il 90% delle casistiche le risolvi con il 10% del linguaggio.
aaa
06/08/16 21:30
Bonnox
:k:

perdonami una sola domanda...

Che significa AVR? :_doubt:

comunque io di solito quando faccio il debug mi definisco una variabile booleana e se è vera stampo a console (anche se magari il programma è grafico) le informazioni di debug... tu invece come fai? ma lavori su sistemi embedded? blocchi run time l'esecuzione con dispositivi di dump?

e per finire, cosa succederebbe se non dichiarassi phony le regole?

grazie e buonasera
aaa
06/08/16 22:42
nessuno
Postato originariamente da Bonnox:

Che significa AVR? :_doubt:


it.wikipedia.org/wiki/…
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.