Gå til innhold

Anbefalte innlegg

Jeg har nettopp begynt med programmering på linux og hittil ikke helt imponert.

 

Fra å programmere i Visual Studio er det mer styr synes jeg å komme i gang i linux. Jeg har ikke helt grepet på make og makefiler ennå men jobber med saken. Jeg har laget "Hello World" i c++ og har følgende makefile:

 

# Compiler
CC = g++

# Compiler arguments
CFLAGS = -c -Wall

# Project paths
SPATH = source/
IPATH = include/

all: program


program: main.o

$(CC) main.o -o program


main.o: $(SPATH)main.cpp

$(CC) $(CFLAGS) $(SPATH)main.cpp


clean:
rm -rf *o program

 

Det over funker men det er vel ikke helt optimalt? Går det ikke ann å fortelle at den skal finne alle cpp filer i source mappa(strukturen min er følgende: jeg har prosjektmappa som har en "include" mappe samt en "source" mappe. Makefila ligger i prosjektmappa) og smelle dem sammen? Bruken av SPATH er vel kanskje ikke helt sånn som man skal gjøre? Jeg ser det brukes noe VPATH her og der men jeg forstår ikke helt hvordan denne brukes, er den reservert og betyr noe spess?

Lenke til kommentar
Videoannonse
Annonse
Og hvis du ikke vil bruke makefiles så finnes det da IDEer til Linux også (Codeblocks f.eks.) :) Minst like enkelt å bruke som VS (dog, det er greit å kunne makefiles også).

 

Takk for tipset... fikk lasta ned codeblocks og alt funker som det skal. men må få satt meg inn i makefiler også.

Lenke til kommentar

Makefiler handler stort sett om å sette opp hvilke dependencies diverse komponenter har, også løser make resten.

 

Kan ta et eksempel på hvordan jeg satte opp et enkelt buildsystem for kodeprosjektet mitt. Bytta det senere ut med autotools-generert build, dog.

 

include config.mk 
# Denne fila inkluderer ting som jeg ikke kunne vite på forhånd,
# f.eks. hvis noen kjører ./configure --disable-feature-x,
# og ble generert av et svært simpelt håndmekka configure script.

SERVER = rsoundserv

CLIENT = rsound
CLIENTOBJECTS = client.o endian.o

PREFIX = .

# all er avhengig av at $(SERVER) og $(CLIENT) er ferdig
all : $(SERVER) $(CLIENT) 

# $(SERVER) er avhengig at alle $(SERVOBJECTS) er kompilert ferdig. 
# Denne variabelen er avhengig av hvordan configure blir kjørt.
$(SERVER) : $(SERVOBJECTS) 
$(CC) -o $(SERVER) $(SERVOBJECTS) $(LIBS)

# Samme greia
$(CLIENT) : $(CLIENTOBJECTS) 
$(CC) -o $(CLIENT) $(CLIENTOBJECTS)

# Har et eget tilfelle for rsound.o siden den ikke skal ha $(EXTRAFLAGS)
rsound.o : rsound.c 
$(CC) $(CFLAGS) -c rsound.c

# Setter opp en generell løsning for objektfiler. 
# $< betyr at .c-filen det var snakk om i %.c skal settes inn.
%.o : %.c			  
$(CC) $(CFLAGS) $(EXTRAFLAGS) -c $< 

clean: clean-obj clean-bin

clean-all: clean
rm config.mk

clean-obj:
rm *.o

clean-bin:
rm $(SERVER)
rm $(CLIENT)

# Avhengig av at all er kjørt før vi kan installere noe.
install: all				 
mkdir -p $(PREFIX)/bin
cp -f  $(SERVER) $(PREFIX)/bin/
cp -f  $(CLIENT) $(PREFIX)/bin/
chmod 755 $(PREFIX)/bin/$(SERVER)
chmod 755 $(PREFIX)/bin/$(CLIENT)

install-server: $(SERVER)
mkdir -p $(PREFIX)/bin
cp -f  $(SERVER) $(PREFIX)/bin/
chmod 755 $(PREFIX)/bin/$(SERVER)

install-client: $(CLIENT)
mkdir -p $(PREFIX)/bin
cp -f  $(CLIENT) $(PREFIX)/bin/
chmod 755 $(PREFIX)/bin/$(CLIENT)

server : $(SERVER)

client : $(CLIENT)

 

Så fikser make resten. Hvis du skriver make -j8 f.eks, vil den prøve å utføre 8 oppgaver samtidig, så lenge dette lar seg gjøre.

Endret av TheMaister
Lenke til kommentar
For å finne alle cpp filer i en mappe kan du bruker:

 

SOURCE = $(wildcard *.cpp)

 

For å så finne de tilsvarende object filene kan du bruke:

 

OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES))

 

Akkurat det du beskriver der kan også gjøres med patterns som

 

%.o: %.cpp

 

Men disse er default så du kan bare skrive

 

