Jak skompilować wiele plików w jeden wykonywalny w Linuxie?

0

Mam problem, ponieważ zawsze korzystałem z jakiegoś IDE i tam linker sobie to wszystko łączył. Mam zainstalowane gcc. Jak wyglądała/y by komenda/y do stworzenia pliku wykonywalnego z program_do_wykoniania.c

program_do_wykoniania.c  //main
bibiloteki.h
mojefunkcje.c
0
gcc program_do_wykoniania.c  mojefunkcje.c
1

Gdy użyjesz tego co wyżej będziesz miał plik a.out. Co prawda będzie działał, ale możesz również nadać mu bardziej sensowną nazwę za pomocą -o.
Czyli:

gcc program_do_wykonania.c mojefunkcje.c -o program

Przy większej ilości plików łatwiej jest używać programu make

1

W przypadku gdy masz jeden plik wynikowy:
Wszystkie pliki .c kompilujesz z flagą -c, następnie uzyskane pliki .o kompilujesz już normalnie. gcc znajdzie sobie funkcję main w tych wszystkich podanych plikach .o .
Przykład:

gcc -c -o plik1.o plik1.c 
gcc -c -o main.o main.c 
gcc -o program_wynikowy main.o plik1.o

Ewentualnie tak jak pisał atmal skorzystać z makefile.
W folderze tworzysz plik Makefile. W projekcie dla 1 plikowego programu korzystam z czegoś takiego:
przykład dla cpp.

CPP_FILES := $(wildcard ./src/*.cpp)
OBJ_FILES := $(addprefix ./obj/, $(notdir $(CPP_FILES:.cpp=.o)))

CC_FLAGS := --std=c++11 -O0 -g3 -Wall -pedantic -I include/

all: nazwa_programu

nazwa_programu: $(OBJ_FILES)
	g++ $(CC_FLAGS) -o $@ $^

./obj/%.o: ./src/%.cpp
	g++ $(CC_FLAGS) -c -o $@ $<

clean:
	rm $(OBJ_FILES)
	rm nazwa_programu
  1. CPP_FILES - lista plików, w tym przypadku C++
  2. OBJ_FILES - gdzie ma zapisywać pliki obiektowe
  3. Flaga -I (duże i) - gdzie masz pozostałe includy.
    W powyższym, posiadam funkcję wildcard oraz appendfix (jeśli nie ma to trzeba ręcznie dodać pliki), foldery src z plikami .c, folder obj dla wygenerowanych plików .o, folder include dla plików .h (tutaj nie ma obowiązku dodawać nic ręcznie).
    Przed uruchomieniem make w konsoli i skopiowania powyższego do siebie, należy usunąć wszystkie białe znaki stojące przed każdą z komend i dodać własne. make bardzo mocno patrzy na takie szczegóły.
0

@Andy Misio ten makefile nie bierze pod uwagę plików h. Piszesz że „nie ma obowiązku dodawać nic ręcznie”, ale w ten sposób zmiana w pliku .h należącym do projektu nie będzie zauważona przez make.
Można sobie łatwo wyobrazić sytuację, w której zmieniamy wartość jakiegoś #define'a w pliku .h, i… nic się nie dzieje. Frustracja gwarantowana.

Oto jedno z rozwiązań:

# właściwie wszystko co potrzeba to podać listę plików .c w CFILES (można brać *.c ale wolę w ten sposób)
# i nazwę exeka
CFILES = plik1.c plik2.c main.c
EXEFILE = program

OBJFILES = $(subst .c,.o,$(CFILES))
DEPFILES = $(subst .c,.d,$(CFILES))

all: $(EXEFILE)

clean:
	rm -f $(OBJFILES)
	rm -f $(EXEFILE)

veryclean: clean
	rm -f $(DEPFILES)

$(EXEFILE): $(OBJFILES)
	gcc -o $@ $^

%.o: %.c
	gcc -MMD -MP -MF $(subst .o,.d,$@) -c $<

-include $(DEPFILES)

.PHONY: clean
.DEFAULT_GOAL = all

Kwestię podzielenia tego na podkatalogi (żeby nie było wszystko razem do kupy) pozostawiamy czytelnikowi ;-)

0

A najlepiej nie będzie zwyczajnie użyć cmake?

0
Andy Misio napisał(a):

W przypadku gdy masz jeden plik wynikowy:
Wszystkie pliki .c kompilujesz z flagą -c, następnie uzyskane pliki .o kompilujesz już normalnie. gcc znajdzie sobie funkcję main w tych wszystkich podanych plikach .o .

Przepraszam za moją niekompetencję, ale czy kompilowanie wszystkich plików na raz, tak jak napisał @atmal, nie pomaga kompilatorowi w optymalizacji?

Wydaje mi się, że coś na ten temat stojało napisanało w man gcc, sorry nie mam teraz czasu przedzierać się przez tę książkę szukając cytatu bo właśnie wychodzę, ale za jakiś czas może tu wrócę i zapodam cytat

0

Przepraszam za moją niekompetencję, ale czy kompilowanie wszystkich plików na raz, tak jak napisał @atmal, nie pomaga kompilatorowi w optymalizacji?

Problem w tym, że kiedy tych plików będzie kilkanaście, kilkadziesiąt, kilkaset, przekompilowywanie wszystkiego od zero za każdą minimalną zmianą będzie zbyt uciążliwe.

Od tego jest flaga gcc -flto, ale też bym tego używał tylko w buildach releasowych.

1 użytkowników online, w tym zalogowanych: 0, gości: 1