Dạo Đầu Với Cmake Thông Qua Ví Dụ
Nó hỗ trợ tính năng ra đời Makefile một biện pháp hiệu quả. Duy nhất là đối với các dự án công trình phức tạp. Nó cũng hỗ trợ thêm các bộ sinh khác nhằm sinh cấu trúc cai quản source cho các IDE khác biệt như Project mang lại Visual Studio, etc.
Bạn đang xem: Dạo đầu với cmake thông qua ví dụ
vào giới hạn, tôi sẽ nói tới việc áp dụng CMake để build một simple project bên trên Linux.
Bạn Đang Xem: CMake – khí cụ sinh Makefile, Project file mang đến source code C/C++

Ta vẫn xoay quanh ví dụ kinh khủng là sinh sản chương trình Hello World, tuy thế yêu cầu hiển thị câu kia trên tối thiểu 3 ngôn ngữ. Ja,en,vi. Lịch trình sẽ viết bằng ngôn ngữ C.
(Link tham khảo)
Ví dụ được tiến hành trong folder /home/oedev/Code/CMake
Nội dung thiết yếu gồm các phần sau,
Chương trình Hello World đến En.Thêm ngôn ngữ Ja, Vi vào chương trình trên.Thêm ngôn từ Spain(Es) trong một trường hợp khác.============================================================
Ta sẽ sở hữu được file source như sau: mainapp.c
#include // // Greeting message in En // void greeting_en() printf("Hello world n"); // // Main functions // int main(int argc, char* argv<>) greeting_en(); return 0; File thực hiện cho CMake là 1 trong file CMakeLists.txt. Nó sẽ có được nội dung như sau:
# # Điều kiện về version buổi tối thiểu nhằm đọc được file CMakeList.txt này. # cmake_minimum_required(VERSION 2.8.12) # # tên project thường xuyên sẽ là tên file chạy # project (helloworld) # # Định nghĩa mối tương quan giữa tệp tin chạy và file mối cung cấp # add_executable(hellworld mainapp.c) Đặt cả hai file bên trên vào thuộc 1 thư mục: văn bản được kiểm tra bởi lệnh tree như sau
CMake ├── CMakeLists.txt └── mainapp.c tệp tin CMakeList.txt đó là file quan niệm source sử dụng ngôn ngữ mà CMake phát âm được. Đến đây, ta thực hiện quá trình chính của CMake. Đó là ra đời Makefiles cho project đơn giản dễ dàng này. Ta cần chuyển vào bên trong thư mục CMake trước lúc chạy lệnh bên dưới đây:
$ cmake . Vệt . phía sau khôn cùng quan trọng. Đó là mặt đường dân đến thư mục chưa file CMakeList.txt hay rất có thể thay nó bằng $(PWD) trong trường hợp này. Văn bản chạy kết thúc nên như thế này:
manhongit.dhp
gmail.com:~/Code/CMake$ cmake . -- The C compiler identification is GNU 4.8.2 -- The CXX compiler identification is GNU 4.8.2 -- kiểm tra for working C compiler: /usr/bin/cc -- check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- kiểm tra for working CXX compiler: /usr/bin/c++ -- check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/oedev/Code/CMake văn bản thư mục sau thời điểm chạy lệnh trên:
manhongit.dhp
gmail.com:~/Code/CMake$ tree -L 2 . ├── CMakeCache.txt ├── CMakeFiles │ ├── 2.8.12.2 │ ├── cmake.check_cache │ ├── CMakeDirectoryInformation.cmake │ ├── CMakeOutput.log │ ├── CMakeTmp │ ├── hellworld.dir │ ├── Makefile2 │ ├── Makefile.cmake │ ├── progress.marks │ └── TargetDirectories.txt ├── cmake_install.cmake ├── CMakeLists.txt ├── mainapp.c └── Makefile Như ta thấy, có không ít file và thư mục được tạo nên khi ta chạy CMake. Tuy thế trong số lượng giới hạn bài này ta chỉ cân nhắc Makefile thôi. Ta cũng thấy rằng chương trình chưa được build, hay nói cách khác CMake chỉ làm trách nhiệm của nó đến đây thôi. Tức là sinh ra Makefile , rồi nghỉ.
Giờ ý muốn build project ta vừa tạo ban sơ (chỉ có một file .c), ta đang chạy Makefiles thôi.
Xem thêm: Ốp Lưng Tay Cầm Chơi Game Cho Iphone 6 Plus Chất Lượng, Giá Tốt 2021
manhongit.dhp
gmail.com:~/Code/CMake$ make Scanning dependencies of target hellworld <100%> Building C object CMakeFiles/hellworld.dir/mainapp.c.o Linking C executable hellworld <100%> Built target hellworld tác dụng thu được như sau
manhongit.dhp
gmail.com:~/Code/CMake$ ls CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt hellworld mainapp.c Makefile Ta vẫn thây file helloword được sinh ra, đây chính là file chạy:
manhongit.dhp
gmail.com:~/Code/CMake$ ./hellworld Hello world giờ ta vẫn thêm lời xin chào bằng ngôn ngữ Ja, Vi vào công tác trên.
Ta sẽ tổ chức lại source như sau:
manhongit.dhp
gmail.com:~/Code/CMake$ tree . ├── CMakeLists.txt ├── include │ ├── greetings_en.h │ ├── greetings_ja.h │ └── greetings_vi.h └── src ├── greetings_en.c ├── greetings_ja.c ├── greetings_vi.c └── mainapp.c Do cấu trúc thư mục đã rứa đổi, vị trí các file mối cung cấp cũng thế. Ta cần chuyển đổi file CMakeList.txt để phù hợp với chuyển đổi này. Văn bản file này sẽ thành như sau:
*CMakeList.txt* # # Điều kiện về version # cmake_minimum_required(VERSION 2.8.12) # # tên project # project (helloworld) # # Khai bảo thư mục cất file header (.h) # include_directories(include) # # Thêm từ file nguồn bằng lệnh *set* # set(SOURCES src/mainapp.c src/greetings_en.c src/greetings_ja.c src/greetings_vi.c) # # thêm 1 tập các file bằng một bộ lọc trong thư mục không source # Đây là phương pháp nhanh và thịnh hành hơn. # #file(GLOB SOURCES "src/*.c") # # Định nghĩa sự liên quan giữa file chạy và những file nguồn. # add_executable(hellworld $SOURCES) Ta đã chạy cmake để sinh Makefiles và build chương trình với Makefiles xem hiệu quả thế nào: Với những sử dụng hàm set: Chạy cmake
manhongit.dhp
gmail.com:~/Code/CMake$ cmake . -- The C compiler identification is GNU 4.8.2 -- The CXX compiler identification is GNU 4.8.2 -- kiểm tra for working C compiler: /usr/bin/cc -- kiểm tra for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- check for working CXX compiler: /usr/bin/c++ -- kiểm tra for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/oedev/Code/CMake Chạy Make
manhongit.dhp
gmail.com:~/Code/CMake$ make Scanning dependencies of target hellworld < 25%> Building C object CMakeFiles/hellworld.dir/src/mainapp.c.o < 50%> Building C object CMakeFiles/hellworld.dir/src/greetings_en.c.o < 75%> Building C object CMakeFiles/hellworld.dir/src/greetings_ja.c.o <100%> Building C object CMakeFiles/hellworld.dir/src/greetings_vi.c.o Linking C executable hellworld <100%> Built target hellworld Kiểm tra thư mục
manhongit.dhp
gmail.com:~/Code/CMake$ tree -L 2 . ├── CMakeCache.txt ├── CMakeFiles │ ├── 2.8.12.2 │ ├── cmake.check_cache │ ├── CMakeDirectoryInformation.cmake │ ├── CMakeOutput.log │ ├── CMakeTmp │ ├── hellworld.dir │ ├── Makefile2 │ ├── Makefile.cmake │ ├── progress.marks │ └── TargetDirectories.txt ├── cmake_install.cmake ├── CMakeLists.txt ├── hellworld ├── include │ ├── greetings_en.h │ ├── greetings_ja.h │ └── greetings_vi.h ├── Makefile └── src ├── greetings_en.c ├── greetings_ja.c ├── greetings_vi.c └── mainapp.c Kết quả chạy chương trình
manhongit.dhp
gmail.com:~/Code/CMake$ ./hellworld Hello world Konichiwa!!! Xin chao !!!! Khi cầm cố set command bằng command tệp tin (GLOB) thì cho tác dụng gần như hệt nhau nhau.
2.1 sản xuất thư mục để build riêng
À, bao gồm một điểm cần nói sinh sống đây, vừa ta tất cả thấy rất nhiều file (ngoài Makefile) được ra đời trong quá trình cmake chạy. Nếu như để những file đó phổ biến với thư mục các file source, header ta vừa sinh sản sẽ gây nên rắc rối, khó quản lý. Ta vẫn tống các file đó vào 1 thư mục, hotline là folder build. Cấu trúc thư mục sẽ biến đổi như sau:
manhongit.dhp
gmail.com:~/Code/CMake$ tree . ├── build ├── CMakeLists.txt ├── include │ ├── greetings_en.h │ ├── greetings_ja.h │ └── greetings_vi.h └── src ├── greetings_en.c ├── greetings_ja.c ├── greetings_vi.c └── mainapp.c tiếng ta sẽ thực hiện toàn thể quá trình cmake và make bên phía trong thư mục build
manhongit.dhp
gmail.com:~/Code/CMake/build$ cmake .. -- The C compiler identification is GNU 4.8.2 -- The CXX compiler identification is GNU 4.8.2 -- kiểm tra for working C compiler: /usr/bin/cc -- check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- check for working CXX compiler: /usr/bin/c++ -- check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/oedev/Code/CMake/build Ta thực hiện .. thay bởi vì . như ở các câu lệnh trước, vị ta đã đưa vào folder ./build yêu cầu file CMakeList.txt ngơi nghỉ thư mục phụ thân của thư mục này. Ta đề xuất nói mang đến cmake biết điều đó. Liên tục chạy lệnh make, ta sẽ có nội dung thư mục CMake đang như sau:
manhongit.dhp
gmail.com:~/Code/CMake$ tree -L 3 . ├── build │ ├── CMakeCache.txt │ ├── CMakeFiles │ │ ├── 2.8.12.2 │ │ ├── cmake.check_cache │ │ ├── CMakeDirectoryInformation.cmake │ │ ├── CMakeOutput.log │ │ ├── CMakeTmp │ │ ├── hellworld.dir │ │ ├── Makefile2 │ │ ├── Makefile.cmake │ │ ├── progress.marks │ │ └── TargetDirectories.txt │ ├── cmake_install.cmake │ ├── hellworld │ └── Makefile ├── CMakeLists.txt ├── include │ ├── greetings_en.h │ ├── greetings_ja.h │ └── greetings_vi.h └── src ├── greetings_en.c ├── greetings_ja.c ├── greetings_vi.c └── mainapp.c Như ta thấy, cục bộ nội dung của quá trình chạy cmake và make được duy trì trong thư mục ./build, phần đinh nghĩa source code phía bên ngoài không bị ảnh hưởng gì hết. Để chạy chương trình, ta cần vào thư mục ./build hiệu quả vẫn là :
manhongit.dhp
gmail.com:~/Code/CMake/build$ ./hellworld Hello world Konichiwa!!! Xin chao !!!! tình huống khác ở đây là gì? Tôi muốn nói tới tình huống như sau: đưa sử ta bao gồm một thư viện đựng lời chào cho 3 ngữ điệu En, Ja, Vi. Ta đề nghị thêm ngôn ngữ Es để có một chương trình với loài kính chào của 4 ngôn từ En, Ja, Vi, Es.
Trước hết, ta yêu cầu hiểu thư viện như thế nào? vào C/C++ để sử dụng lại được mã mối cung cấp hoặc để bảo đảm an toàn mã nguồn. Người ta thường build hồ hết mã nguồn mong muốn sử dụng lại hoặc đưa cho những người khác thành những thư viện. Về mặt tệp tin ta thấy được, thư viện sẽ có 2 loại: tủ sách tĩnh(.a) với thư viện động(.so). Các hàm ta sẽ viết trong file .c vẫn nằm trong số file tủ sách này.
Nếu tủ sách chỉ tất cả thế thôi thì không đủ, ta nên biết thư viện đó cung cấp gì cho bên phía ngoài có thể áp dụng được. Có thể là biến toàn cục, hoàn toàn có thể là hàm.
Các hàm và biến hóa này phải đặt đâu đó trong những file header . Rồi lúc build với source cơ mà ta viết, trình biên dịch sẽ biết phương pháp compile hoặc liên kết cho ưa thích hợp. Tệp tin header thường được cung cấp kèm theo các file .a(.so). Còn nếu như không có, thì phải có tài năng liệu tế bào tả. Bao gồm cả tài liệu với file header là vấn đề lý tưởng nhất.
Giả định rằng, ta bao gồm thư viện chưa cách xử lý hiển thị 3 loài chào En, Ja, Vi. Cơ mà ta chỉ gồm file header trình bày prototype của những hàm nhưng mà không thấy được source của nó.
3.1 Build thư viện tĩnh
Kết quả của đoạn này sẽ là file thư viện greetings_en_ja_vi.a cùng 3 file header đi kèm. Kế tiếp ta rất có thể xóa 3 tệp tin source(.c) đi được. Về cấu tạo file, vì chưng thư viện không cất hàm main() được, ta đề nghị bỏ file mainapp.c đi. Lưu giữ nhé, thư viện thì chỉ cần file header thôi là dùng được rồi. Thư viện chủng loại mực sẽ không còn cần mang đến xem code, ta chỉ cần xem biểu thị API hoặc tệp tin header là hoàn toàn có thể dùng được rồi. Kết cấu file mới sẽ như thế này:
manhongit.dhp
gmail.com:~/Code/CMake$ tree -L 2 . ├── CMakeLists.txt ├── include │ ├── greetings_en.h │ ├── greetings_ja.h │ └── greetings_vi.h └── src ├── greetings_en.c ├── greetings_ja.c └── greetings_vi.c Giờ, ta phải sửa lại file CMakeList.txt, nó đang thành như sau: CMakeList.txt
Chạy tiếp cmake với make trong thư mục build: Ta đã được hiệu quả như sau: Chạy Cmake, công dụng gần như không thay đổi so cùng với trước:
manhongit.dhp
gmail.com:~/Code/CMake/build$ cmake .. -- The C compiler identification is GNU 4.8.2 -- The CXX compiler identification is GNU 4.8.2 -- kiểm tra for working C compiler: /usr/bin/cc -- kiểm tra for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- check for working CXX compiler: /usr/bin/c++ -- kiểm tra for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/oedev/Code/CMake/buil Chạy make:
manhongit.dhp
gmail.com:~/Code/CMake/build$ make Scanning dependencies of target greetings_enjavi < 33%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_vi.c.o < 66%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_ja.c.o <100%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_en.c.o Linking C static library libgreetings_enjavi.a <100%> Built target greetings_enjavi Ta thấy rằng thương hiệu thư viện hiện ra là libgreetings_enjavi.a, như vậy tiền tố lib được sản xuất tên thư viện ta đang khai báo cùng với add_library trong file CMakeList.txt. Ta có thể kiểm tra xem thư viện này chứa mẫu gì, bằng câu lệnh ar
manhongit.dhp
gmail.com:~/Code/CMake/build$ ar -t libgreetings_enjavi.a greetings_vi.c.o greetings_ja.c.o greetings_en.c.o Ta đang thấy không tồn tại file chạy làm sao được có mặt trong thư mục build. Đúng như ước ao muốn, ta nên build thư viện. Ta cũng kiểm tra size file này:
manhongit.dhp
gmail.com:~/Code/CMake/build$ ls -lh libgreetings_enjavi.a -rw-rw-r-- 1 oedev oedev *4.9K* 8月 17 23:13 libgreetings_enjavi.a Đó là 4.9K (dung lượng NET), dính trên đĩa chắc bắt buộc hơn.
3.2 Build tủ sách động
Ta đang build tủ sách tĩnh, được file .a (một file nén không 3 file .o). Kích thước 4.9K(NET) giờ ra build thư viện động. Vậy động với tĩnh khác nhau ở chỗ nào, lý do phải build cả động làm cho gì. Chuyện hơi dài, tôi sẽ trình diễn ngắn gọn. Tủ sách tĩnh, có nghĩa là tất cả xử lý của các hàm đều nằm trong thư viện đó rồi. Ví dụ, nó gọi hàm printf vào source .c, thì khi tạo nên thư viện tĩnh, nó ôm cục bộ xử lý của printf vào trong tệp tin .a mà lại ta vừa tạo. Còn thư viện động, thì không có tác dụng thế, nó lưu lại tin tức báo là, chỗ này call hàm printf với các tham số x,y,z gì đó. Khi nào chạy thì hỏi tiếp xem hàm kia ở đâu, cách xử trí thế nào rồi new truyền các tham số để xử lý.
Cấu trúc các file source, header không thay đổi gì so với lúc build tủ sách tĩnh. Ta cần biến hóa file CMakeList.txt một chút: Nó sẽ có nội dung như thế này:
# # Điều kiện phiên phiên bản nhỏ tốt nhất của CMake # cmake_minimum_required(VERSION 2.8.12) # # tên project # project (multilang_greetings) # # Thêm folder chứa những file header (.h) # include_directories(include) # # thêm 1 tập các file source # file(GLOB SOURCES "src/*.c") # # Thư viện bao hàm những source nào. # một số loại thư viện là SHARED(động, thực chất không sát nghĩa mang đến lắm) # tên thư viện rất có thể khác thương hiệu *project* # add_library(greetings_enjavi SHARED $SOURCES) hiệu quả của lúc chạy CMake là không biến đổi gì, còn khi chạy make, nó sẽ như vậy này:
manhongit.dhp
gmail.com:~/Code/CMake/build$ make Scanning dependencies of target greetings_enjavi < 33%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_vi.c.o < 66%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_ja.c.o <100%> Building C object CMakeFiles/greetings_enjavi.dir/src/greetings_en.c.o Linking C shared library libgreetings_enjavi.so <100%> Built target greetings_enjavi thư viện được sinh ra là libgreetings_enjavi.so, cũng ban đầu với chi phí tố lib, nhưng phần không ngừng mở rộng là .so. Với tủ sách động, ta sẽ bình chọn nội dung như sau:
manhongit.dhp
gmail.com:~/Code/CMake/build$ ldd libgreetings_enjavi.so linux-vdso.so.1 => (0x00007fff3e7fc000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6cf04e7000) /lib64/ld-linux-x86-64.so.2 (0x00007f6cf0acd000) thực tế mình cũng không hiểu biết nhiều kĩ mấy cái này, rất tốt không giải thích gì. ;))
3.3 Thêm ngôn từ Es
Giờ ta đã gồm trong tay khôn xiết thư viện với 2 phiên bản, tĩnh với động. Ta đang viết code sử dụng chúng, đồng thời thêm chức năng lời chào bằng tiếng Spain nữa.
Với tủ sách tĩnh gần như là rất tương đương thư viện động, chỉ không giống tên tệp tin thư viện thôi. Ta chỉ việc thay libgreetings_enjavi.so trong file CMakeList.txt tại đoạn dưới bởi libgreetings_enjavi.a, ta sẽ build ở đoạn trên thôi.Với tủ sách động kết cấu thư mục đang như sau:manhongit.dhp
gmail.com:~/Code/CMake$ tree -L 2 . ├── build ├── CMakeLists.txt ├── include │ ├── greetings_en.h │ ├── greetings_es.h │ ├── greetings_ja.h │ └── greetings_vi.h ├── lib │ └── libgreetings_enjavi.so └── src ├── greetings_es.c └── mainapp.c Ta cũng cần sửa lại file CMakeList.txt nữa Nó đã thành như thế này: CMakeList.txt
# # ràng buộc về version # cmake_minimum_required(VERSION 2.8.12) # # thương hiệu project # project (multilang_greetings) # # Khai báo địa điểm chưa tủ sách (.so) # phối (PROJECT_LINK_LIBS libgreetings_enjavi.so) link_directories(lib) # # nơi chưa các file header(.h) # include_directories(include) # # Thêm source .c bằng lệnh phối # #set(SOURCES src/greetings_es.c) # # Thêm source .c bởi file GLOB # file(GLOB SOURCES "src/*.c") # # file chạy sẽ được tạo như thế nào # sử dụng thư viện đang khai báo qua PROJECT_LINK_LIBS # add_executable(helloworld $SOURCES) target_link_libraries(helloworld $PROJECT_LINK_LIBS) Sau đó, ta cũng chạy CMake và Make để tạo ra file chạy: kết quả của bài toán chạy CMake hầu như vẫn vậy. Còn tác dụng của Make sẽ như vậy này:
manhongit.dhp
gmail.com:~/Code/CMake/build$ make Scanning dependencies of target helloworld < 50%> Building C object CMakeFiles/helloworld.dir/src/mainapp.c.o <100%> Building C object CMakeFiles/helloworld.dir/src/greetings_es.c.o Linking C executable helloworld <100%> Built target helloworld tệp tin chạy là helloworld công dụng chạy của file này sẽ như vậy này:
manhongit.dhp
gmail.com:~/Code/CMake/build$ ./helloworld Hello world Konichiwa!!! Xin chao !!!! Hola!!! Trên đây chỉ mô tả biện pháp dùng CMake với một ví đơn giản dễ dàng trên Linux( tôi dung Ubuntu). Do nội dung bài viết đã thừa dài, tôi không thể hiện cách áp dụng trên Window (cho Visual Studio) của CMake. Về cơ bản, họ sẽ tất cả một công tác CMake (có GUI) để trợ giúp bài toán export một source đựng file CMakeList.txt ra một thư mục cất project Visual Studio. Có mấy điểm để ý ở đây;
Thứ tự tiến hành sẽ là:
Xem thêm: Bảng Ngọc Olaf Mùa 9 Top - Bảng Ngọc Olaf Mùa 12 Và Cách Lên Đồ Mạnh Nhất
Chú ý ở đây là dù ta bao gồm export ra project rồi nhưng mà source mà lại project kia chưa phần nhiều ở dạng tham chiếu đến các file source chứa trong folder chọn bằng