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

沒有留言:

張貼留言

2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...