Table of Contents
Η κατασκευή εφαρμογών C που μεταγλωττίζουν και τρέχουν αξιόπιστα σε Windows, macOS, και Linux απαιτεί περισσότερα από φορητό πηγαίο κώδικα ⁇ απαιτεί ένα σύστημα κατασκευής που προσαρμόζεται στην αρχική εργαλειοθήκη κάθε πλατφόρμας. CMake, μια γεννήτρια συστήματος κατασκευής ανοιχτού κώδικα, επιλύει αυτό επιτρέποντας σας να ορίσετε το έργο σας μια φορά σε ένα απλό αρχείο διαμόρφωσης και στη συνέχεια να παράγει αρχεία κατασκευής ειδικά για την πλατφόρμα (Makefiles, Visual Studio αρχεία λύσης, Xcode έργα, κλπ.). Αυτό το άρθρο παρέχει έναν πλήρη, πρακτικό οδηγό για τη δημιουργία ενός συστήματος κατασκευής cross-platform για έργα C με CMake, καλύπτοντας τα πάντα από τη βασική εγκατάσταση έως τις προηγμένες τεχνικές όπως διαχείριση εξάρτησης, δοκιμές, και αντισύλληψη.
Τι Είναι το CMake;
Το CMake είναι ένα μετα-κατασκευαστικό σύστημα: δεν μεταγλωττίζει απευθείας τον κώδικα αλλά δημιουργεί αρχεία εισόδου για άλλα συστήματα κατασκευής. Περιγράφετε το έργο σας σε [[LPT:0]] αρχεία χρησιμοποιώντας μια γλώσσα-συγκεκριμένη τομέα.
Βασικά χαρακτηριστικά της CMake περιλαμβάνουν:
- Πλατφόρμα-αγνωστική σύνταξη: Το ίδιο λειτουργεί στο Unix, στα Windows, και στο macOS.
- Πολλαπλές γεννήτριες: Υποστηριγές Μάρκα, Ninja, Visual Studio, Xcode, και άλλες.
- Εξωπορικά οικοδομήματα: Διατηρεί την κατασκευή τεχνουργημάτων ξεχωριστά από τον πηγαίο κώδικα.
- Επέκταση: Οι ενότητες, οι λειτουργίες και οι μακροεντολές επιτρέπουν επαναχρησιμοποιήσιμη λογική κατασκευής.
- Ανακάλυψη πακέτου: εντοπίζει εγκατεστημένες βιβλιοθήκες και κεφαλίδες.
- Εγκατάσταση με CI/CD: Λειτουργεί απρόσκοπτα σε αυτόματους αγωγούς.
Το CMake έχει γίνει το de facto πρότυπο για την ανάπτυξη cross-platform στο οικοσύστημα C και C++, που χρησιμοποιείται από έργα τόσο ποικίλα όσο το LLVM, το MySQL και ολόκληρο το περιβάλλον επιφάνειας εργασίας του KDE.
Οφέλη από τη χρήση CMake για την ανάπτυξη Cross-Platform C
Η υιοθέτηση της CMake φέρνει αρκετά συγκεκριμένα πλεονεκτήματα πέρα από την απλή φορητότητα:
- Μονή πηγή αλήθειας: Γράψτε τη λογική να οικοδομήσουμε μια φορά και να δημιουργήσουμε αρχεία για κάθε πλατφόρμα, εξαλείφοντας εύθραυστα σενάρια κελύφους ή ειδικά Makefiles πλατφόρμας.
- Ολοκλήρωση ΙΔΕ: Οι ομάδες μπορούν να εργαστούν σε Visual Studio, CLion, Xcode, ή VS Code ενώ μοιράζονται το ίδιο .
- Σύνδεση της δομής του έργου: Χρήση για τη διαίρεση των μεγάλων έργων σε διαχειρίσιμα συστατικά με τις δικές τους εξαρτήσεις.
- Συνθετική λογική: Εφαρμόστε σημαίες, αρχεία πηγών ή βιβλιοθήκες ειδικά για την πλατφόρμα μόνο όταν χρειάζεται, χωρίς να αναπαράγετε ολόκληρες διαμορφώσεις.
- Αυτοματοποιημένος χειρισμός εξάρτησης: ] και απλοποιεί χρησιμοποιώντας βιβλιοθήκες τρίτων.
- Δοκιμές και συσκευασία: Το CTest και το CPack είναι καλά ενσωματωμένα, καθιστώντας ασήμαντα τα πρόσθετα τεστ και τη δημιουργία εγκαταστάτων.
- Κατασκευαστική απόδοση: Η γεννήτρια νίντζα σε συνδυασμό με το CCAche μειώνει δραματικά τους χρόνους ανακατασκευής.
- Ενεργή κοινότητα: Τεταμένη επίσημη τεκμηρίωση και ακμάζον οικοσύστημα ενοτήτων και διδακτικών μαθημάτων.
Έναρξη: ⁇ CMake για ένα έργο C
Το τμήμα αυτό περνά μέσα από την πλήρη ροή εργασίας από την εγκατάσταση σε ένα μεταγλωττισμένο εκτελέσιμο σε τρεις μεγάλες πλατφόρμες.
1. Εγκαταστήστε το CMake
Κατεβάστε το τελευταίο δυαδικό από cmake.org ή χρησιμοποιήστε το διαχειριστή πακέτων του συστήματός σας:
- Linux (Ντεμπιάν/Ουμπούντου):
- macOS (Αρχική):
- Windows: Εκτελέστε τον εγκαταστάτη και βεβαιωθείτε ότι επιλέγεται η «Προσθήκη CMake στο σύστημα PATH».
Επαλήθευση εγκατάστασης με [[LFT:9]]. Έκδοση 3.10 ή υψηλότερη συνιστάται για τα χαρακτηριστικά που εξετάζονται εδώ.
2. Γράψτε ένα ελάχιστο CMakeLists.txt
Δημιουργία ενός αρχείου με το όνομα στη ρίζα του έργου σας. Παρακάτω είναι ένα ελάχιστο παράδειγμα για ένα έργο C ενός πηγαίου κώδικα:
cmake_minimum_required(VERSION 3.10)
project(HelloWorld C)
add_executable(hello main.c)
Ανάλυση:
- θέτει την ελάχιστη έκδοση CMake. Αυτό επιτρέπει επίσης ενημερώσεις πολιτικής που βελτιώνουν τη συμπεριφορά.
- ορίζει το όνομα του έργου και τη γλώσσα. Ο προσδιορισμός εμποδίζει την CMake να σαρώσει για μεταγλωττιστές C++.
- λέει η CMake ότι ο στόχος πρέπει να κατασκευαστεί από .
Ένα ελαφρώς πιο ρεαλιστικό παράδειγμα προσθέτει σημαίες μεταγλωττιστών και μια εξάρτηση μόνο κεφαλίδας:
cmake_minimum_required(VERSION 3.15)
project(Calculator C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_executable(calc main.c parser.c)
target_include_directories(calc PRIVATE include)
Εδώ προσθέτει στην διαδρομή αναζήτησης κεφαλίδας του μεταγλωττιστή μόνο για τον στόχο .
3. Δημιουργία αρχείων κατασκευής
Δημιουργία ενός καταλόγου κατασκευής και εκτέλεση του CMake:
mkdir build
cd build
cmake ..
Στα Windows με το Visual Studio εγκατεστημένο, δημιουργεί ένα αρχείο [[LFT:23]]. Για να ζητήσετε μια διαφορετική γεννήτρια, χρησιμοποιήστε [[LFT:24]].
Μετά τη γενιά, μπορείτε να περάσετε επιλογές κατά τη ρύθμιση του χρόνου:
cmake .. -DCMAKE_BUILD_TYPE=Release -DMY_FEATURE=ON
Οι μεταβλητές αυτές αποθηκεύονται σε και επαναχρησιμοποιούνται σε επόμενες διαδρομές.
4. Κατασκευάστε το Έργο
Μόλις δημιουργηθούν αρχεία κατασκευής, μεταγλωττίστε:
- Make/Ninja: (εργάζεται σε όλες τις πλατφόρμες και γεννήτριες)
- Οραματικό Studio:
- Χωδικός:
Η εντολή είναι διαπλατφόρμα και αποφεύγει τις ειδικές επίκλησης πλατφόρμας. Χρησιμοποιήστε [[LFT:31]] για να επιταχύνετε τις δομές.
Προηγμένες τεχνικές CMake για τα πραγματικά-κόσμο έργα
Πέρα από τα βασικά, το CMake προσφέρει χαρακτηριστικά που βελτιώνουν τις μεγαλύτερες ή πιο σύνθετες κατασκευές.
Διαχείριση εξαρτήσεων με find package
Η εντολή εντοπίζει εγκατεστημένες βιβλιοθήκες και θέτει μεταβλητές για τις διαδρομές και τα αρχεία της βιβλιοθήκης. Η σύγχρονη CMake ενθαρρύνει τη χρήση [[LFT:0]] εισαγόμενων στόχων[[[LFT:1]] για την καθαρή διάδοση εξάρτησης:
find_package(SDL2 REQUIRED)
target_link_libraries(my_app PRIVATE SDL2::SDL2)
Οι εισαγόμενοι στόχοι φέρουν αυτόματα καταλόγους, μεταγλωττίζουν ορισμούς και συνδέουν σημαίες. Αν η βιβλιοθήκη δεν παρέχει αρχεία CMake config, μπορεί να χρειαστείτε μια ενότητα Εύρεσης. Γράψτε τη δική σας ή βασιστείτε σε αυτά της κοινότητας στο [[LFT:0]]]cmake-developer[[LFT:1]].
Για εξαρτήσεις χωρίς εγκατάσταση σε όλο το σύστημα, [[LFT:34]] κατεβάζει και ενσωματώνει τον πηγαίο κώδικα κατά τη ρύθμιση του χρόνου:
include(FetchContent)
FetchContent_Declare(
zlib
GIT_REPOSITORY https://github.com/madler/zlib.git
GIT_TAG v1.3
)
FetchContent_MakeAvailable(zlib)
target_link_libraries(my_app PRIVATE zlib)
Αυτή η προσέγγιση εξασφαλίζει αναπαραγώγιμα builds με την καρφιτσώστε συγκεκριμένες εκδόσεις.
Προσθέτοντας δοκιμές με CTest
Το CMake ενσωματώνει τις δοκιμές μέσω του CTest. Ενεργοποιήστε το και ορίστε τις δοκιμές στο [[LFT:36]]:
enable_testing()
add_executable(test_parser test_parser.c)
target_link_libraries(test_parser PRIVATE parser_lib)
add_test(NAME ParserTest COMMAND test_parser)
Δοκιμή εκτέλεσης με:
ctest --output-on-failure
Για πιο ολοκληρωμένες δοκιμές, εξετάστε το συνδυασμό με ένα πλαίσιο δοκιμής μονάδας όπως [[LFT:0]]cmocka[[LFT:1]] συνδέοντας τη βιβλιοθήκη του και χρησιμοποιώντας [[LFT:39]].
Διασταύρωση
Το CMake απλοποιεί τη διασυναρμολόγηση μέσω [[LFT:0]] αρχείων toolchain[[LFT:1]]. Ένα αρχείο αλυσίδας εργαλείων θέτει τον μεταγλωττιστή, το sysroot, και την αρχιτεκτονική προορισμού. Δημιουργήστε ένα αρχείο όπως [[LFT:40]:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_SYSROOT /path/to/sysroot)
Στη συνέχεια επικαλέστε CMake με την αλυσίδα εργαλείων:
cmake -DCMAKE_TOOLCHAIN_FILE=arm-cross.cmake ..
Η CMake θα χρησιμοποιήσει αυτόματα τον καθορισμένο διασυνδετήρα και θα αναζητήσει το σύστημα για βιβλιοθήκες. Αυτή η τεχνική λειτουργεί για ενσωματωμένα συστήματα, κινητές πλατφόρμες, και οποιοδήποτε σενάριο όπου η μηχανή κατασκευής διαφέρει από τη μηχανή-στόχο. Ανατρέξτε στον επίσημο Cross Compiling with CMake[[LFT:1]] guide for details.
Εγκατάσταση και Συσκευασία
Χρησιμοποιήστε εντολές για τον καθορισμό του τρόπου ανάπτυξης του έργου σας:
install(TARGETS my_app DESTINATION bin)
install(FILES config.ini DESTINATION etc)
Η CPack δημιουργεί στη συνέχεια εγκαταστάτες: DEB, RPM, NSIS, DMG, κ.λπ. Προσθήκη στο τέλος της :
include(CPack)
Εκτέλεση για την παραγωγή ενός πακέτου Debian. Το CPack κληρονομεί όλους τους κανόνες εγκατάστασης και επιτρέπει την προσαρμογή μέσω μεταβλητών όπως .
Κοινές Παγίδες και Βέλτιστες Πρακτικές
Εδώ είναι συχνά ζητήματα και πώς να τους αποφύγει:
Παγίδα: Μονοπάτια HardCoding
Ποτέ μην χρησιμοποιείτε απόλυτες διαδρομές σε . Χρησιμοποιήστε και σε σχέση με το δέντρο πηγής. Για τοποθεσίες αρχείων, χρησιμοποιήστε για να ενσωματώσετε διαδρομές ή να βασιστείτε σε καταλόγους εγκατάστασης.
Παγίδα: Αγνοώντας τις εκφράσεις γεννητριών
Εκφράσεις γεννήτριας ([[LFT:53]]) αξιολογούν κατά τη στιγμή κατασκευής, δεν ρυθμίζουν το χρόνο. Είναι απαραίτητες για τις ρυθμίσεις ανά ρύθμιση:
target_compile_definitions(my_app PRIVATE
$<$<CONFIG:Debug>:_DEBUG>
)
Αυτό προσθέτει μόνο για τις κατασκευές Debug. Αποφύγετε τη χρήση επειδή οι γεννήτριες πολλαπλών ρυθμίσεων (Visual Studio, Xcode) δεν ρυθμίζουν κατά τη ρύθμιση του χρόνου.
Παγίδα: Υπερβολή των παγκόσμιων εντολών
Εντολές όπως , ] και επηρεάζουν όλους τους στόχους. Προτιμήστε συγκεκριμένες εντολές όπως , ] και για καλύτερη εγκλωβισμό.
Παγίδα: Δεν χρησιμοποιεί κατάλληλο πεδίο για την εύρεση πακέτο
Ορίστε το πεδίο εφαρμογής κατάλληλα. Με το σύγχρονο CMake, προτιμήστε [[LFT:65]] και στη συνέχεια συνδέστε τους στόχους του. Μην χρησιμοποιείτε [[LFT:66]] και χειροκίνητα ρυθμίστε καταλόγους συνδέσμων εκτός αν είναι απολύτως απαραίτητο.
Συμπέρασμα
Η CMake μετατρέπει την πρόκληση της ανάπτυξης πολλαπλών πλατφορμών C σε μια διαχειρίσιμη, επαναλαμβανόμενη διαδικασία. Με τη συγγραφή ενός μόνο συνόλου οδηγιών κατασκευής, αποκτάτε εγγενείς επιδόσεις, υποστήριξη IDE και ισχυρή διαχείριση εξάρτησης σε όλα τα μεγάλα λειτουργικά συστήματα. Ξεκινήστε με μια απλή [] και σταδιακά υιοθετήστε προηγμένα χαρακτηριστικά ⁇ δοκιμάζοντας, πολλαπλών συνθέσεων, συσκευασίας ⁇ καθώς μεγαλώνει το έργο σας. Η επένδυση στην εκμάθηση CMake αποπληρώνει κάθε φορά που χτίζετε, δοκιμάζετε, ή αναπτύσσεστε σε μια διαφορετική πλατφόρμα χωρίς να ξαναγράφετε μια ενιαία γραμμή κώδικα κατασκευής.