ただ、ネット上には日本語の情報がちょっと少ないので(英語の情報は結構あるけど)いくつかメモしときます。
ちなみに、最初はまず
http://www.cmake.org/Wiki/CMake_FAQ
のFAQに一通り目を通すことをお勧めします。
また、使用したCMakeはversion 2.8.10.1です(Ubuntu 13.04 64bit)。
Makefileでいう += ってどう記述するの
例えばMakefileで
SRCS += hoge.cというのは、
set (SRCS ${SRCS} hoge.c)というように、変数の後に追加したい値を書けばよい。
コンパイルフラグにセミコロン(';')が入ってビルドが止まるんだけど
FAQの
http://www.cmake.org/Wiki/CMake_FAQ#Why_do_I_have_unwanted_semicolons_.3B_in_my_compiler_flags.3F
がそのまんま。CMakeは、内部ではリストをセミコロン区切りの文字列として管理しているので、それをコンパイラに渡すとセミコロンが残ってしまうらしい。
そういう場合は、" " で囲うことでセミコロン区切りをスペース区切りに変換してくれる。
特に、先ほどの例のように
CFLAGS += -gとMakefileで書いていたのを
# NG set (CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-g")とうっかり書くと、セミコロンが入ってしまい死ぬ。
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")とすればOK。
ターゲット名をlibhogeにしてライブラリをビルドすると、liblibhoge.soができる
まあ、ターゲット名をlibhogeでなくhogeにしろ、ということなんでしょうけど…。
FAQの
http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_rename_a_library_after_it_has_already_been_built.3F
にヒントがある。ビルド後にファイルのコピーをするのではなく、set_target_property() を使ってOUTPUT_NAMEプロパティを変更する方が良いそうだ。
ただ、先頭の "lib" だけを削除するのはもっと簡単で、PREFIXプロパティをいじって消せばOK。
set (TARGET_NAME libhoge) add_library (${TARGET_NAME} SHARED hoge.c hoge2.c) set_target_properties (${TARGET_NAME} PROPERTIES PREFIX "")
ビルド時に、公開ヘッダファイルを一箇所にコピーしたい
例えばこのような感じの(ほげほげした)プロジェクトがあって、
. ├── lib │ ├── libhoge │ │ ├── include │ │ │ ├── hoge.h │ │ │ └── hoge_common.h │ │ ├── src │ │ │ ├── src1.c │ │ │ ├── src2.c │ │ │ └── internal.h │ │ └── CMakeLists.txt │ └── libfuga │ ├── fuga.c │ ├── fuga.h │ └── CMakeLists.txt ├── src │ └── main.c └── CMakeLists.txt
ビルドを実行する前に、export_headers というディレクトリを作って
- libhoge/hoge.h
- libhoge/hoge_common.h
- libfuga/fuga.h
をコピーして格納したい、というようなケース。
http://stackoverflow.com/questions/15972898/cmake-how-to-run-a-add-custom-command-before-everything-else
を読むと、add_custom_target() を使ってコマンドを定義し、さらに add_dependencies() で依存関係を作っておけば、
ビルド前に何かを実行させることができる、ということらしい。
つまり、例えばlib/libhoge/CMakeLists.txtの中に
add_library (libhoge SHARED src/src1.c src/src2.c) add_custom_target (copy_header_hoge_h COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/include/hoge.h ${CMAKE_BINARY_DIR}/export_headers/libhoge/hoge.h) add_dependencies(libhoge copy_header_hoge_h)と書いておけば、libhogeをビルドする前にinclude/hoge.hをコピーできる。
……まあ、ヘッダファイルそれぞれに対してこれらをいちいち書くのは非常に面倒なので、
マクロにしてしまいましょう。
set (TARGET_NAME libhoge) set (SRCS src/src1.c src/src2.c ) set (C_INCLUDES include src ) # コピーするヘッダファイルの一覧 set (EXPORT_HEADER_FILES include/hoge.h include/hoge_common.h ) # export_headers内のサブディレクトリ名 set (EXPORT_HEADER_DIR libhoge) include_directories (${C_INCLUDES}) add_library (${TARGET_NAME} SHARED ${SRCS}) set_target_properties (${TARGET_NAME} PROPERTIES PREFIX "") # マクロなので、引数にリストを渡す時は " " で囲うことに注意 copy_headers (${TARGET_NAME} ${EXPORT_HEADER_DIR} "${EXPORT_HEADER_FILES}")
set (TARGET_NAME libfuga) set (SRCS fuga.c ) # コピーするヘッダファイルの一覧 set (EXPORT_HEADER_FILES fuga.h ) # export_headers内のサブディレクトリ名 set (EXPORT_HEADER_DIR libfuga) add_library (${TARGET_NAME} SHARED ${SRCS}) set_target_properties (${TARGET_NAME} PROPERTIES PREFIX "") copy_headers (${TARGET_NAME} ${EXPORT_HEADER_DIR} "${EXPORT_HEADER_FILES}")
# ---------- 共通の設定 # バージョンはてきとう cmake_minimum_required (VERSION 2.6.0) project (piyo-project) set (CMAKE_BUILD_TYPE Debug) set (CMAKE_C_FLAGS "-Wall -Werror") set (GLOBAL_HEADER_DIR ${CMAKE_BINARY_DIR}/export_headers) # ---------- マクロ定義 # ヘッダをコピーするマクロ macro (copy_headers MODULE_NAME OUT_DIR_PREFIX FILE_LIST) foreach (HEADER_FILE ${FILE_LIST}) # ファイル名を取得 get_filename_component (FNAME ${HEADER_FILE} NAME) # ファイル名の一部を使って、ターゲット名を生成 get_filename_component (TEMP_TARGET ${HEADER_FILE} NAME_WE) set (TEMP_TARGET copy_header_${OUT_DIR_PREFIX}_${TEMP_TARGET}) # コピーするコマンド add_custom_target ( ${TEMP_TARGET} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILE} ${GLOBAL_HEADER_DIR}/${OUT_DIR_PREFIX}/${FNAME} ) # 依存関係を指定(ライブラリのビルドの前にコピーが実行されるようになる) add_dependencies (${MODULE_NAME} ${TEMP_TARGET}) endforeach (HEADER_FILE ${FILE_LIST}) endmacro (copy_headers MODULE_NAME OUT_DIR_PREFIX FILE_LIST) # ---------- サブディレクトリを登録 set (SUB_DIRS lib/libhoge lib/libfuga ) foreach (DIR ${SUB_DIRS}) add_subdirectory (${DIR}) endforeach (DIR ${SUB_DIRS}) # ---------- メインの実行ファイル set (TARGET_EXE_NAME piyoproj) set (SRCS src/main.c ) set (SHARED_LIBS libhoge libfuga ) include_directories (${GLOBAL_HEADER_DIR}) add_executable (${TARGET_EXE_NAME} ${SRCS}) target_link_libraries (${TARGET_EXE_NAME} ${SHARED_LIBS})
実行結果。
$ mkdir build $ cd build $ cmake .. -- The C compiler identification is GNU 4.7.3 -- The CXX compiler identification is GNU 4.7.3 -- Check 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/amano/cmake_sample/build $ make Scanning dependencies of target copy_header_libfuga_fuga [ 0%] Built target copy_header_libfuga_fuga Scanning dependencies of target libfuga [ 25%] Building C object lib/libfuga/CMakeFiles/libfuga.dir/fuga.c.o Linking C shared library libfuga.so [ 25%] Built target libfuga Scanning dependencies of target copy_header_libhoge_hoge_common [ 25%] Built target copy_header_libhoge_hoge_common Scanning dependencies of target copy_header_libhoge_hoge [ 25%] Built target copy_header_libhoge_hoge Scanning dependencies of target libhoge [ 50%] Building C object lib/libhoge/CMakeFiles/libhoge.dir/src/src1.c.o [ 75%] Building C object lib/libhoge/CMakeFiles/libhoge.dir/src/src2.c.o Linking C shared library libhoge.so [ 75%] Built target libhoge Scanning dependencies of target piyoproj [100%] Building C object CMakeFiles/piyoproj.dir/src/main.c.o Linking C executable piyoproj [100%] Built target piyoproj $ ls -R export_headers/ export_headers/: libfuga libhoge export_headers/libfuga: fuga.h export_headers/libhoge: hoge.h hoge_common.h
# いつの間にか年が明けてブログ開設から1年が過ぎていることについてはスルー。
0 コメント