C++, “Старомодный” путь

Я изучал C++ в школе для создания маленьких программ командной строки.

Однако я только разработал свои проекты с IDE, включая VS08 и QtCreator.

Я понимаю процесс позади разрабатывания проекта: скомпилируйте источник в объектный код, затем свяжите их в исполняемый файл, который является конкретной платформой (.exe, .app, и т.д.). Я также знаю, что большинство проектов также использует make оптимизировать процесс компиляции и соединения нескольких исходных и заголовочных файлов.

Вещь, хотя IDE делают все это под капотом, делая жизнь очень легкой, я действительно не знаю то, что действительно происходит, и чувствуйте, что я должен привыкнуть к строительным проектам "старомодный путь": из командной строки, с помощью набора инструментальных средств явно.

Я знаю что Makefiles, но не, как записать им.
Я знаю что gcc делает, но не, как использовать его.
Я знаю то, что компоновщик делает, но не, как использовать его.

То, что я ищу, является или объяснением или ссылкой на учебное руководство, которое объясняет, рабочий процесс для проекта C++, от первого написания кода до выполнения произведенного исполняемого файла.

Я действительно хотел бы знать какой, как, и почему из создания C++.

(Если это имеет какое-либо значение, я запускаю Mac OS X, с gcc 4.0.1 и делаю 3.81),

Спасибо!

9
задан Austin Hyde 23 December 2011 в 23:57
поделиться

8 ответов

Компиляция

Скажем, вы хотите написать простое приложение "hello world". У вас есть 3 файла, hello.cpp hello-writer.cpp и hello-writer.h, содержимое которых

// hello-writer.h
void WriteHello(void);

// hello-writer.cpp
#include "hello-writer.h"
#include <stdio>
void WriteHello(void){
    std::cout<<"Hello World"<<std::endl;
}

// hello.cpp
#include "hello-writer.h"
int main(int argc, char ** argv){
    WriteHello();
}

*.cpp файлы преобразуются в объектные файлы с помощью g++, используя команды

g++ -c hello.cpp -o hello.o
g++ -c hello-writer.cpp -o hello-writer.o

Флаг -c пропускает линковку на данный момент. Чтобы соединить все модули вместе, необходимо запустить

g++ hello.o hello-writer.o -o hello

, создав программу -c. Если вам необходимо связать какие-либо внешние библиотеки, вы добавляете их в эту строку, например -lm для математической библиотеки. Реальные файлы библиотек будут выглядеть как libm.a или libm.so, при добавлении флага компоновщика вы игнорируете суффикс и 'lib' часть имени файла.

Makefile

Для автоматизации процесса сборки вы используете makefile, который состоит из серии правил, в которых перечислены вещи, которые нужно создать, и файлы, необходимые для его создания. Например, hello.o зависит от hello.cpp и hello-writer.h, его правило равно

hello.o:hello.cpp hello-writer.h
     g++ -c hello.cpp -o hello.o # This line must begin with a tab.

Если вы хотите прочитать руководство по созданию, оно расскажет вам, как использовать переменные и автоматические правила для упрощения вещей. Вы должны быть в состоянии просто написать

hello.o:hello.cpp hello-writer.h

и правило будет создано автоматически. Полный makefile для примера приветствия имеет вид

all:hello
hello:hello.o hello-writer.o
    g++ hello.o hello-writer.o -o hello
hello.o:hello.cpp hello-writer.h
    g++ -c hello.cpp -o hello.o
hello-writer.o:hello-writer.cpp hello-writer.h
    g++ -c hello-writer.cpp -o hello-writer.o

Помните, что строки с отступами должны начинаться с табуляции. Не то чтобы не все правила нуждались в реальном файле, цель all просто говорит create hello. Обычно это первое правило в makefile, первое правило создается автоматически при запуске make.

Со всеми этими настройками вы сможете перейти в командную строку и запустить

