C++
Kompilowanie i budowanie
Szukaj…
Wprowadzenie
Programy napisane w C ++ muszą zostać skompilowane przed uruchomieniem. Dostępnych jest wiele różnych kompilatorów w zależności od systemu operacyjnego.
Uwagi
Większość systemów operacyjnych jest dostarczana bez kompilatora i należy je zainstalować później. Niektóre popularne opcje kompilatorów to:
- GCC, kolekcja kompilatorów GNU g ++
- clang: frontend dla rodziny C dla LLVM clang ++
- MSVC, Microsoft Visual C ++ (zawarty w Visual Studio) visual-c ++
- C ++ Builder, Embarcadero C ++ Builder (zawarty w RAD Studio) c ++ builder
Zapoznaj się z odpowiednią instrukcją kompilatora dotyczącą sposobu kompilacji programu C ++.
Inną opcją użycia określonego kompilatora z jego własnym systemem kompilacji jest możliwość zezwolenia ogólnym systemom kompilacji na skonfigurowanie projektu dla określonego kompilatora lub domyślnie zainstalowanego.
Kompilacja z GCC
Zakładając pojedynczy plik źródłowy o nazwie main.cpp
, polecenie kompilowania i łączenia -Og
pliku wykonywalnego wygląda następująco (kompilacja bez optymalizacji jest przydatna do początkowego programowania i debugowania, chociaż -Og
jest oficjalnie zalecane dla nowszych wersji GCC).
g++ -o app -Wall main.cpp -O0
W celu wytworzenia zoptymalizowanej wykonywalny do stosowania w produkcji, zastosowanie tego -O
opcji (patrz -O1
, -O2
, -O3
, -Os
, -Ofast
)
g++ -o app -Wall -O2 main.cpp
Jeśli opcja -O zostanie pominięta, domyślnie zostanie użyta opcja -O0, co oznacza brak optymalizacji (określenie -O bez liczby oznacza -O1).
Alternatywnie użyj bezpośrednio flag optymalizacji z grup O
(lub więcej optymalizacji eksperymentalnych). Poniższy przykład buduje z optymalizacją -O2
, plus jedna flaga z poziomu optymalizacji -O3
:
g++ -o app -Wall -O2 -ftree-partial-pre main.cpp
Aby utworzyć zoptymalizowany plik wykonywalny specyficzny dla platformy (do użycia w produkcji na komputerze o tej samej architekturze), użyj:
g++ -o app -Wall -O2 -march=native main.cpp
Każde z powyższych spowoduje wygenerowanie pliku binarnego, który można uruchomić za pomocą .\app.exe
w systemie Windows i ./app
w systemie Linux, Mac OS itp.
Flaga -o
można również pominąć. W takim przypadku GCC utworzy domyślny plik wykonywalny a.exe
w systemie Windows i a.out
w systemach uniksopodobnych. Aby skompilować plik bez łączenia go, użyj opcji -c
:
g++ -o file.o -Wall -c file.cpp
W ten sposób powstaje plik obiektowy o nazwie file.o
który można później połączyć z innymi plikami w celu utworzenia pliku binarnego:
g++ -o app file.o otherfile.o
Więcej informacji na temat opcji optymalizacji można znaleźć na stronie gcc.gnu.org . Na szczególną uwagę zasługują -Og
(optymalizacja z naciskiem na doświadczenie debugowania - zalecane dla standardowego cyklu edycji-kompilacji-debugowania) i -Ofast
(wszystkie optymalizacje, w tym te, które nie uwzględniają ścisłej zgodności ze standardami).
Flaga -Wall
włącza ostrzeżenia o wielu typowych błędach i zawsze powinna być używana. Aby poprawić jakość kodu, często zaleca się również użycie opcji -Wextra
i innych flag ostrzegawczych, które nie są automatycznie włączane przez -Wall
i -Wextra
.
Jeśli kod oczekuje określonego standardu C ++, określ, którego standardu użyć, włączając flagę -std=
. Obsługiwane wartości odpowiadają rokowi finalizacji każdej wersji standardu ISO C ++. Od GCC 6.1.0 prawidłowe wartości dla flagi std=
to c++98
/ c++03
, c++11
, c++14
oraz c++17
/ c++1z
. Wartości oddzielone ukośnikiem są równoważne.
g++ -std=c++11 <file>
GCC zawiera niektóre rozszerzenia specyficzne dla kompilatora, które są wyłączone, gdy są w konflikcie ze standardem określonym przez flagę -std=
. Aby skompilować przy włączonych wszystkich rozszerzeniach, można użyć wartości gnu++XX
, gdzie XX
oznacza dowolny z lat użytych przez wartości c++
wymienione powyżej.
Domyślny standard zostanie użyty, jeśli żaden nie zostanie określony. W przypadku wersji GCC wcześniejszych niż 6.1.0 wartością domyślną jest -std=gnu++03
; w GCC 6.1.0 i nowszych wartością domyślną jest -std=gnu++14
.
Zauważ, że z powodu błędów w GCC flaga -pthread
musi być obecna podczas kompilacji i łączenia dla GCC, aby obsługiwać standardową funkcjonalność wątkowania C ++ wprowadzoną w C ++ 11, taką jak std::thread
i std::wait_for
. Pominięcie go podczas korzystania z funkcji wątków może spowodować brak ostrzeżeń, ale nieprawidłowe wyniki na niektórych platformach.
Łączenie z bibliotekami:
Użyj opcji -l
, aby przekazać nazwę biblioteki:
g++ main.cpp -lpcre2-8
#pcre2-8 is the PCRE2 library for 8bit code units (UTF-8)
Jeśli biblioteka nie znajduje się w standardowej ścieżce biblioteki, dodaj ścieżkę z opcją -L
:
g++ main.cpp -L/my/custom/path/ -lmylib
Wiele bibliotek można połączyć ze sobą:
g++ main.cpp -lmylib1 -lmylib2 -lmylib3
Jeśli jedna biblioteka zależy od drugiej, umieść bibliotekę zależną przed biblioteką niezależną:
g++ main.cpp -lchild-lib -lbase-lib
Lub niech linker sam ustali kolejność poprzez --start-group
i --end-group
(uwaga: ma to znaczny koszt wydajności):
g++ main.cpp -Wl,--start-group -lbase-lib -lchild-lib -Wl,--end-group
Kompilacja z Visual C ++ (wiersz poleceń)
Dla programistów pochodzących z GCC lub Clang do Visual Studio, lub dla programistów bardziej wygodnych z linii poleceń, możesz użyć kompilatora Visual C ++ z linii poleceń, a także IDE.
Jeśli chcesz skompilować kod z wiersza polecenia w programie Visual Studio, musisz najpierw skonfigurować środowisko wiersza polecenia. Można to zrobić, otwierając Visual Studio Command Prompt
Developer Command Prompt
Visual Studio Command Prompt
/ Visual Studio Command Prompt
Developer Command Prompt
/ Developer Command Prompt
x86 Native Tools Command Prompt
/ Developer Command Prompt
x86 Native Tools Command Prompt
x64 Native Tools Command Prompt
lub podobny (w zależności od wersji programu Visual Studio) lub w wierszu polecenia, przechodząc do podkatalog VC
katalogu instalacyjnego kompilatora (zazwyczaj \Program Files (x86)\Microsoft Visual Studio x\VC
, gdzie x
to numer wersji (np. 10.0
dla 2010 lub 14.0
dla 2015) i z uruchomionym VCVARSALL
wsadowym VCVARSALL
parametr wiersza polecenia określony tutaj .
Zauważ, że w przeciwieństwie do GCC, Visual Studio nie zapewnia link.exe
dla linkera ( link.exe
) za pośrednictwem kompilatora ( cl.exe
), ale zamiast tego udostępnia linker jako osobny program, który kompilator wywołuje podczas zamykania. cl.exe
i link.exe
mogą być używane osobno z różnymi plikami i opcjami, lub cl
może zostać poproszony o przesłanie plików i opcji link
jeśli oba zadania zostaną wykonane razem. Wszelkie opcje łączenia określone dla cl
zostaną przetłumaczone na opcje dla link
, a wszelkie pliki nieprzetworzone przez cl
zostaną przekazane bezpośrednio do link
. Ponieważ jest to głównie prosty przewodnik po kompilowaniu za pomocą wiersza polecenia programu Visual Studio, argumenty dla link
nie zostaną w tej chwili opisane; jeśli potrzebujesz listy, zobacz tutaj .
Zauważ, że w argumentach do cl
rozróżniana jest cl
liter, podczas gdy w argumentach link
nie.
[Należy pamiętać, że niektóre z poniższych przykładów używają zmiennej „bieżący katalog” powłoki systemu Windows, %cd%
, przy określaniu bezwzględnych nazw ścieżek. Każdy, kto nie zna tej zmiennej, rozwija się do bieżącego katalogu roboczego. Z wiersza poleceń będzie to katalog, w którym byłeś podczas uruchamiania cl
, i jest on domyślnie określony w wierszu polecenia (jeśli na przykład wiersz polecenia to C:\src>
, to %cd%
to C:\src\
).]
Zakładając, że w bieżącym folderze znajduje się pojedynczy plik źródłowy o nazwie main.cpp
, polecenie skompilowania i połączenia niezoptymalizowanego pliku wykonywalnego (przydatne do początkowego programowania i debugowania) to (użyj jednego z poniższych):
cl main.cpp
// Generates object file "main.obj".
// Performs linking with "main.obj".
// Generates executable "main.exe".
cl /Od main.cpp
// Same as above.
// "/Od" is the "Optimisation: disabled" option, and is the default when no /O is specified.
Zakładając dodatkowy plik źródłowy „niam.cpp” w tym samym katalogu, użyj:
cl main.cpp niam.cpp
// Generates object files "main.obj" and "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".
Możesz także używać symboli wieloznacznych, jak można się spodziewać:
cl main.cpp src\*.cpp
// Generates object file "main.obj", plus one object file for each ".cpp" file in folder
// "%cd%\src".
// Performs linking with "main.obj", and every additional object file generated.
// All object files will be in the current folder.
// Generates executable "main.exe".
Aby zmienić nazwę lub przenieść plik wykonywalny, użyj jednej z następujących czynności:
cl /o name main.cpp
// Generates executable named "name.exe".
cl /o folder\ main.cpp
// Generates executable named "main.exe", in folder "%cd%\folder".
cl /o folder\name main.cpp
// Generates executable named "name.exe", in folder "%cd%\folder".
cl /Fename main.cpp
// Same as "/o name".
cl /Fefolder\ main.cpp
// Same as "/o folder\".
cl /Fefolder\name main.cpp
// Same as "/o folder\name".
Zarówno /o
i /Fe
przekazują swój parametr (nazwijmy go o-param
), aby link
jako /OUT:o-param
, dołączając odpowiednie rozszerzenie (ogólnie .exe
lub .dll
) do „nazwij” o-param
jeśli to konieczne. Podczas gdy zarówno /o
i /Fe
są identyczne pod względem funkcjonalności, ta ostatnia jest preferowana w Visual Studio. /o
jest oznaczony jako przestarzały i wydaje się być przeznaczony głównie dla programistów bardziej obeznanych z GCC lub Clang.
Zauważ, że chociaż odstęp między /o
a określonym folderem i / lub nazwą jest opcjonalny, nie może być odstępu między /Fe
a określonym folderem i / lub nazwą.
Podobnie, aby utworzyć zoptymalizowany plik wykonywalny (do użycia w produkcji), użyj:
cl /O1 main.cpp
// Optimise for executable size. Produces small programs, at the possible expense of slower
// execution.
cl /O2 main.cpp
// Optimise for execution speed. Produces fast programs, at the possible expense of larger
// file size.
cl /GL main.cpp other.cpp
// Generates special object files used for whole-program optimisation, which allows CL to
// take every module (translation unit) into consideration during optimisation.
// Passes the option "/LTCG" (Link-Time Code Generation) to LINK, telling it to call CL during
// the linking phase to perform additional optimisations. If linking is not performed at this
// time, the generated object files should be linked with "/LTCG".
// Can be used with other CL optimisation options.
Wreszcie, aby utworzyć zoptymalizowany plik wykonywalny specyficzny dla platformy (do użycia w produkcji na komputerze o określonej architekturze), wybierz odpowiedni VCVARSALL
polecenia lub parametr VCVARSALL
dla platformy docelowej. link
powinien wykryć pożądaną platformę z plików obiektowych; jeśli nie, użyj opcji /MACHINE
, aby jawnie określić platformę docelową.
// If compiling for x64, and LINK doesn't automatically detect target platform:
cl main.cpp /link /machine:X64
Każde z powyższych spowoduje utworzenie pliku wykonywalnego o nazwie określonej przez /o
lub /Fe
, lub jeśli nie zostanie podany, o nazwie identycznej z pierwszym plikiem źródłowym lub obiektowym określonym w kompilatorze.
cl a.cpp b.cpp c.cpp
// Generates "a.exe".
cl d.obj a.cpp q.cpp
// Generates "d.exe".
cl y.lib n.cpp o.obj
// Generates "n.exe".
cl /o yo zp.obj pz.cpp
// Generates "yo.exe".
Aby skompilować plik (i) bez łączenia, użyj:
cl /c main.cpp
// Generates object file "main.obj".
To mówi cl
aby zakończył pracę bez wywoływania link
, i tworzy plik obiektowy, który można później połączyć z innymi plikami w celu utworzenia pliku binarnego.
cl main.obj niam.cpp
// Generates object file "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".
link main.obj niam.obj
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".
Istnieją również inne cenne parametry wiersza poleceń, które użytkownicy powinni wiedzieć:
cl /EHsc main.cpp
// "/EHsc" specifies that only standard C++ ("synchronous") exceptions will be caught,
// and `extern "C"` functions will not throw exceptions.
// This is recommended when writing portable, platform-independent code.
cl /clr main.cpp
// "/clr" specifies that the code should be compiled to use the common language runtime,
// the .NET Framework's virtual machine.
// Enables the use of Microsoft's C++/CLI language in addition to standard ("native") C++,
// and creates an executable that requires .NET to run.
cl /Za main.cpp
// "/Za" specifies that Microsoft extensions should be disabled, and code should be
// compiled strictly according to ISO C++ specifications.
// This is recommended for guaranteeing portability.
cl /Zi main.cpp
// "/Zi" generates a program database (PDB) file for use when debugging a program, without
// affecting optimisation specifications, and passes the option "/DEBUG" to LINK.
cl /LD dll.cpp
// "/LD" tells CL to configure LINK to generate a DLL instead of an executable.
// LINK will output a DLL, in addition to an LIB and EXP file for use when linking.
// To use the DLL in other programs, pass its associated LIB to CL or LINK when compiling those
// programs.
cl main.cpp /link /LINKER_OPTION
// "/link" passes everything following it directly to LINK, without parsing it in any way.
// Replace "/LINKER_OPTION" with any desired LINK option(s).
Dla każdego bardziej zaznajomionego z systemami * nix i / lub GCC / Clang, cl
, link
i inne narzędzia wiersza poleceń Visual Studio mogą akceptować parametry określone za pomocą łącznika (takiego jak -c
) zamiast ukośnika (takiego jak /c
). Ponadto system Windows rozpoznaje ukośnik lub ukośnik odwrotny jako prawidłowy separator ścieżek, więc można również używać ścieżek w stylu * nix. Ułatwia to konwersję prostych wierszy poleceń kompilatora z g++
lub clang++
na cl
lub odwrotnie, przy minimalnych zmianach.
g++ -o app src/main.cpp
cl -o app src/main.cpp
Oczywiście podczas przenoszenia wierszy poleceń korzystających z bardziej złożonych opcji g++
lub clang++
należy wyszukać równoważne polecenia w odpowiednich dokumentacjach kompilatora i / lub na stronach z zasobami, ale ułatwia to rozpoczęcie pracy przy minimalnym czasie poświęconym na naukę nowe kompilatory.
W przypadku, gdy potrzebujesz określonych funkcji językowych dla swojego kodu, wymagana była specjalna wersja MSVC. Od wersji Visual C ++ 2015 Update 3 można wybrać wersję standardu do kompilacji za pomocą flagi /std
. Możliwe wartości to /std:c++14
i /std:c++latest
( /std:c++17
nastąpi wkrótce).
Uwaga: W starszych wersjach tego kompilatora dostępne były specyficzne flagi funkcji, które jednak były używane głównie do podglądu nowych funkcji.
Kompilowanie za pomocą Visual Studio (interfejs graficzny) - Hello World
- Pobierz i zainstaluj Visual Studio Community 2015
- Otwórz społeczność Visual Studio
- Kliknij Plik -> Nowy -> Projekt
- Kliknij Szablony -> Visual C ++ -> Aplikacja konsoli Win32, a następnie nazwij projekt MyFirstProgram .
- Kliknij OK
- Kliknij Dalej w następnym oknie.
- Zaznacz pole
Empty project
, a następnie kliknij przycisk Zakończ: - Kliknij prawym przyciskiem myszy folder Plik źródłowy, a następnie -> Dodaj -> Nowy element:
- Wybierz plik C ++ i nazwij plik main.cpp, a następnie kliknij Dodaj: 10: Skopiuj i wklej następujący kod w nowym pliku main.cpp:
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
return 0;
}
Twoje środowisko powinno wyglądać następująco:
- Kliknij opcję Debuguj -> Rozpocznij bez debugowania (lub naciśnij kombinację klawiszy Ctrl + F5):
Kompilowanie z Clangiem
Ponieważ interfejs Clang został zaprojektowany tak, aby był kompatybilny z GCC, większość programów, które można skompilować za pomocą GCC , skompiluje się po zamianie g++
na clang++
w skryptach kompilacji. Jeśli nie -std=version
, zostanie użyty gnu11.
Użytkownicy systemu Windows przyzwyczajeni do MSVC mogą zamienić cl.exe
z clang-cl.exe
. Domyślnie clang próbuje być kompatybilny z najwyższą zainstalowaną wersją MSVC.
W przypadku kompilacji ze studiem wizualnym można użyć clang-cl, zmieniając Platform toolset
we właściwościach projektu.
W obu przypadkach clang jest kompatybilny tylko przez interfejs, ale próbuje również wygenerować pliki obiektów kompatybilnych binarnie. Użytkownicy clang-cl powinni pamiętać, że kompatybilność z MSVC nie jest jeszcze pełna .
Aby użyć clang lub clang-cl, można użyć domyślnej instalacji w niektórych dystrybucjach Linuksa lub w pakietach z IDE (jak XCode na Macu). W przypadku innych wersji tego kompilatora lub na platformach, na których go nie zainstalowano, można go pobrać z oficjalnej strony pobierania .
Jeśli używasz CMake do budowania kodu, zwykle możesz przełączyć kompilator, ustawiając zmienne środowiskowe CC
i CXX
następujący sposób:
mkdir build
cd build
CC=clang CXX=clang++ cmake ..
cmake --build .
Zobacz także wprowadzenie do Cmake .
Kompilatory online
Różne strony internetowe zapewniają dostęp online do kompilatorów C ++. Zestaw funkcji kompilatora online różni się znacznie w zależności od witryny, ale zazwyczaj pozwalają one na wykonanie następujących czynności:
- Wklej kod do formularza internetowego w przeglądarce.
- Wybierz niektóre opcje kompilatora i skompiluj kod.
- Zbierz dane wyjściowe kompilatora i / lub programu.
Zachowanie strony internetowej kompilatora online jest zazwyczaj dość restrykcyjne, ponieważ pozwala każdemu uruchamiać kompilatory i wykonywać dowolny kod po stronie serwera, podczas gdy zwykle zdalne wykonanie dowolnego kodu jest uważane za podatność na atak.
Kompilatory online mogą być przydatne do następujących celów:
- Uruchom mały fragment kodu z komputera bez kompilatora C ++ (smartfony, tablety itp.).
- Upewnij się, że kod kompiluje się pomyślnie z różnymi kompilatorami i działa w ten sam sposób, niezależnie od kompilatora, z którym został skompilowany.
- Naucz się lub naucz podstawy języka C ++.
- Poznaj nowoczesne funkcje C ++ (C ++ 14 i C ++ 17 w najbliższej przyszłości), gdy aktualny kompilator C ++ nie będzie dostępny na komputerze lokalnym.
- Znajdź błąd w kompilatorze w porównaniu z dużym zestawem innych kompilatorów. Sprawdź, czy błąd kompilatora został naprawiony w przyszłych wersjach, które nie są dostępne na twoim komputerze.
- Rozwiązywanie problemów z oceną online.
Do jakich kompilatorów online nie należy używać:
- Twórz w pełni funkcjonalne (nawet małe) aplikacje za pomocą C ++. Zwykle kompilatory online nie pozwalają na łączenie się z bibliotekami stron trzecich lub pobieranie artefaktów kompilacji.
- Wykonuj intensywne obliczenia. Zasoby obliczeniowe po stronie serwera są ograniczone, więc każdy program podany przez użytkownika zostanie zabity po kilku sekundach wykonania. Dozwolony czas wykonania jest zwykle wystarczający do przetestowania i nauki.
- Zaatakuj sam serwer kompilatora lub hosty innych firm w sieci.
Przykłady:
Oświadczenie: autor (autorzy) dokumentacji nie są powiązani z żadnymi zasobami wymienionymi poniżej. Strony internetowe są wymienione alfabetycznie.
- http://codepad.org/ Kompilator online z udostępnianiem kodu. Edytowanie kodu po kompilacji z ostrzeżeniem lub błędem kodu źródłowego nie działa tak dobrze.
- http://coliru.stacked-crooked.com/ Kompilator online, dla którego określasz wiersz poleceń. Udostępnia kompilatory GCC i Clang.
- http://cpp.sh/ - Kompilator online z obsługą C ++ 14. Nie pozwala edytować wiersza polecenia kompilatora, ale niektóre opcje są dostępne za pośrednictwem kontrolek GUI.
- https://gcc.godbolt.org/ - Zapewnia szeroką listę wersji kompilatora, architektur i danych wyjściowych z demontażu. Jest to bardzo przydatne, gdy trzeba sprawdzić, w jaki sposób kod się kompiluje za pomocą różnych kompilatorów. Obecne są GCC, Clang, MSVC (
CL
), kompilator Intel (icc
), ELLCC i Zapcc, przy czym jeden lub więcej z tych kompilatorów jest dostępnych dla ARM, ARMv8 (jako ARM64), Atmel AVR, MIPS, MIPS64, MSP430, PowerPC , architekci x86 i x64. Argumenty wiersza poleceń kompilatora mogą być edytowane. - https://ideone.com/ - Szeroko stosowany w sieci w celu zilustrowania zachowania fragmentu kodu. Udostępnia GCC i Clang do użytku, ale nie pozwala na edycję wiersza poleceń kompilatora.
- http://melpon.org/wandbox - Obsługuje wiele wersji kompilatora Clang i GNU / GCC.
- http://onlinegdb.com/ - Niezwykle minimalistyczne IDE, które zawiera edytor, kompilator (gcc) i debugger (gdb).
- http://rextester.com/ - Zapewnia kompilatory Clang, GCC i Visual Studio dla C i C ++ (wraz z kompilatorami dla innych języków), z biblioteką Boost dostępną do użytku.
- http://tutorialspoint.com/compile_cpp11_online.php - W pełni funkcjonalna powłoka UNIX z GCC i przyjazny dla użytkownika eksplorator projektów.
- http://webcompiler.cloudapp.net/ - Internetowy kompilator Visual Studio 2015, dostarczony przez Microsoft jako część RiSE4fun.
Proces kompilacji w C ++
Gdy tworzysz program C ++, następnym krokiem jest skompilowanie programu przed jego uruchomieniem. Kompilacja jest procesem przekształcającym program napisany w języku czytelnym dla człowieka, takim jak C, C ++ itp., W kod maszynowy, zrozumiały bezpośrednio przez Central Processing Unit. Na przykład, jeśli masz plik kodu źródłowego C ++ o nazwie prog.cpp i wykonujesz polecenie kompilacji,
g++ -Wall -ansi -o prog prog.cpp
Istnieją 4 główne etapy tworzenia pliku wykonywalnego z pliku źródłowego.
C ++ preprocesor pobiera plik kodu źródłowego C ++ i zajmuje się nagłówkami (#include), makrami (#define) i innymi dyrektywami preprocesora.
Rozszerzony plik kodu źródłowego C ++ utworzony przez preprocesor C ++ jest kompilowany w języku asemblera dla platformy.
Kod asemblera generowany przez kompilator jest montowany w kodzie obiektowym platformy.
Plik kodu obiektowego utworzony przez asembler jest połączony ze sobą
z plikami kodu obiektowego dla dowolnych funkcji bibliotecznych używanych do tworzenia biblioteki lub pliku wykonywalnego.
Przetwarzanie wstępne
Preprocesor obsługuje dyrektywy preprocesora, takie jak #include i #define. Jest niezależny od składni języka C ++, dlatego należy go używać ostrożnie.
Działa na jednym pliku źródłowym C ++ na raz, zastępując dyrektywy #include zawartością odpowiednich plików (co zwykle jest tylko deklaracjami), zastępując makra (# zdefiniować) i wybierając różne części tekstu w zależności od # if, Dyrektywy #ifdef i #ifndef.
Preprocesor działa na strumieniu tokenów przetwarzania wstępnego. Makropodstawienie definiuje się jako zastępowanie tokenów innymi tokenami (operator ## umożliwia łączenie dwóch tokenów, gdy ma to sens).
Po tym wszystkim preprocesor wytwarza pojedyncze wyjście, które jest strumieniem tokenów wynikających z transformacji opisanych powyżej. Dodaje także specjalne znaczniki, które informują kompilator, skąd pochodzi każda linia, aby mógł używać tych znaków do generowania rozsądnych komunikatów o błędach.
Na tym etapie można popełnić pewne błędy dzięki sprytnemu zastosowaniu dyrektyw #if i #error.
Używając poniższej flagi kompilatora, możemy zatrzymać proces na etapie wstępnego przetwarzania.
g++ -E prog.cpp
Kompilacja
Etap kompilacji wykonywany jest na każdym wyjściu preprocesora. Kompilator analizuje czysty kod źródłowy C ++ (teraz bez dyrektyw preprocesora) i konwertuje go na kod asemblera. Następnie wywołuje bazowe zaplecze (asembler w toolchain), które składa ten kod w kod maszynowy, tworząc rzeczywisty plik binarny w jakimś formacie (ELF, COFF, a.out, ...). Ten plik obiektowy zawiera skompilowany kod (w formie binarnej) symboli zdefiniowanych na wejściu. Symbole w plikach obiektowych są określane według nazwy.
Pliki obiektowe mogą odnosić się do symboli, które nie są zdefiniowane. Dzieje się tak, gdy używasz deklaracji i nie podajesz jej definicji. Kompilatorowi to nie przeszkadza i chętnie utworzy plik obiektowy, o ile kod źródłowy jest poprawnie sformułowany.
Kompilatory zwykle pozwalają zatrzymać kompilację w tym momencie. Jest to bardzo przydatne, ponieważ dzięki niemu możesz skompilować każdy plik kodu źródłowego osobno. Zaletą tego jest to, że nie trzeba ponownie kompilować wszystkiego, jeśli zmienisz tylko jeden plik.
Wytworzone pliki obiektowe można umieścić w specjalnych archiwach zwanych bibliotekami statycznymi, aby ułatwić ich późniejsze użycie.
Na tym etapie zgłaszane są „zwykłe” błędy kompilatora, takie jak błędy składniowe lub błędy rozwiązywania przeciążenia.
Aby zatrzymać proces po kroku kompilacji, możemy użyć opcji -S:
g++ -Wall -ansi -S prog.cpp
Złożenie
Asembler tworzy kod obiektowy. W systemie UNIX możesz zobaczyć pliki z sufiksem .o (.OBJ w MSDOS), aby wskazać pliki kodu obiektowego. W tej fazie asembler konwertuje te pliki obiektowe z kodu asemblera na instrukcje na poziomie maszyny, a utworzony plik jest przemieszczalnym kodem obiektu. Dlatego faza kompilacji generuje program obiektu relokowalnego i ten program może być używany w różnych miejscach bez konieczności ponownej kompilacji.
Aby zatrzymać proces po kroku montażu, możesz użyć opcji -c:
g++ -Wall -ansi -c prog.cpp
Łączenie
Linker jest tym, co tworzy ostateczne dane wyjściowe kompilacji z plików obiektowych utworzonych przez asembler. Dane wyjściowe mogą być biblioteką współdzieloną (lub dynamiczną) (i chociaż nazwa jest podobna, nie mają wiele wspólnego z wymienionymi wcześniej bibliotekami statycznymi) ani plikiem wykonywalnym.
Łączy wszystkie pliki obiektowe, zastępując odwołania do niezdefiniowanych symboli poprawnymi adresami. Każdy z tych symboli można zdefiniować w innych plikach obiektowych lub w bibliotekach. Jeśli są zdefiniowane w bibliotekach innych niż biblioteka standardowa, musisz o nich poinformować linkera.
Na tym etapie najczęstszymi błędami są brakujące definicje lub duplikaty definicji. To pierwsze oznacza, że albo definicje nie istnieją (tzn. Nie są zapisane), albo że pliki obiektów lub biblioteki, w których się znajdują, nie zostały przekazane linkerowi. To ostatnie jest oczywiste: ten sam symbol został zdefiniowany w dwóch różnych plikach obiektowych lub bibliotekach.
Kompilowanie z Code :: Blocks (interfejs graficzny)
Pobierz i zainstaluj Code :: Blocks tutaj . Jeśli korzystasz z systemu Windows,
mingw
, aby wybrać plik, dla którego nazwa zawieramingw
, inne pliki nie instalują żadnego kompilatora.Otwórz Code :: Blocks i kliknij „Utwórz nowy projekt”:
Wybierz „Aplikacja konsoli” i kliknij „Idź”:
Kliknij „Dalej”, wybierz „C ++”, kliknij „Dalej”, wybierz nazwę swojego projektu i wybierz folder, w którym chcesz go zapisać, kliknij „Dalej”, a następnie „Zakończ”.
Teraz możesz edytować i kompilować swój kod. Domyślny kod drukujący „Witaj świecie!” w konsoli już tam jest. Aby skompilować i / lub uruchomić program, naciśnij jeden z trzech przycisków kompilacji / uruchamiania na pasku narzędzi:
Aby skompilować bez uruchamiania, naciśnij , aby uruchomić bez ponownej kompilacji, naciśnij i aby skompilować, a następnie uruchomić, naciśnij .
Kompilowanie i uruchamianie domyślnego „Hello world!” kod daje następujący wynik: