2016年4月29日 星期五

最簡單的 CMake 使用說明 – how to use cmake

http://mqjing.blogspot.hk/2009/09/cmake-how-to-use-cmake.html
最簡單的 CMake 使用說明 – how to use cmake


2009年9月15日 星期二


[程式設計] 最簡單的 CMake 使用說明 – how to use cmake

http://mqjing.blogspot.hk/2009/09/cmake-how-to-use-cmake.html
我們常常改別人已經寫好的 open source 專案, 讓我有一種感覺 … 似乎大的系統都會有一套 building system, 先解析平台上的 toolchain, 使得系統可以容易安裝到其他平台上.
在 Unix 世界裡面, 最常見的就是 GNU Building System. 也就是你常見的先下 .configure -參數 指令, 然後會產生一堆 Makefile. 使用 building system 有另外一個好處, 那就是我們的 source code 就不會被某個編譯環境鎖住了 (ex: Visual Studio .Net).

今天要介紹的是 CMake!
CMake 指令, 可以讓我們的使用者更容易把程式建構於不同的平台. 重要的是, 它可以讓我選擇要產生 Makefile 或 Visual Studio .Net 的專案檔 (sln 專案檔).
本文的主要結構為:
        1. 最簡單的 CMakeLists.txt 範例
        2. 如何在 Cygwin 下, 自動產生 Makefile
        3. 如何在 Windows 下, 自動產生 Visual Studio .Net 專案檔 (sln)
        4. FAQ
               -  設定/使用變數範例: set       
               -  建立/使用 macro 範例: MACRO
               -  存取環境變數的範例: $ENV{PATH}
               -  加入 Post Build 的範例: add_custom_command
               -  秀 Message 的範例: Message
               -  若你的執行檔是 Windows 程式, 請加入 Win32
               -  MFC 設定
               -  設定 source code 群組範例: set_group
               -  目前 binary 目錄 與 source 目錄:
                              CMAKE_CURRENT_SOURCE_DIR
                              CMAKE_CURRENT_BINARY_DIR
             
   -  建立 dll 範例
                - console 與 windows (/SUBSYSTEM:CONSOLE or /SUBSYSTEM:WINDOWS)
       5.  好用的變數 (more)

我想達成的目的, 如下所示:
cmake_structure

先把範例端上來

-------------------- fun.cpp --------------------
int add(int a,int b){
    return a+b;
}

// fun.h
int add(int a,int b);

-------------------- main.cpp --------------------
#include "fun.h"
#include <stdio.h>
int main(){
    int ans=add(1,2);
    printf("ans=%d",ans);
    return 0;
}

我想要做的事情是
1. 建立一個 library 檔稱為 MyLibrary, 裡面包含 fun.cpp
2. 自動建立 makefile, 把 main.cpp 與 MyLibrary 連接並且編譯.
用 cmake 該怎麼作?

Step 1: 寫一個 CMakeLists.txt, 描述該怎麼編譯你的 source
ex:
-------------------- CMakeLists.txt -----------------
project(MyProject)
add_library(MyLibrary fun.cpp)  # 建立程式庫 MyLibrary
add_executable(MyProgram main.cpp) # 建立執行檔 MyProgram

# 產生執行檔 MyProgram 與 程式庫 MyLibrary 連結指令
target_link_libraries(MyProgram MyLibrary)
-------------------- end of CMakeLists.txt -----------------

Step 2: 把它與你的 source files 放在一起
ex:
cmake_CMakeLists
Step 3: Enjoy

選擇你要產生的專案

自動產生 Makefile 的作法


Step 1: 在要放置 binary 的位置, 直接下指令 cmake [source code 目錄位置]
ex: 我在 ~/cmake_demo/bin 這個空目錄中, 下 cmake ../source 指令
cmake
 Step 2: 來看看結果如何? (cmake 會把 Makefile 放在 bin/ 中)
01_Makefile

 Step 3: 在 bin/ 下 make 指令, 看到底會不會動
02_in_process

嗯! 確實可以執行! ^_^
02_result

----------------------------------------------------------------------------------------

產生 Microsoft Visual Studio 專案的作法


Step 1: 選擇編譯結果目錄, 我們希望
    a.  指定 source code 的位置在: cmake_demo/source
    b. 編譯後的結果放在: cmake_demo/bin
    這樣作就不會把 source code 目錄弄髒了.