$ make
$ ./hello
Hello World

More advanced Makefile

Есть также несколько полезных переменных, которые вы можете определить в makefile, в том числе

  • CXX: c++ компилятор
  • CXXFLAGS: Дополнительные флаги для передачи компилятор (например, включить каталоги с -I)
  • LDFLAGS: Дополнительные флаги к перейти к компоновщику
  • LDLIBS: Библиотеки для компиляции
  • CC: c компилятором (также используется для ссылка)
  • CPPFLAGS: флаги препроцессора

Определение переменных с помощью =, добавление к переменным с помощью +=.

Правило по умолчанию для преобразования .cpp файла в .o файл равно

$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@

, где $< является первой зависимостью, а $@ - выходным файлом. Переменные расширяются путем добавления их в $(), это правило будет выполняться по шаблону hello.o:hello.cpp

Аналогично, правило компоновщика по умолчанию равно

$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)

, где $^ - это все предпосылки. Это правило будет выполняться по шаблону hello:hello.o hello-writer.o. Обратите внимание, что при этом используется компилятор c, если вы не хотите переопределять это правило и используете c++, добавьте библиотеку -lstdc++ в LDLIBS со строкой

LDLIBS+=-lstdc++

в makefile.

Наконец, если вы не перечислите зависимости файла make .o, то сможете найти их сами, так что минимальный makefile может быть

LDFLAGS=-lstdc++
all:hello
hello:hello.o hello-writer.o

Обратите внимание, что при этом игнорируется зависимость двух файлов от hello-writer.h, так что если заголовок изменен, то программа не будет перестроена. Если вы заинтересованы, проверьте флаг -MD в gcc docs на то, как вы можете автоматически сгенерировать эту зависимость.

Final makefile

Разумным окончательным makefile будет

// Makefile
CC=gcc
CXX=g++
CXXFLAGS+=-Wall -Wextra -Werror
CXXFLAGS+=-Ipath/to/headers
LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect 
                 # (watch out for c code though!)

all:hello                                   # default target
hello:hello.o hello-world.o                 # linker
hello.o:hello.cpp hello-world.h             # compile a module
hello-world.o:hello-world.cpp hello-world.h # compile another module
    $(CXX) $(CXXFLAGS) -c $< -o $@          # command to run (same as the default rule)
                                            # expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o
15
ответ дан 4 December 2019 в 07:14
поделиться

Чтобы выкинуть это туда, здесь можно найти всю документацию по gcc: http://www.delorie.com/gnu/docs/gcc/gcc_toc.html

2
ответ дан 4 December 2019 в 07:14
поделиться

компилятор принимает CPP и превращается в объектный файл, который содержит нативный код и некоторую информацию об этом нативном коде

линкер принимает объектные файлы и устанавливает выяснение, используя дополнительную информацию в Объектный файл .... Он находит все ссылки на то же самое и связывает их, и делает и изображение полезно для операционной системы, чтобы узнать, как загрузить весь код в память.

Проверьте форматы файлов объектов, чтобы лучше понять, что производит компилятор

http://en.wikipedia.org/wiki/object_file (разные компиляторы используют разные форматы)

также проверьте (для GCC)

http://pages.cs.wisc.edu/~beeChung/ref/gcc-intro.html на то, что вы введите в командной строке

0
ответ дан 4 December 2019 в 07:14
поделиться

Вы также можете посмотреть в Autoproject, который устанавливает AutoProject и Autoconf файлы, что облегчает людей скомпилировать ваши пакеты на разных платформах: http://packages.debian.org/unstable/devel/autoproject

0
ответ дан 4 December 2019 в 07:14
поделиться

Мне нравится это причудливое введение в сборку программы hello world с помощью gcc, основанной на Linux, но командная строка должна отлично работать на OS/X. В частности, она проводит вас через совершение некоторых распространенных ошибок и просматривает сообщения об ошибках.

