Измислих добра структура за нов проект, който в момента използвам успешно.
ЗАБЕЛЕЖКА: Тази структура е от полза за проекта, който е разработен от множество програмисти.
<Project Directory>
+ include
+ Haroogan
+ Utility
- util.h
+ More
- more.h
+ Whatever
- whatever.h
+ src
+ Haroogan.More <--- Artifact
- more.h
- more.cpp
- CMakeLists.txt
+ Haroogan.More.Whatever <--- Artifact
- whatever.h
- whatever.cpp
- CMakeLists.txt
+ Haroogan.Utility <--- Artifact
- util.h
- util.cpp
- CMakeLists.txt
+ Haroogan.Application <--- Artifact
- app.h
- app.cpp
- CMakeLists.txt
- CMakeLists.txt <--- "Root" CMakeLists.txt
Артефакт - е библиотека, изпълним файл и т.н. - разбрахте смисъла.
Име на артефакт (както в темата) - е просто името на артефакта, което се извежда от CMake от името на директорията, посветена на артефакта. Всъщност термините Artifact и Artifact-Name са по същество едни и същи. Например: артефактът, намиращ се в директория „Haroogan.More.Whatever“, има име „Haroogan.More.Whatever“.
Това има няколко последствия:
- библиотека, изпълним файл и т.н., произведени след компилация, ще бъдат наименувани с Artifact-Name;
- целият изходен код, отнасящ се до определен артефакт, е затворен в пространство от имена, съответстващо на името на артефакта. Например: артефактът "Haroogan.More.Whatever" налага "Haroogan::More::Whatever" пространство от имена на всички свои източници;
- когато един артефакт иска да използва друг, тогава човек трябва да включи заглавките на друг и по желание да се свърже с него. Въпреки това, всички знаем, че писането на
#include "../Haroogan.More/more.h"
не само изглежда объркано, но също така нарушава основната идея, че артефактите всъщност представляват самостоятелни компоненти, които трябва да бъдат отделени дори по отношение на файловата система. Освен това концепцията за частни заглавки също е нарушена, защото по този начин имам достъп до всякакви заглавки в други артефакти.
Това, от което се нуждаем тук, е просто публично хранилище на заглавки – директорията „включване“. Затова, за да се справя с последния проблем - реших да направя следното:
- всеки артефакт решава (разбира се, в своя CMakeLists.txt) сам кои хедъри иска да експортира към външния свят;
- след това копира (при всяка компилация, но само когато е необходимо, разбира се) тези заглавни файлове в съответната директория вътре в "include". Например, ако Artifact-Name е "Haroogan.More.Whatever", тогава заглавките ще бъдат копирани в директорията "include/Haroogan/More/Whatever/" (както е показано по-горе).
Вярвам, че това е хубав и стабилен подход, тъй като сега, ако искам да използвам класове "каквото" и "повече" от артефакти "Haroogan.More.Whatever" и "Haroogan.More" в други компоненти - просто пиша:
#include <Haroogan/More/Whatever/whatever.h>
#include <Haroogan/More/more.h>
using Haroogan::More::Whatever::whatever;
using Haroogan::More::more;
Системата работи като чар (мога да осигуря CMake скриптове, ако някой иска). Въпреки това не съм доволен от факта, че заглавките се копират. Би било много по-добре, ако например вместо да копира "whatever.h" CMake създаде нов файл "whatever.h" в "Haroogan/More/Whatever/" и инжектира #include "../../../../src/Haroogan.More.Whatever/whatever.h"
в него.
Моята система в момента е напълно автоматизирана. С други думи, пътят "Haroogan/More/Whatever" автоматично се извежда от името на артефакта "Haroogan.More.Whatever". Ето защо би било чудесно, ако инжектирането на #include "../../../../src/Haroogan.More.Whatever/whatever.h"
с всички тези гадни ../../
също бъде автоматизирано.
За съжаление, аз съм нов в CMake и не знам как да постигна тази функционалност, но мисля, че е възможно и може вече да е направено от някой. Благодаря ти.
РЕДАКТИРАНЕ:
Временно решение на този проблем може да бъде следното:
Вместо да създавам "whatever.h" вътре в "Haroogan/More/Whatever/", което незабавно води до справяне с ../../
бъркотия, мога просто да създам "Haroogan.More.Whatever.whatever.h" (като префикс "whatever.h" с „Haroogan.More.Whatever“) точно в директорията „включване“ и го използвайте като:
#include <Haroogan.More.Whatever.whatever.h>
using Haroogan::More::Whatever::whatever;
Това решение е приемливо, но не ми харесва толкова, колкото това, което ме интересува.