git clone --recursive https://github.com/m-tmatma/googletest-sample-cmake.gitor
git clone https://github.com/m-tmatma/googletest-sample-cmake.git git submodule init git submodule update
mkdir build-on cd build-on cmake -D BUILD_SHARED_LIBS=1 ..\googletest-sample-cmake\以下のように実行してプロジェクトを生成すれば Static Library になります。
mkdir build-off cd build-off cmake -D BUILD_SHARED_LIBS=0 ..\googletest-sample-cmake\
│ CMakeLists.txt │ runtime.cmake │ ├─googletest │ ├─src │ CMakeLists.txt │ calc.cpp │ calc.h │ └─tests CMakeLists.txt test.cpp test2.cpp
######################################################################################################## # see https://cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F ######################################################################################################## if (NOT BUILD_SHARED_LIBS) foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if(${flag_var} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") endif(${flag_var} MATCHES "/MD") endforeach(flag_var) endif (NOT BUILD_SHARED_LIBS)
BUILD_SHARED_LIBS が OFF のとき (static ライブラリのとき) /MT オプションを指定することで C のランタイムを static バージョンを使うようにします。
# set 3.6 to use VS_STARTUP_PROJECT cmake_minimum_required(VERSION 3.6) project (googletest-sample-cmake) option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) if (APPLE) set(CMAKE_MACOSX_RPATH 1) endif(APPLE) # switch DLL or static libary by specifying by command line set (LIB_TYPE STATIC) if (BUILD_SHARED_LIBS) # User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED' set (LIB_TYPE SHARED) endif (BUILD_SHARED_LIBS) # set Target Directories set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_subdirectory(googletest) add_subdirectory(src) add_subdirectory(tests) # set Startup Project set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "tests" ) # turn on solution folder set_property(GLOBAL PROPERTY USE_FOLDERS ON) # create solution folder set_target_properties(gmock PROPERTIES FOLDER GoogleTest) set_target_properties(gmock_main PROPERTIES FOLDER GoogleTest) set_target_properties(gtest PROPERTIES FOLDER GoogleTest) set_target_properties(gtest_main PROPERTIES FOLDER GoogleTest) set_target_properties(calc PROPERTIES FOLDER library) set_target_properties(tests PROPERTIES FOLDER executable)Mac で警告ができるので以下を指定します。
if (APPLE) set(CMAKE_MACOSX_RPATH 1) endif(APPLE)以下定義で BUILD_SHARED_LIBS が ON(1) になっていたら ${LIB_TYPE} は SHARED (Shared Library) になります。
# switch DLL or static libary by specifying by command line set (LIB_TYPE STATIC) if (BUILD_SHARED_LIBS) # User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED' set (LIB_TYPE SHARED) endif (BUILD_SHARED_LIBS)BUILD_SHARED_LIBS が OFF(0) になっていたら ${LIB_TYPE} は STATIC (Static Library) になります。
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) でライブラリ出力先フォルダを指定します。
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) で実行ファイルの出力先フォルダを指定します。
CMAKE_BINARY_DIR の変数はビルドディレクトリのトップディレクトリを表します
CMake : out-of-sourceビルドで幸せになるを参考
add_subdirectory(googletest) 等でサブディレクトリをビルド対象にしています。
# turn on solution folder set_property(GLOBAL PROPERTY USE_FOLDERS ON) # create solution folder set_target_properties(gmock PROPERTIES FOLDER GoogleTest) set_target_properties(gmock_main PROPERTIES FOLDER GoogleTest) set_target_properties(gtest PROPERTIES FOLDER GoogleTest) set_target_properties(gtest_main PROPERTIES FOLDER GoogleTest) set_target_properties(calc PROPERTIES FOLDER library) set_target_properties(tests PROPERTIES FOLDER executable)set_property(GLOBAL PROPERTY USE_FOLDERS ON) でソリューションフォルダの機能を有効にします。
cmake_minimum_required(VERSION 2.6.4) include (../runtime.cmake) # define a variable of project name set( project_name calc) # define a variable of project name project (${project_name}) # define a variable SRC with file GLOB file(GLOB SRC *.cpp *.h) # define as exports if (BUILD_SHARED_LIBS) add_definitions(-D${project_name}_EXPORTS) endif (BUILD_SHARED_LIBS) # add include directory for ${project_name}_Export.h include_directories(${PROJECT_BINARY_DIR}) # define sources files of an executable ADD_LIBRARY(${project_name} ${LIB_TYPE} ${SRC} ${PROJECT_BINARY_DIR}/${project_name}_Export.h) include (GenerateExportHeader) GENERATE_EXPORT_HEADER( ${project_name} BASE_NAME ${project_name} EXPORT_MACRO_NAME ${project_name}_EXPORT EXPORT_FILE_NAME ${project_name}_Export.h STATIC_DEFINE ${project_name}_BUILT_AS_STATIC )親ディレクトリある runtime.cmake を読み込みます。
include (../runtime.cmake)
include_directories でインクルードディレクトリを指定します
${PROJECT_BINARY_DIR} はこのプロジェクトに対応するビルドディレクトリを意味します。
add_library でライブラリを定義します。${LIB_TYPE} のところで SHARED を指定すると shared Library(Windows ではDLL)になり,
STATIC を指定するとスタティックライブラリになります。
トップディレクトリにある CMakeLists.txt でこの変数を定義します。
include (GenerateExportHeader) GENERATE_EXPORT_HEADER( ${project_name} BASE_NAME ${project_name} EXPORT_MACRO_NAME ${project_name}_EXPORT EXPORT_FILE_NAME ${project_name}_Export.h STATIC_DEFINE ${project_name}_BUILT_AS_STATIC )以下のようなヘッダファイルが出力先に生成されます。これは Windows で実行したときの内容です。Mac や Linux では内容は異なります。
#ifndef calc_EXPORT_H #define calc_EXPORT_H #ifdef calc_BUILT_AS_STATIC # define calc_EXPORT # define CALC_NO_EXPORT #else # ifndef calc_EXPORT # ifdef calc_EXPORTS /* We are building this library */ # define calc_EXPORT __declspec(dllexport) # else /* We are using this library */ # define calc_EXPORT __declspec(dllimport) # endif # endif # ifndef CALC_NO_EXPORT # define CALC_NO_EXPORT # endif #endif #ifndef CALC_DEPRECATED # define CALC_DEPRECATED __declspec(deprecated) #endif #ifndef CALC_DEPRECATED_EXPORT # define CALC_DEPRECATED_EXPORT calc_EXPORT CALC_DEPRECATED #endif #ifndef CALC_DEPRECATED_NO_EXPORT # define CALC_DEPRECATED_NO_EXPORT CALC_NO_EXPORT CALC_DEPRECATED #endif #if 0 /* DEFINE_NO_DEPRECATED */ # ifndef CALC_NO_DEPRECATED # define CALC_NO_DEPRECATED # endif #endif #endif
cmake_minimum_required(VERSION 2.6.4) include (../runtime.cmake) # define a variable of project name set( project_name tests) # define a project name project (${project_name}) # define a variable SRC with file GLOB file(GLOB SRC *.cpp *.h) # https://cmake.org/cmake/help/v3.0/variable/PROJECT-NAME_SOURCE_DIR.html # add include directories include_directories(${googletest_SOURCE_DIR}/include) include_directories(${calc_SOURCE_DIR}) # https://cmake.org/cmake/help/v3.0/variable/PROJECT-NAME_BINARY_DIR.html # add include directory for calc_Export.h include_directories(${calc_BINARY_DIR}) # define sources files of an executable add_executable(${project_name} ${SRC}) # link libraries target_link_libraries(${project_name} gtest) target_link_libraries(${project_name} gtest_main) target_link_libraries(${project_name} calc)
include_directories でインクルードディレクトリの指定をしていますが、 ${PROJECT_BINARY_DIR} を参照する場合、Program のプロジェクトに対する生成ディレクトリなので calc のプロジェクトに対するフォルダを指定する必要があるので ../src を追加しています。
変数名 | リンク | 説明 |
---|---|---|
<PROJECT-NAME>_SOURCE_DIR | <PROJECT-NAME>_SOURCE_DIR | <PROJECT-NAME> のプロジェクトのソースコードのトップディレクトリ |
<PROJECT-NAME>_BINARY_DIR | <PROJECT-NAME>_BINARY_DIR | <PROJECT-NAME> のプロジェクトのバイナリディレクトリ |
<PROJECT-NAME> は project() で指定する名前です。
例えばある CMakeLists.txt で以下のように定義しているプロジェクトを参照する場合 <PROJECT-NAME>_SOURCE_DIR は ${calc_SOURCE_DIR} のように参照します。
# define a variable of project name set( project_name calc) # define a variable of project name project (${project_name})
記述 | 説明 |
---|---|
include_directories(${googletest_SOURCE_DIR}/include) | googletest プロジェクトのソースコードのディレクトリをインクルードディレクトリに追加する |
include_directories(${calc_SOURCE_DIR}) | calc プロジェクトのソースコードのディレクトリをインクルードディレクトリに追加する |
include_directories(${calc_BINARY_DIR}) | calc プロジェクトのバイナリディレクトリをインクルードディレクトリに追加する |
target_link_libraries でリンクするライブラリを指定しています。GoogleTest の gtest と gtest_main と calc をリンクしています。