Как скомпилировать файлы в другом каталоге в С++?

Я делаю более сложный проект на C++, но этот пример аналогичен тому, что мне нужно, и названия примеров будут просто изменены, но, опять же, это то же самое, что и я. Допустим, у меня есть такая файловая структура:

|--project/
|--main.cpp
|--include/
|      |--class1.hpp
|      |--class2.hpp
|--impl/
|      |--class1.cpp
|      |--class2.cpp

Класс2 имеет зависимость класса1.

class1.hpp

#ifndef CLASS1_HPP
#define CLASS1_HPP

class class1 {
private: string name;
}

#endif

class2.hpp

#ifndef CLASS2_HPP
#define CLASS2_HPP

#include "class1.hpp"

class class2 {
private: Class1 class1;
}

#endif

class1.cpp

#include "class1.hpp"
#include <iostream>

(functions implemantations...)

}

class2.cpp

#include "class2.hpp"
#include "class1.hpp"
#include <iostream>

(functions implemantations...)

}

main.cpp

#include "class2.hpp"
#include <iostream>

int main() {
    Class2 class2;
    (...)
    return 0;
}

То есть мои .hpp и .cpp находятся в разных каталогах, как мне скомпилировать классы в разных каталогах?

Используйте инструмент автоматизации, такой как cmake и т. д.

user12002570 12.04.2024 03:43

Хорошо! Есть ли у вас ссылка, которая поможет мне узнать больше об этом? А если я хочу скомпилировать в терминале? для чего я использую?

Ramon Jales 12.04.2024 03:44
Cmake: базовая отправная точка. Также есть книги и руководства по теме «cmake».
user12002570 12.04.2024 03:46

«Как мне скомпилировать классы в разных каталогах?...» Если вы не используете, скажем, cmake и т. д., вы также можете скомпилировать несколько файлов из определенного каталога одновременно. Ставьте лайк g++ *.cpp -o output. См. Использование G++ для компиляции нескольких файлов .cpp и .h. Но я настоятельно рекомендую использовать cmake и т. д., чтобы сделать это автоматически.

user12002570 12.04.2024 03:49

«А если я хочу скомпилировать в терминале? для чего мне это использовать?» Обычно я использую CMake из терминала.

jabaa 12.04.2024 03:58

Независимо от того, какой инструмент автоматизации вы используете, вам необходимо решить две проблемы (1) при компиляции, чтобы каждая директива #include однозначно разрешалась в правильный заголовок. Все компиляторы командной строки, IDE и соответствующие инструменты автоматизации поддерживают возможность указать «путь включения» (и один и тот же путь включения должен использоваться при компиляции каждого исходного файла). Также необходимо либо обеспечить возможность поиска всех объектных файлов при связывании, либо указав путь для связывания (где искать объекты), либо ссылаясь при связывании на полные имена объектных файлов/библиотек.

Peter 12.04.2024 04:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
6
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Просто скомпилируйте из терминала

См. справку по команде g++:

gcc -help | grep " \-I"
  -I-                     Restrict all prior -I flags to double-quoted inclusion and remove current directory from include path
  -I <dir>                Add directory to the end of the list of include search paths

Вы можете просто скомпилировать свой код следующим образом:

g++ -Wall -Iinclude main.cpp impl/class1.cpp impl/class2.cpp -o project

Показанная команда означает:

  1. Включить все предупреждения
  2. при поиске включенных заголовков компилятор должен искать не только в системных каталогах include, но и в include
  3. добавить все исходные файлы
  4. выведите исполняемый файл с именем project

Но это слишком сложно, особенно когда вам нужно несколько раз компилировать и тестировать.

Используйте инструмент автоматизации

Вообще говоря, есть 2 варианта: make и cmake.

Для вашего понимания следующие решения являются упрощенными, но не очень элегантными.

Делать

all: main.o class1.o class2.o
    gcc -Wall main.o class1.o class2.o -o project

main.o: main.cpp
    gcc -c -Wall main.cpp -o main.o

class1.o: impl/class1.cpp
    gcc -c -Wall -Iinclude impl/class1.cpp -o class1.o

class2.o: impl/class2.cpp
    gcc -c -Wall -Iinclude impl/class2.cpp -o class2.o

clean:
    rm -f project main.o class1.o class2.o

Поместите это в свой каталог project, назовите его Makefile и запустите: make

❯ make
gcc -c -Wall main.cpp -o main.o
gcc -c -Wall -Iinclude impl/class1.cpp -o class1.o
gcc -c -Wall -Iinclude impl/class2.cpp -o class2.o
gcc -Wall main.o class1.o class2.o -o project

Появится исполняемый файл с именем project. Вы можете запустить make clean, чтобы удалить все .o файлы и ваш project исполняемый файл.

CMake

cmake_minimum_required(VERSION 3.15)

project(project)

add_executable(project 
  main.cpp
  impl/class1.cpp 
  impl/class2.cpp
)
target_include_directories(project PRIVATE include)

Поместите это в каталог project и назовите CMakeLists.txt. Бегать:

cmake -B build # This generate a build dir under `project` dir and names it `build`
cmake --build build # This builds your project

Ваш исполняемый файл будет помещен в каталог build.

Другие вопросы по теме