Как компилировать несколько файлов c
Как скомпилировать несколько файлов через консоль g++
Как скомпилировать программу написанную на Паскаль через консоль?
Помогите, пожалуйста. Как скомпилировать программу написанную на Паскаль через консоль. Есть файл.
Как скомпилировать несколько папок и файлов в EXE?
Как скомпилировать в exe одновременно и bat файл (который должен исполняться), и файлы, необходимые.
Как скомпилировать несколько файлов Python в один exe?
Здравствуйте, я написал калькулятор, но как скампилировать main и ui в один exe не знаю помогите.
Создание исполняемого файла проходит в два этапа: компиляция и компоновка. g++ позволяет запустить этот процесс в одну строчку. Во время компиляции работает компилятор и генерирует объектные файлы. Здесь главное, чтоб все используемые функции были вами объявлены, но необязательно определены. В местах вызова функций компилятор оставляет пометки для компоновщика: «Здесь идёт вызов такой-то функции. В одном из объектных файлов она есть». Компиляция cpp-файлов идёт по одному, независимо от других. В итоге объектные файлы состоят из блоков исполняемого кода с пометками для компоновщика.
Компоновщик объединяет объектные файлы в исполняемый. В местах пометок правильно расставляются адреса, по которым можно вызвать нужную функцию. Так всё работает упрощённо в моём понимании))
Как компилировать несколько файлов c
Это далеко не все пробемы, которые могут возникнуть при наличии программы «монстра». Поэтому при разработке программ рекомендуется их разбивать на куски, которые функционально ограничены и закончены. В этом значительно помогает сам язык C++, предоставляя свой богатый синтаксис.
Для того, чтобы вынести функцию или переменную в отдельный файл надо перед ней поставить зарезервированное слово extern. Давайте для примера создадим программу из нескольких файлов. Сначала создадим главную программу, в которой будут две внешние процедуры. Назовем этот файл main.c:
Теперь создаем два файла, каждый из которых будет содержать полное определение внешней функции из главной программы. Файлы назовем f1.c и f2.c:
Компилировать можно все файлы одновременно одной командой, перечисляя составные файлы через пробел после ключа -c:
Или каждый файл в отдельности:
В результате работы компилятора мы получим три отдельных объектных файла:
Чтобы их собрать в один файл с помощью gcc надо использовать ключ -o, при этом линкер соберет все файлы в один:
В результате вызова полученной программы rezult командой:
На экране появится результат работы:
Теперь, если мы изменим какую-то из процедур, например f1():
То компилировать заново все файлы не придется, а понадобится лишь скомпилировать измененный файл и собрать результирующий файл из кусков:
Таким образом можно создавать большие проекты, которые больше не будут отнимать много времени на компиляцию и поиск ошибок. Однако помните, не стоит также черезчур разбивать программу, иначе у Вас получится несколько десятков файлов, в которых Вы сами рано или поздно запутаетесь. Найдите «золотую середину», например в отдельные файлы помещайте те функции или классы, с которыми Вам приходится больше всего работать при отладке. После того, как функция будет окончательно отлажена, ее вполне можно перенести в более крупный файл.
Как компилировать несколько файлов c
В статье вы научитесь создавать программу из нескольких файлов
Содержание
Объявления и определения
Ради интереса решим задачу с помощью рекурсии:
Увы программа не компилируется. В C++ каждая функция должна быть объявлена или определена до первого использования, но в нашем случае printEvenRecursive использует printOddRecursive, а printOddRecursive использует printEvenRecursive! Мы не можем поместить определение одной функции выше другой так, чтобы каждая функция была объявлена перед использованием.
Но кроме определений функций в C++ есть объявления функций
Объявление функции похоже на определение функции, только вместо тела стоит точка с запятой:
Теперь мы можем переписать рекурсивный пример, просто разместив определения обеих функций в начале файла.
Хорошим стилем считается заранее и в одном месте писать объявления всех функций, кроме main. Вы можете писать объявления в начале cpp-файла или в заголовке. О заголовках читайте ниже.
Пишем свой заголовок
Мы могли бы убрать из заголовка printEvenRecursive и printOddRecursive, сделав его чище, но сейчас для примера оставим.
Запомните правила хорошего тона:
Обратите внимание: #include находится в cpp-файле, а не в заголовке, потому что экспортированные из iostream сущности нужны только в реализации функций, но не нужны в объявлении.
В конце создайте файл main.cpp и скопируйте в него код:
Компоновка программы из нескольких файлов
Собирая программу из одного файла с помощью g++, вы на деле выполняли одним махом два действия:
Сейчас эти же действия мы выполним раздельно. Отройте терминал и введите последовательно две команды:
Теперь мы вызовем g++ для компоновки объектных файлов. На выходе мы получим исполняемый файл print_executable.exe
На деле компилятор не будет компоновать: он передаст эту задачу утилите ld. Вызывать утилиту ld вручную мы не станем, потому что потребуются дополнительные флаги, которые включают компоновку со стандартной библиотекой C++.
Компоновка программы в CMake
CMake прячет факт раздельной компиляции файлов. Чтобы в CMake скомпоновать программу, состоящую из нескольких частей, просто перечислите эти файлы в add_executable.
Удалите файл print_recursive.exe :
Создайте файл CMakeFiles.txt с одной строкой:
Теперь выполните конфигурирование и сборку программы:
Многофайловые программы
Объектный код
Для программ, состоящих из нескольких файлов исходного кода, получение объектных файлов является необходимым. Именно из них потом компонуется единственный исполняемый файл.
Компиляция программы, состоящей из нескольких файлов исходного кода
В теле функции main() заполняется массив, состоящий из строк, а также массив указателей на эти строки. Далее в функции l2r() и r2l() передаются ссылки на первый элемент массива указателей и значение символической константы N. Эти функции осуществляют вывод элементов массива строк с отступами.
Чтобы получить исполняемый файл этой программы, надо сначала получить объектные файлы из исходных:
Тоже самое можно сделать за один вызов gcc:
Или даже вот так, если в каталоге находятся только файлы текущего проекта:
В любом случае в каталоге появятся два объектных файла: superprint.o и main.o. Далее их можно скомпилировать в один исполняемый файл так:
Обратите внимание на то, что в данном случае обязательно требуется указывать имя исполняемого файла. Такой вариант недопустим:
Если теперь запустить файл myprint, то программа будет ожидать ввода пяти слов, после чего выведет их на экран два раза по-разному (с помощью функций l2r() и r2l() ):
Создание заголовочных файлов
Куда правильней сообщать о неверном вызове функций уже при получении объектного файла. Поэтому хотя можно обойтись и без этого, но очень желательно сообщать функции main() прототипы функций, которые из нее вызываются. Это можно сделать, прописав объявления функций в файле main.c:
Теперь, если мы передадим неправильные параметры, ошибка возникнет уже на этапе получения объектных файлов.
А теперь представим, что программа у нас несколько больше и содержит десяток файлов исходного кода. Файл aa.c требует функций из файла bb.c, dd.c, ee.c. В свою очередь dd.c вызывает функции из ee.c и ff.c, а эти два последних файла активно пользуются неким файлом stars.c и одной из функций в bb.c. Программист замучится сверять, что чего вызывает откуда и куда, где и какие объявления надо прописывать. Поэтому все прототипы (объявления) функций проекта, а также совместно используемые символические константы и макросы выносят в отдельный файл, который подключают к каждому файлу исходного кода. Такие файлы называются заголовочными; с ними мы уже не раз встречались. В отличие от заголовочных файлов стандартной библиотеки, заголовочные файлы, которые относятся только к вашему проекту, при подключении к файлу исходного кода заключаются в кавычки, а не скобки. Об этом упоминалось в предыдущем уроке.
В принципе смысла подключать myprint.h к файлу superprint.c в данном случае нет, т.к. последний не использует никаких сторонних функций, кроме стандартной библиотеки. Но если планируется расширять программу и есть вероятность, что в файле superprint.c будут вызываться сторонние для него функции, то будет надежней сразу подключить заголовочный файл.
Обратим внимание еще на один момент. Стоит ли в описанном в этом уроке примере выносить константу N в заголовочный файл? Здесь нельзя дать однозначный ответ. Если ее туда вынести, то она станет доступна в обоих файлах, и поэтому можно изменить прототипы функций так, чтобы они принимали только один параметр (указатель), а значение N будет известно функциям их заголовочного файла. Однако стоит ли так делать? В функции r2l() второй параметр изменяется в процессе ее выполнения, что делать с константой будет невозможно. Придется переписывать тело функции. Кроме того, вдруг в последствии нам захочется использовать файл superprint.c в другом проекте, где будут свои порядки, и константы N в заголовочном файле не найдется.
В таком случае лучше N не выносить в заголовочный файл. Хотя имейте в виду, в каких-то проектах символическая константа может использоваться так часто и во множестве функций, что ее будет лучше поместить в заголовочный файл.
Особенности использования глобальных переменных
Однако в языке программирования C есть проблема. С помощью return можно вернуть только одно значение. Но могут быть случаи, когда функция должна изменить несколько переменных (здесь не имеются ввиду элементы массива). В таком случае без глобальных переменных обойтись сложно.
Напишите простые наглядные примеры, использования глобальных функций:
2.7 – Программы с несколькими файлами исходного кода
Добавление файлов в ваш проект
По мере того, как программы становятся больше, в целях организации или повторного использования их обычно разделяют на несколько файлов. Одним из преимуществ работы с IDE является то, что они значительно упрощают работу с несколькими файлами. Вы уже знаете, как создавать и компилировать однофайловые проекты. Добавить новые файлы в существующие проекты очень просто.
Лучшая практика
Для пользователей Visual Studio
В Visual Studio кликните правой кнопкой мыши на папке Исходные файлы (Source Files) в окне Обозревателя решений (Solution Explorer) и выберите Добавить (Add) → Создать элемент… (New Item…).
Рисунок 1 – Добавление нового файла в проект в Visual Studio
Убедитесь, что у вас выбран Файл C++ (.cpp). Дайте новому файлу имя, и он будет добавлен в ваш проект.
Рисунок 2 – Создание нового файла в проекте в Visual Studio
Примечание. Если вы создаете новый файл из меню Файл (File), а не из своего проекта в обозревателе решений, новый файл не будет добавлен в ваш проект автоматически. Вам придется добавить его в проект вручную. Для этого кликните правой кнопкой мыши на папке Исходные файлы (Source Files) в окне Обозревателя решений (Solution Explorer) и выберите Добавить (Add) → Существующий элемент (Existing Item), а затем выберите свой файл.
Теперь, когда вы компилируете свою программу, вы должны увидеть, как компилятор перечисляет имя вашего файла при компиляции.
Для пользователей Code::Blocks
В Code::Blocks перейдите в меню File (Файл) и выберите New (Создать) → File… (Файл…).
Рисунок 3 – Создание нового файла в Code::Blocks
В диалоговом окне New from template (Создать из шаблона) выберите C/C++ source (Исходный файл C/C++) и нажмите Go (Перейти).
Рисунок 4 – Создание нового исходного файла C/C++ в Code::Blocks
На этом этапе вы можете увидеть или не увидеть приветствие в диалоговом окне мастера создания исходного файла C/C++. Если да, щелкните Next (Далее).
Рисунок 5 – Диалоговое окно мастера создания исходного файла C/C++
На следующей странице мастера выберите C++ и нажмите Next (Далее).
Рисунок 6 – Выбор языка при создании нового исходного файла в Code::Blocks
Рисунок 7 – Указание имени файла и выбор конфигураций сборки
Теперь, когда вы будете компилировать свою программу, вы должны увидеть, как компилятор перечисляет имя вашего файла по мере компиляции.
Для пользователей GCC/G++
Из командной строки вы можете создать дополнительный файл самостоятельно, используя свой любимый редактор, и дать ему имя. Когда вы компилируете свою программу, вам нужно будет включить в строку компиляции все соответствующие исходные файлы. Например:
где main.cpp и add.cpp – это имена ваших исходных файлов, а main – имя выходного файла.
Пример с несколькими файлами
В уроке «2.6 – Предварительные объявления и определения» мы рассмотрели программу с одним исходным файлом, которая не компилируется:
Теперь посмотрим на аналогичную программу из нескольких исходных файлов:
Помните, что компилятор компилирует каждый файл отдельно. Он не знает о содержимом других исходных файлов и не запоминает что-либо, что он видел из ранее скомпилированных исходных файлов. Таким образом, даже если компилятор, возможно, видел определение функции add ранее (если он сначала скомпилировал add.cpp ), он этого не запомнил.
Эта ограниченная видимость и короткая память являются преднамеренными, чтобы файлы могли иметь функции или переменные, у которых одинаковые имена, но которые не конфликтуют друг с другом. В следующем уроке мы рассмотрим пример такого конфликта.
Наши варианты решения здесь такие же, как и раньше: поместить определение функции add перед функцией main или удовлетворить компилятор предварительным объявлением. В этом случае, поскольку функция add находится в другом файле, вариант изменения порядка определений не подходит.
Лучшее решение здесь – использовать предварительное объявление:
main.cpp (с предварительным объявлением):
add.cpp (остается прежним):
Используя этот метод, мы можем предоставить файлам доступ к функциям, которые находятся в другом файле.
Попробуйте скомпилировать add.cpp и main.cpp с предварительным объявлением. Если вы получили ошибку линкера, убедитесь, что вы правильно добавили add.cpp в свой проект или строку компиляции.
Что-то пошло не так!
Есть много вещей, которые могут пойти не так, когда вы в первый раз попытаетесь работать с несколькими файлами. Если вы попробовали приведенный выше пример и столкнулись с ошибкой, проверьте следующее:
2. Если вы получаете сообщение об ошибке компоновщика о том, что add не определена, например
2b. … возможно, вы добавили add.cpp не в тот проект.
2c. … возможно, что файл не компилируется или не линкуется. Проверьте свойства файла и убедитесь, что файл настроен для компиляции/линковки. В Code::Blocks компиляция и линковка – это отдельные флажки, которые следует установить. В Visual Studio есть параметр «исключить из сборки» (exclude from build), для которого следует установить значение «нет» или оставить пустым.
Резюме
Когда компилятор компилирует программу из нескольких исходных файлов, он может компилировать эти файлы в любом порядке. Кроме того, он компилирует каждый файл отдельно, не зная, что находится в других файлах.
Мы будем много работать с несколькими файлами, как только перейдем к объектно-ориентированному программированию, поэтому сейчас самое подходящее время, чтобы убедиться, что вы понимаете, как добавлять и компилировать проекты с несколькими файлами.
Напоминание: всякий раз, когда вы создаете новый исходный файл (.cpp), вам нужно будет добавить его в свой проект, чтобы он компилировался.