04_Windows_Configure

Step 2: 選擇產生 Visual Studio 8 2005 專案檔
05_win_Choose_Target_and_Specify_Native_compilers

Step 3: 設定編譯器所在位置
    ex: C:\Program Files\Microsoft Visual Studio 8\VC\bin
06_win_Choose_VisualStudio_cl

Step 4: 選擇 [Generate] 開始產生 Visual Studio 專案
07_win_reConfigure_and_runGenerate
07_win_run_testing

08_win_solution_result

FAQ
Unicode 設定的問題
如果你的字元處理是 Unicode, 那麼可以在 CMakeLists.txt 裡面加入
# 設定 Unicode
add_definitions(-DUNICODE -D_UNICODE)
如下圖所示
unicode

你會在產生出來的 project 設定中, 看見
unicode_prj 
# 設定變數範例           set(MYLIBPATH "C:\\Documents and
                  Settings\\Jing\\Desktop\\opencv_bin\\lib\\release\\")
# 使用變數範例           target_link_libraries(${name} ${MYLIBPATH}cv200.lib)

# 建立 macro 範例
           MACRO(MY_DEFINE_EXAMPLE name srcs)
                 add_executable(${name} ${srcs})
           ENDMACRO(MY_DEFINE_EXAMPLE)
# 使用 macro 範例            MY_DEFINE_EXAMPLE(demo     demo.cpp)

# 存取環境變數的範例
             MESSAGE("$ENV{PATH}")
# 加入 Post Build 的範例     add_custom_command(
            TARGET ${MyPluginTarget}
            POST_BUILD
            COMMAND copy
                           ${CMAKE_CFG_INTDIR}\\${MyPluginTarget}.dll
                           "C:\\Program Files\\Mozilla Firefox\\
                             plugins\\${MyPluginTarget}.dll"
        )

# 若你的執行檔是 Windows 程式, 請加入 Win32
# ex:
        add_executable(demo WIN32 ${SOURCE})

# MFC 設定
# ex:
        set(CMAKE_MFC_FLAG 2)
        set_target_properties(MyApp      PROPERTIES   
                   COMPILE_DEFINITIONS
                                                                  _AFXDLL, _UNICODE, UNICODE,
                                                                  _BIND_TO_CURRENT_CRT_VERSION,
                                                                  _BIND_TO_CURRENT_MFC_VERSION
                    LINK_FLAGS
                                                                  " /ENTRY:\"wWinMainCRTStartup\"    ")
         記得:
                         add_executable(demo WIN32 ${SOURCE})
# 設定 source code 群組範例
ex 1:
    file(GLOB_RECURSE myRESOURCE_FILE “*.def” “*.rc”)
    source_group(Resource FILES ${myRESOURCE_FILE })
ex 2:
    source_group(abc_group REGULAR_EXPRESSION "abc.*")
    source_group(123_group REGULAR_EXPRESSION "123.*")
   
    set(SOURCE abc.cpp abc.h 123.cpp 123.h abc.rc main.cpp main.h
                              resource.h stdafx.cpp  stdafx.h
                              ./res/123.ico ./res/123.rc2)
     add_executable(demo WIN32 ${SOURCE})

# 建立 dll 範例
ex:
     add_library( target SHARED a.c b.c);

#console 與 windows (/SUBSYSTEM:CONSOLE or /SUBSYSTEM:WINDOWS)
a. 如果你的程式是 Windows.
          => 則 add_executable(demo WIN32 ${SOURCE})
b. 如果是 console, 則
          => 則 add_executable(demo ${SOURCE})


5. 好用的變數 (more)
PROJECT_SOURCE_DIR:  包含 project 命令的 CMakeFile.txt 完整路徑. (ex: c:\abc)
usage:
       set(PROJECT_HOME ${PROJECT_SOURCE_DIR}\\..\\)

Enjoy.
by Jing

沒有留言:

張貼留言

2007 to 2023 HP and Dell Servers Comparison

  HP Gen5 to Gen11  using ChatGPT HP ProLiant Gen Active Years CPU Socket Popular HP CPUs Cores Base Clock Max RAM Capacity Comparable Dell ...