CMake

CMakeのedit_cacheが使えるという話

CMake で Makefile とか生成したときにできる edit_cache ターゲットが実は便利なやつだったと 気づいた。 edit_cache すると、すでにビルドディレクトリとして CMake を走らせたディレクトリの オプションをいろいろ編集できる。 これまでは適当に CMakeCache.txt を直接編集してたけど、このツールだともっと楽で安全に編集できるっぽい。 make edit_cache とかで起動する。 するとデフォルトだと CMAKE_INSTALL_PREFIX と CMAKE_BUILD_TYPE が出るっぽい。 まあ現実的に変えたそうなやつだし妥当だと思う。 なぜか Boost を find_package のした結果設定された変数が出てるけどなんでなんでしょうね (にっこり)。 あと CMakeLists.txt の中で option(...) コマンドを使ってると、これで設定してる変数も出る。便利。 でカーソルキーとか J/K とかで項目選んで Enter 押すと編集。bool だと ON と OFF が切り替わる。 PATH とかだとそこが編集可能になるんだけどカーソル一番後ろにしといて欲しかった。

CMake on Windows (ライブラリの解決関係)

zlib とか libpng とかをビルドして、適当に C:\usr とかに配置してたら CMake が認識してくれなかった。 -DCMAKE_PREFIX_PATH で C:\usr を指定してやれば解決。 > cmake -DCMAKE_PREFIX_PATH=C:\usr .. このパスが複数ある場合 (例えばライブラリごとにインストールされているパスが違う場合) は CMake のリスト (セミコロン ; で区切る) で渡せばよい。 参考 CMAKE_PREFIX_PATH — CMake 3.20.0-rc1 Documentation

WindowsにCMakeのプロジェクトを移植する

UNIX で Makefile 生成してビルドしていたような CMake のプロジェクトを Windows に移植する。 ここでは Visual Studio について言及するとき Visual Studio 2019 を前提とする (というか試せる環境がそれしかない)が多分そこにはそんなに依存していないはず。 とりあえず言えることは,CMake で Visual Studio のプロジェクトを生成する方法は Make を使ったプロジェクトとビルドシステムの設計というか思想が違いすぎてその差異を CMakeLists.txt で吸収するのは無理だと思う(たぶん単純なプロジェクトだと大丈夫だけど凝ったことをしようとすると すぐ詰む)。書くの面倒臭いので飛ばすけど Visual Studio は CMake では Multi-config という扱いになって Makefile とはちょっと違う環境になるので。 というわけで,NMake の Makefile を生成するのが簡単な方法だと思う。 この方法だと最小限のプラットフォーム固有の(cmake の)コードでビルドが通るようにできる。

CMakeのExternalProject

これで良いのかは分からないが,まあ動くっぽいのでヨシッ! 厳密なこと言うといくらでもダメな状況ってのが出てきそう。 cmake_minimum_required(VERSION 3.15) project(ext_sample CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_STANDARD_REQUIRED ON) include(ExternalProject) ExternalProject_Add(zlib_project URL https://zlib.net/zlib-1.2.11.tar.xz CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/zlib) ExternalProject_Add(libpng_project URL https://download.sourceforge.net/libpng/libpng-1.6.37.tar.xz CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/libpng) add_library(zlib IMPORTED SHARED) set_target_properties(zlib PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/zlib/lib/libz.so) add_library(libpng IMPORTED SHARED) add_dependencies(libpng zlib) set_target_properties(libpng PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libpng/lib/libpng.so INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/zlib/include INTERFACE_LINK_LIBRARIES zlib) find_package(Threads) find_package(Boost COMPONENTS unit_test_framework) add_executable(mcmap) target_include_directories(mcmap PRIVATE ${PROJECT_SOURCE_DIR}/libpng/include ${PROJECT_SOURCE_DIR}/zlib/include) target_include_directories(mcmap PRIVATE ${CMAKE_BINARY_DIR}) target_link_libraries(mcmap PRIVATE zlib libpng ${CMAKE_THREAD_LIBS_INIT}) add_subdirectory(block) add_subdirectory(src) で試しに ldd で見てみる。 $ ldd build/mcmap linux-vdso.so.1 (0x00007fffbf7f6000) libpng16.so.16 => /tmp/foo/libpng/lib/libpng16.so.16 (0x00007f3a7ffea000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f3a7ff9c000) libz.so.1 => /tmp/foo/zlib/lib/libz.so.1 (0x00007f3a7ff7b000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f3a7fd9e000) libm.so.6 => /usr/lib/libm.so.6 (0x00007f3a7fc59000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f3a7fc3f000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f3a7fa76000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f3a8007c000) あといい感じに install を書きましょう(こんな方法が必要なのは Windows でのビルドだけのような気がするが)。 まあ実際に使うときは最初に find_package してみてダメだったらフォールバックする って感じにするかなと。 そういや最近 Windows の winget ってのが発表されましたね。