Istnieje kilka oddzielnych elementów tego pytania: jak przekazać kompilatorowi/linkerowi, aby wygenerował i zachował "informacje debugowania" (mapowanie między kodem źródłowym i kodem obiektowym), jak powiedzieć kompilatorowi, aby skompilował kod inaczej niż ułatwiają debugowanie (pomyśl o assert() i #ifdef _DEBUG) oraz o tym, czy prekompilowane biblioteki, które łączysz z projektem, zawierają informacje o debugowaniu.
-Zi (oznaczenie flagą kompilatora CL, aby poinformować go o konieczności wygenerowania informacji debugowania) jest odpowiednikiem flagi -g gcc.
(Istnieją inne formy opcji -Z: -ZI, jeśli chcesz obsługiwać "edytuj i kontynuuj" w Visual Studio IDE, ale jeśli używasz IDE prawdopodobnie używasz jego interfejsu do ustawienia kompilatora zamiast manipulowania nimi bezpośrednio, oraz -Z7, jeśli potrzebujesz starej informacji o debugowaniu w formacie CodeView, za każdym razem, gdy wywołałem CL bezpośrednio, zawsze było to -Zi, którego szukałem.)
Pamiętaj, że używając -Zi (lub -ZI) zwykle generuje plik .pdb na katalog, ale po połączeniu kodu może pochodzić z plików .obj reprezentowanych w różnych plikach .pdb, a także chcesz połączyć te osobne pliki .pdb w master reprezentujący kod, który połączyłeś ze sobą - do tego służy przełącznik -debug dla linkera.
Uwaga: może to wydawać się sprzeczne z intuicją, ale zawsze używaj -Zi (dla CL) i -debug (dla link.exe). Nawet w przypadku kodu, który zamierzasz wydać. Nie zwiększa rozmiaru pliku wykonywalnego ani nie ujawnia klientom tajemnic, ponieważ informacje o debugowaniu są przesyłane do osobnego pliku .pdb (który nie będzie wysyłany do klientów). Jeśli istnieje jakaś szansa, że będziesz musiał go debugować, będziesz chciał .pdb. (-Zi nie jest nawet niekompatybilny z optymalizacjami, chociaż -ZI jest. Więc możesz chcieć skompilować kompilacje "debugowania" za pomocą -ZI, a twoja "wersja" kompiluje się z "-Zi -O2".)
Jeśli chodzi o biblioteki: nie musisz ściśle dopasowywać właściwości debugowania/wydania biblioteki wykonawczej C, czy twój kod zawiera informacje o debugowaniu, ale zazwyczaj jest to dobry pomysł - jeśli zamierzasz debugować projekt, który chcesz aby móc debugować wszystko, a jeśli nie zamierzasz debugować, nie potrzebujesz dodatkowej wagi. Użycie wersji debug/release danej biblioteki nie wpłynie na to, czy ma dostępne symbole debugowania (miejmy nadzieję, jeśli ktokolwiek skompilował bibliotekę zrozumiał punkt, który zrobiłem w poprzednim akapicie), ale wpłynie to na takie rzeczy jak assert i dodatkowe #ifdef _DEBUG kod w tej bibliotece.
Dotyczy to wszystkich bibliotek, z którymi się łączysz, ale w szczególności dla biblioteki uruchomieniowej C - Microsoft dodał dodatkowy kod wykrywania błędów do malloc() i free(). Więc jeśli cokolwiek w twoim projekcie używa smaku debugowania biblioteki CRT, to wszystko powinno być.
Opcje/M (/ MTd i/MDd) są dziwne i magiczne, moim zdaniem - to tylko aliasy dla skomplikowanego zestawu innych rzeczy, które dzieje się za kulisami. Take/MDd na przykład, udokumentowane jako "Definiuje _DEBUG, _MT i _DLL i powoduje, że twoja aplikacja używa debugującej wielowątkowej i DLLowej wersji biblioteki wykonawczej, a także powoduje, że kompilator umieszcza nazwę biblioteki MSVCRTD. lib do pliku .obj. " Tutaj ma wpływ zarówno na preprocesor (definiujący _DEBUG i niektóre inne symbole preprocesora), jak i linker (w rzeczywistości umieszcza komentarz #pragma (linker) w kodzie źródłowym). Jeśli dbasz o to, co się dzieje i nie rozumiesz tego, może to powodować poważne problemy - widziałem wiele projektów, które nie używają IDE, grzęzną w ostrzeżeniach dotyczących zarówno msvcrt.lib, jak i msvcrtd.lib są połączone, itp. Do czasu, gdy zrozumiesz, jak bezpiecznie korzystać z tych (/ M opcji), nie potrzebujesz ich już więcej! Wolę robić rzeczy jawne: wpisz "-D _DEBUG" bezpośrednio tam, gdzie jest to potrzebne, określ, które biblioteki mają zostać połączone z jawnie (i użyj -nodefaultlib), a następnie opcje/M nie są potrzebne.
+1 Łał. Czy mogę zapytać, jak stałeś się zaznajomiony z dziwactwami narzędzia Microsoft Toolchain? :) –
Lata i lata korzystania z różnych wersji MSVC, wiele projektów krzyżowych, więc używaliśmy plików Makefile lub w inny sposób obchodziliśmy system budowania IDE, korzystając z bibliotek open-source zbudowanych przez 3rd parties, utrzymując całość prac przez uaktualnienia do nowych wersji MSVC lub SDK itp. :) – metamatt