C ++ Linker вопрос дизайна - PullRequest
       4

C ++ Linker вопрос дизайна

1 голос
/ 20 июня 2011

Так что это больше вопрос дизайна, чем что-либо еще, хотя любая информация о компоновщике g ++ была бы потрясающей.

У меня есть файлы .cpp, встроенные в следующую структуру:

Main
Main/Utilities
Main/Utilities/Data

Когда я компилирую основную точку входа .cpp в Main, я должен указать все .cpp файлы, которые когда-либо использует любой связанный .cpp - это нормально работает для моего тестового проекта, который имеет только 5 связанных файлов, но этот проект будет расти очень быстро, и это, очевидно, невозможно. Есть ли способ обойти это? Что вызывает это?

Я попытался использовать "g ++ * .cpp", но он хочет, чтобы я все еще связывал другие. Я должен сделать что-то вроде "g ++ main.cpp Utilities / other.cpp Utilities / Data / data.cpp". other.cpp использует data.cpp, а main.cpp использует other.cpp. При компиляции other.cpp я должен указать data.cpp, как и раньше.

Большое спасибо за любые идеи или помощь!

Ответы [ 3 ]

3 голосов
/ 20 июня 2011

Общий подход к управлению большим проектом состоит в том, чтобы использовать правильную структуру каталогов (например, ту, что у вас уже есть), а затем помещать Makefile в каждый каталог. Верхний уровень Makefile должен рекурсивно вызывать требуемый Makefiles. Каждый Makefile должен указывать исходные файлы, которые должны быть скомпилированы из этого каталога (и другие флаги компиляции, если требуется). В идеале вы должны создавать статические библиотеки (или, возможно, динамические) в зависимости от ваших требований. После того, как вы собрали весь зависимый код (значит, у вас есть файлы .lib или .o), вы должны скомпилировать исходный файл, имеющий точку входа (например, функция main в c / c ++) и указав зависимый библиотеки для компоновщика (ld).

Например, просто посмотрите на любой проект с открытым исходным кодом, который имеет как минимум двухуровневую структуру каталогов.

0 голосов
/ 20 июня 2011

Я предполагаю, что вы на самом деле находитесь в UNIX (подобной) системе, поэтому оболочка заменит спецификацию подстановочного знака *.cpp на фактические имена файлов. Другие системы могут вести себя по-другому, хотя я в этом сомневаюсь.

Вы сохранили свои файлы в структуре каталогов, поэтому просто сказав, что *.cpp будет соответствовать файлу только в текущем каталоге, где вы вызываете g ++ - в вашем случае, предположительно, просто main.cpp.

Если вы хотите, чтобы все другие файлы также закрывались подстановочными знаками, вам также необходимо указать их в командной строке. В вашем случае:

g++ *.cpp Utilities/*.cpp Utilities/data/*.cpp

Если это действительно проще, чем просто назвать все файлы, я не могу судить.

РЕДАКТИРОВАТЬ: , как говорили другие, лучший способ для компиляции / сборки нетривиальных программ, конечно, с использованием make или некоторого сопоставимого инструмента сборки.

0 голосов
/ 20 июня 2011

... Я должен указать все файлы .cpp, которые когда-либо использует любой связанный .cpp ...

Это неверно. Вы должны предоставить компоновщику достаточно информации для разрешения всех символов, используемых в коде, но вы можете сделать это как файлы исходного кода (.cpp и др.), Как объектные файлы (.o) или как библиотеки (.so или. а). Достаточно скомпилировать каждый из файлов исходного кода в объектные файлы, а затем связать каждый из объектных файлов вместе, чтобы создать двоичный файл.

g++ foo.cpp -c -o foo.o
g++ bar.cpp -c -o bar.o
g++ main.cpp -c -o main.o
g++ main.o foo.o bar.o -o main.exe
...