[解決済み] 最もシンプルで完全なCMakeの例
質問
どういうわけか、私は CMake がどのように動作するかについて完全に混乱しています。私はCMakeが書かれることを意味する方法を理解するために近づいていると思うたびに、それは私が読む次の例で消えます。私が知りたいのは、私のCMakeが将来的に最小限のメンテナンスを必要とするように、私は私のプロジェクトをどのように構成すべきか、ということです。たとえば、私は、私のsrcツリーに新しいフォルダを追加しているときに、私のCMakeList.txtを更新したくないのですが、それは他のすべてのsrcフォルダとまったく同じように動作します。
これは私のプロジェクトの構造を想像する方法ですが、これは単なる例であることをお願いします。推奨される方法が異なる場合は、教えてください、そしてそれを行う方法を教えてください。
myProject
src/
module1/
module1.h
module1.cpp
module2/
[...]
main.cpp
test/
test1.cpp
resources/
file.png
bin
[execute cmake ..]
ところで、私のプログラムでは、リソースがどこにあるのかを知っていることが重要です。リソースを管理するための推奨される方法を知りたいのです。私は "../resources/file.png" で自分のリソースにアクセスしたくありません。
どのように解決するのですか?
いくつかの研究の後、私は今、最もシンプルだが完全なCMakeの例の私自身のバージョンを持っています。これは、リソースとパッケージングを含む、基本的なことのほとんどをカバーしようとするものです。
1 つのことは、非標準的なリソースの処理です。デフォルトでは、CMake はそれらを /usr/share/ や /usr/local/share/ および Windows で同等のものに置きたいと考えています。私は、どこでも展開して実行できるシンプルなzip/tar.gzを持ちたかったのです。したがって、リソースは実行ファイルから相対的にロードされます。
CMakeコマンドを理解するための基本的なルールは、以下の構文です。
<function-name>(<arg1> [<arg2> ...])
コンマやセミコロンを使わないでください。各引数は文字列です。
foobar(3.0)
と
foobar("3.0")
も同じです。リスト/変数を設定するには
set(args arg1 arg2)
. この変数セットで
foobar(${args})
と
foobar(arg1 arg2)
は事実上同じです。存在しない変数は、空のリストと同じです。リストは内部的には単なる文字列で、セミコロンで要素を区切っています。したがって、要素が1つだけのリストは、定義上、その要素だけであり、箱詰めは行われません。変数はグローバルです。組み込みの関数では、何らかの形で
名前付き引数
のような ID を期待するという事実によって、ある種の名前付き引数を提供します。
PUBLIC
または
DESTINATION
を引数リストに入れて、引数をグループ化しています。しかし、これは言語の機能ではなく、これらのIDも単なる文字列であり、関数の実装によってパースされます。
からすべてをクローンすることができます。 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)
関連
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】Enterキーを押して続行する
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み] CMakeにおけるデバッグとリリースの比較
-
[解決済み] CMakeの出力をクリアするための'cmake clean'コマンドを探しています。
-
[解決済み] configure --prefix=DIR && make all install ' と同等のCMakeは何ですか?
-
[解決済み] C++によるスレッディングの簡単な例
-
[解決済み】CMakeでプリプロセッサー・マクロを定義する?
-
[解決済み] CMake:ユニットテストによるプロジェクト構造
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み】変数やフィールドがvoid宣言されている