Budowa projektu za pomocą cmake, pliki w różnych katalogach

0

Witam forumowiczów!
Będę pisać duży projekt w cpp i postanowiłem nauczyć się cmake aby ułatwić sobie życie lecz problem w tym, że praktycznie każdy tutorial na jaki trafiłem jest inny od poprzedniego (w senie niespójny), a poza tym to nie znalazłem satysfakcjonującej odpowiedzi na mój problem. Pliki .hh znajdują się w folderze inc, pliki .cpp w src. W jaki sposób napisać plik cmake aby wszystko kompilowało się poprawnie? Dopiero zaczynam z cmake i chciałbym napisać ten skrypt w dość podstawowy sposób.

0

Są niespójne, choćby dlatego, że projekty/twórcy mają różne konwencje organizacji źródeł, własne style. Skrypt make jest "zaledwie" pochodną tych decyzji.
Może i dla ciebie to ważniejsze pytanie, np podział na moduły, zależności miedzy nimi, ilość kodu templejtowego/inline i "klasycznego" itd ...

Podstawowe użycie make nie było jakieś kosmicznie skomplikowane.

1

@Polski Strażak: W zasadzie nie ma znaczenia czy wrzucisz pliki .hh i .cpp do osobnych folderów, z punktu widzenia cmake'a istotne jest tylko to czy je dołączysz do projektu.

Podstawową rzeczą w cmake'u jest dodanie targetu, czyli tego co ma się zbudować. Typowy target to plik wykonywalny, który dodajesz przez:
add_executable()
albo biblioteka, którą dodajesz przez:
add_library()
Jako parametry podajesz nazwy i pliki źródłowe (.cpp). Reszta to dodatki (parametry kompilacji, jakieś definicje itp)

1

praktycznie każdy tutorial na jaki trafiłem jest inny od poprzedniego (w senie niespójny)

Weź tutorial traktujący o najnowszej wersji CMake i się go trzymaj.

a poza tym to nie znalazłem satysfakcjonującej odpowiedzi na mój problem.

Nie wiem jakiej odpowiedzi konkretnie oczekujesz bo podfoldery w cmake to najmniejszy problem.

Zamiast

set(SOURCES *.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})

piszesz

set(SOURCES src/*.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})
2

Deklarujesz sobie binarki z add_executable i biblioteki z add_library, podając jako argumenty nazwę targetu i listę plików źródłowych. Pliki nagłówkowe wskazujesz z target_include_directories (odpowiednik flagi -I w GCC), biblioteki dodajesz sobie z target_link_libraries (odpowiednik flagi -L w GCC). W najprostszej wersji

$ tree
.
├── CMakeLists.txt
├── inc
│   └── file.hh
└── src
    ├── file.cpp
    └── main.cpp

2 directories, 4 files
# CMakeLists.txt
cmake_minimum_required(VERSION 3.2)

project(MyApp VERSION 1.0.0 LANGUAGES CXX)

add_library(File src/file.cpp)
target_include_directories(File PRIVATE inc)

add_executable(Main src/main.cpp)
target_include_directories(Main PRIVATE inc)
target_link_libraries(Main PRIVATE File)
// inc/file.hh 
#ifndef FILE_HH
#define FILE_HH

class File {
public:
    File();
};

#endif
// src/file.cpp 
#include <file.hh>

#include <iostream>

File::File() {
    std::cout << "Hello, world\n";
}
// src/main.cpp 
#include <file.hh>

int main() {
    File file;
}
1
several napisał(a):

Nie wiem jakiej odpowiedzi konkretnie oczekujesz bo podfoldery w cmake to najmniejszy problem.>
Zamiast

set(SOURCES *.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})

piszesz

set(SOURCES src/*.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})

Nie jestem na bieżąco z najnowszymi wersjami cmake - od kiedy można użyć *.cpp w taki sposób?

Do wersji 3.11 działało

file(GLOB SOURCES *.cpp )

ale ta kostrukcja miała swoje problemy (wymuszała uruchomienie cmake po każdym dodaniu/usunięciu pliku).

W nowszych wersjach dodali opcję

file (GLOB_RECURSE SOURCES CONFIGURE_DEPENDS *.cpp )

Nie miałem jeszcze okazji żeby to testować w czymś większym.

@Polski Strażak:
Tu jest przykładowy BARDZO prosty projekt który przygotowuję dla studentów - work in progress, więc mogę coś w nim jeszcze zepsuć ;)
link

2

Dobry materiał o cmake z polski, w opisie filmu link do repo.

0
Polski Strażak napisał(a):

problem w tym, że praktycznie każdy tutorial na jaki trafiłem jest inny od poprzedniego (w senie niespójny),

Problem polega na tym, że w internecie wielu jak napisze ""hello world" to już biegnie pisać tutoriale, szkolenia, blogi, filmy na youtube.
Jak się znajdzie jakiś materiał, to najpierw trzeba go obejrzeć czy nie śmierdzi, zanim się go dotknie.

Polski Strażak napisał(a):

a poza tym to nie znalazłem satysfakcjonującej odpowiedzi na mój problem. Pliki .hh znajdują się w folderze inc, pliki .cpp w src. W jaki sposób napisać plik cmake aby wszystko kompilowało się poprawnie?

Polecam filmik powyżej.

Co do podziału plków na Src i inc lub include.
Ten katalog include / inc jest dodawany, żeby w trakcie budowania projektu poprawnie testować, czy publiczne nagłówki są prawidłowe.
Jeśli wszystko znajdzie się w jednym katalogu, to projekt będzie się kompilował, a po wyeksportowaniu użytkownik biblioteki będzie miał problemy, bo brakuje mu prywatnego pliku nagłówkowego.
Jeśli nagłówki publiczne trzymane są osobno, to testy wyłapią ten problem natychmiast, bo poszukują nagłówkó tylko z katalogu include, który zawiera tylko nagłówki publiczne. Sam test nie posiada w konfiguracji by szukać nagłówków w Src.

1 użytkowników online, w tym zalogowanych: 0, gości: 1