touch x.cpp y.cpp z.cpp
echo -e "a.out:\tx.o y.o z.o" > makefile
make
g++	-c -o x.o x.cpp
g++	-c -o y.o y.cpp
g++	-c -o z.o z.cpp

Lenke til kommentar
Det over funker men det er vel ikke helt optimalt?

 

Det var ikke så ille for en som akkurat har startet med make.

 

Går det ikke ann å fortelle at den skal finne alle cpp filer i source mappa

 

 

Hvis du har f.eks. x.cpp, y.cpp, z.cpp og main.cpp i en mappe som heter source så kunne du skrive noe som f.eks.:

 

OBJS = x.o y.o z.o

all:	main.elf

main.elf:	main.o $(OBJS)
g++ -o $@ $^

vpath %.cpp source

main.o:	$(OBJS)

Lenke til kommentar
Takk for tipset... fikk lasta ned codeblocks og alt funker som det skal. men må få satt meg inn i makefiler også.

KDevelop, Eclipse og Netbeans kan også være alternativer. De to siste er primært Java-ide'er med støtte for C++ og noen andre språk. Hvor bra de er til «sidemål» vet jeg ikke.

Lenke til kommentar
  • 3 uker senere...

Nå har jeg sittet å fiklet litt med det... fått litt hjelp og prøvd litt selv. Det er utrolig my informasjon som finnes der, og makefiler fremstår, som dere sier, som er kraftig verktøy.

 

Akkurat nå ser makefila mi noe slik ut:

 

CC = g++
CFLAGS = -I ../include

ODIR = obj

SRC = $(wildcard *.cpp)

program: $(SRC)
$(CC) -o $@ $(SRC) $(CFLAGS)

clean:
rm -f $(OFIR)/*.o *~ core $(INDIR)/*~ program

 

Det er et par ting jeg ikke forstår:

 

program: $(SRC)
$(CC) -o $@ $(SRC) $(CFLAGS)

Hva betyr "$@"?

 

clean:
rm -f $(ODIR)/*.o *~ core $(INDIR)/*~ program

Her må det vel være et par feil? Jeg sjekket obj mappa etter å kjørt make og det ligger ingen filer der (.o). Og hva betyr "*~ core". Og er "$(INDIR)/*~" en rein feil ettersom jeg ikke har definert $(INDIR)? (Skyldes nok en copy&paste fra diverste tutorials.

Lenke til kommentar

Er ikke sikker på $@. Hvordan kjører du make, og hva blir navnet på den kjørbare fila di? $@ kan eventuelt byttes ut med det du ønsker at din kjørbare fil skal hete.

 

Siden du kompilerer direkte ved å kjøre kompilering og linking samtidig får du ingen .o filer. $(INDIR) er her ingenting nei, riktig. Så den sjekker i / for backupp filer. Så hvis du har en fil i rot mappa di som slutter på ~ som du av en eller annen grunn har tilgang til, vil den slette den. Burde derfor fjerne det der da det kan ødelegge, og hvertfall ikke kjør make clean som root med den makefila:P

Lenke til kommentar

Er ikke sikker på $@. Hvordan kjører du make, og hva blir navnet på den kjørbare fila di? $@ kan eventuelt byttes ut med det du ønsker at din kjørbare fil skal hete.

 

Siden du kompilerer direkte ved å kjøre kompilering og linking samtidig får du ingen .o filer. $(INDIR) er her ingenting nei, riktig. Så den sjekker i / for backupp filer. Så hvis du har en fil i rot mappa di som slutter på ~ som du av en eller annen grunn har tilgang til, vil den slette den. Burde derfor fjerne det der da det kan ødelegge, og hvertfall ikke kjør make clean som root med den makefila:P

 

Den kjørbare fila mi får navnet "program"

 

clean:
rm -f $(ODIR)/*.o program

Dette litt bedre?

 

Som du påpekte så kompilerer og linker jeg samtidig. Hva er fordelen/ulempen med dette?

 

Kunne jeg kanskje ha gjort noe som dette:

 

CC 0 g++
CFLAGS = -I ../include

ODIR = obj

SRC = $(wildcard *.cpp)

OBJ = $(wildcard obj/*.o)

%.o: $(OBJ)
$(CC) -o $@ $(SRC) $(CFLAGS)

program: $(OBJ)
$(CC) -o $@ $(SRC) $(CFLAGS)

clean:
rm -f $(ODIR)/*.o program

 

kanskje??

Lenke til kommentar

Noe er galt med makefila... irriterende :D

 

fra en tidligere build har jeg .o filene mine som jeg nå har flytta til obj mappa i src.

 

I makefila ser det slik ut:

 


ODIR = obj

_OBJ = main.o person.o
OBJ = $(pathsubst %, $(ODIR)/%, $(_OBJ))

 

men på dette får jeg bare g++: no input files. er OBJ er tom eller noe?

Endret av South_Bridge
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...