sau một số nghiên cứu, bây giờ tôi đã có phiên bản của riêng mình về ví dụ cmake đơn giản nhưng đầy đủ nhất. Đây là nó, và nó cố gắng bao gồm hầu hết những điều cơ bản, bao gồm cả tài nguyên và đóng gói.
một điều nó không theo tiêu chuẩn là xử lý tài nguyên. Theo mặc định, cmake muốn đưa chúng vào / usr / share /, / usr / local / share / và một cái gì đó tương đương trên windows. Tôi muốn có một tệp zip / tar.gz đơn giản mà bạn có thể giải nén ở bất cứ đâu và chạy. Do đó, tài nguyên được tải liên quan đến tệp thực thi.
Quy tắc cơ bản để hiểu các lệnh cmake là cú pháp sau:
<function-name>(<arg1> [<arg2> ...])
không có dấu phẩy hoặc dấu chấm phẩy. Mỗi đối số là một chuỗi. foobar(3.0)
và foobar("3.0")
giống nhau. bạn có thể đặt danh sách / biến với set(args arg1 arg2)
. Với bộ biến này foobar(${args})
và foobar(arg1 arg2)
hiệu quả là như nhau. Một biến không tồn tại tương đương với một danh sách trống. Bên trong danh sách chỉ là một chuỗi có dấu chấm phẩy để phân tách các phần tử. Do đó, một danh sách chỉ có một phần tử thì theo định nghĩa chỉ là phần tử đó, không có quyền anh diễn ra. Các biến có tính toàn cục. Các hàm Builtin cung cấp một số dạng đối số được đặt tên bởi thực tế là chúng mong đợi một số id như PUBLIC
hoặcDESTINATION
trong danh sách đối số của họ, để nhóm các đối số. Nhưng đó không phải là một tính năng ngôn ngữ, những id đó cũng chỉ là các chuỗi và được phân tích cú pháp bởi việc triển khai hàm.
bạn có thể sao chép mọi thứ từ github
cmake_minimum_required(VERSION 3.0)
project(example_project)
###############################################################################
## file globbing ##############################################################
###############################################################################
# these instructions search the directory tree when cmake is
# invoked and put all files that match the pattern in the variables
# `sources` and `data`
file(GLOB_RECURSE sources src/main/*.cpp src/main/*.h)
file(GLOB_RECURSE sources_test src/test/*.cpp)
file(GLOB_RECURSE data resources/*)
# you can use set(sources src/main.cpp) etc if you don't want to
# use globing to find files automatically
###############################################################################
## target definitions #########################################################
###############################################################################
# add the data to the target, so it becomes visible in some IDE
add_executable(example ${sources} ${data})
# just for example add some compiler flags
target_compile_options(example PUBLIC -std=c++1y -Wall -Wfloat-conversion)
# this lets me include files relative to the root src dir with a <> pair
target_include_directories(example PUBLIC src/main)
# this copies all resource files in the build directory
# we need this, because we want to work with paths relative to the executable
file(COPY ${data} DESTINATION resources)
###############################################################################
## dependencies ###############################################################
###############################################################################
# this defines the variables Boost_LIBRARIES that contain all library names
# that we need to link to
find_package(Boost 1.36.0 COMPONENTS filesystem system REQUIRED)
target_link_libraries(example PUBLIC
${Boost_LIBRARIES}
# here you can add any library dependencies
)
###############################################################################
## testing ####################################################################
###############################################################################
# this is for our testing framework
# we don't add REQUIRED because it's just for testing
find_package(GTest)
if(GTEST_FOUND)
add_executable(unit_tests ${sources_test} ${sources})
# we add this define to prevent collision with the main
# this might be better solved by not adding the source with the main to the
# testing target
target_compile_definitions(unit_tests PUBLIC UNIT_TESTS)
# this allows us to use our executable as a link library
# therefore we can inherit all compiler options and library dependencies
set_target_properties(example PROPERTIES ENABLE_EXPORTS on)
target_link_libraries(unit_tests PUBLIC
${GTEST_BOTH_LIBRARIES}
example
)
target_include_directories(unit_tests PUBLIC
${GTEST_INCLUDE_DIRS} # doesn't do anything on Linux
)
endif()
###############################################################################
## packaging ##################################################################
###############################################################################
# all install commands get the same destination. this allows us to use paths
# relative to the executable.
install(TARGETS example DESTINATION example_destination)
# this is basically a repeat of the file copy instruction that copies the
# resources in the build directory, but here we tell cmake that we want it
# in the package
install(DIRECTORY resources DESTINATION example_destination)
# now comes everything we need, to create a package
# there are a lot more variables you can set, and some
# you need to set for some package types, but we want to
# be minimal here
set(CPACK_PACKAGE_NAME "MyExample")
set(CPACK_PACKAGE_VERSION "1.0.0")
# we don't want to split our program up into several things
set(CPACK_MONOLITHIC_INSTALL 1)
# This must be last
include(CPack)
For example I don't want to update my CMakeList.txt when I am adding a new folder in my src tree
bạn có thể cho một ví dụ về IDE thu thập các nguồn tự động không?