Святые компиляторы, Робин, чертова штука сработала!

0
ответ дан 4 December 2019 в 07:14
поделиться

Простой пример часто полезен для поставки Основная процедура, поэтому:

Образец использования GCC для компиляции файлов C ++:

$ g++ -c file1.cpp                 # compile object files
[...]
$ g++ -c file2.cpp
[...]
$ g++ -o program file1.o file2.o   # link program
[...]
$ ./program                        # run program

Использование Make Для этого можно использовать , чтобы можно было использовать следующий makefile:

# main target, with dependencies, followed by build command (indented with <tab>)
program: file1.o file2.o
    g++ -o program file1.o file2.o

# rules for object files, with dependencies and build commands
file1.o: file1.cpp file1.h
    g++ -c file1.cpp

file2.o: file2.cpp file2.h file1.h
    g++ -c file2.cpp

Образец использования makefile:

$ make                              # build it
[...]
$ ./program                         # run it

Для всех деталей вы можете посмотреть на GNU MUSIC и документацию GCC .

10
ответ дан 4 December 2019 в 07:14
поделиться

Я знаю, что такое Makefile, но не знаю, как их писать.

Синтаксис make ужасен, но GNU make docs неплохие. Основной синтаксис:

<target> : <dependency> <dependency> <dep...>
<tab>    <command>
<tab>    <command>

Который определяет команды для построения цели из заданных зависимостей.

Чтение документации и примеров, вероятно, является тем, как большинство людей изучают make-файлы, поскольку существует множество разновидностей make с небольшими отличиями. Загрузите несколько проектов (выберите что-то, что работает в вашей системе, чтобы вы действительно могли попробовать), посмотрите на систему сборки и посмотрите, как они работают.

Вам также следует попробовать создать простой make (уберите кучу более сложных функций для вашей первой версии); Я думаю, что это тот случай, когда это поможет вам лучше понять ситуацию.

Я знаю, что делает gcc, но не знаю, как его использовать.

Опять же, man g ++ , информационные страницы и другая документация полезны, но основное использование, когда вы вызываете его напрямую (а не через систему сборки), будет:

g++ file.cpp -o name            # to compile and link
g++ file.cpp other.cpp -o name  # to compile multiple files and link as "name"

Вы также можете написать ваш собственный сценарий оболочки (ниже мой упрощенный ~ / bin / c ++) для включения $ CXXFLAGS, чтобы вы не забыли:

#!/bin/sh
g++ $CXXFLAGS "$@"

Вы также можете включить любую другую опцию. Теперь вы можете установить эту переменную среды ($ CXXFLAGS, стандартную переменную для флагов C ++) в вашем .bashrc или аналогичном файле или переопределить ее в конкретном сеансе для работы без make-файла (что делает make тоже отлично).

Также используйте флаг -v , чтобы увидеть подробности того, что делает g ++, включая ...

Я знаю, что делает компоновщик, но не знаю, как его использовать.

Компоновщик - это то, что берет объектные файлы и связывает их, как я уверен, вы знаете, но g ++ -v покажет вам точную команду, которую он использует. Сравните gcc -v file.cpp (gcc может работать с файлами C ++) и g ++ -v file.cpp , чтобы увидеть разницу в командах компоновщика, которая часто вызывает например, первый, кто потерпел неудачу. Make также показывает команды в том виде, в котором они выполняются по умолчанию.

Лучше не использовать компоновщик напрямую, потому что гораздо проще использовать либо gcc, либо g ++ и при необходимости дать им определенные параметры компоновщика.

4
ответ дан 4 December 2019 в 07:14
поделиться

Это то, что помогло мне изучить autoconf, automake, ...:

http: //www.bioinf.uni-freiburg. de / ~ mmann / HowTo / automake.html

Это хороший учебник, в котором от простого helloworld к более продвинутым структурам с библиотеками и т. д.

0
ответ дан 4 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: