1. 程式人生 > >CMake初步(1)

CMake初步(1)

原文地址:http://blog.csdn.net/zxgis/article/details/7069493

本章的主要目的並非介紹OpenSceneGraph的常用類和功能,而是介紹它的一個重要夥伴,抑或說,是一個被愈來愈多的開源軟體所青睞的強勁的輔助開發工具——CMake。

CMake的定義是:一個跨平臺、開源、可擴充套件的軟體編譯生成系統,如果您熟悉與之同類的QMake(開源開發庫Qt的自動工程生成工具)或者Automake(Unix系統的常見工程生成工具)的話,想必更有助於對它的深入瞭解。用一句話來描述的話,CMake的工作就是:輔助生成不同平臺上的Makefile指令碼,從而建立整個軟體工程的編譯生成規則,以及它內部以及它與其它軟體工具之間的依賴關係。

不要認為Makefile只是Unix/Linux程式設計師的專屬用品;Windows的程式開發同樣離不開Makefile的概念。事實上,那些層出不窮的強大得令人眼花繚亂的IDE環境(譬如,家喻戶曉的Visual Studio)為開發者們提供了太多的便利條件,以至於大家都漸漸學得好吃懶做起來——按個按鈕,找個選單項,或者極不情願地在命令視窗中輸入一串“start”字元……一切就可盡在掌握?抱歉,這世界上不會有那麼多的便宜事。更多的時候,您不得不用著最簡陋的文字編輯器,一行一行敲擊,一行一行地耕耘。

以上就是我們即將面臨的學習內容——已經悠悠地打著哈欠了嗎?對於那些沒有Visual Studio,沒有視窗和進度條,甚至沒有滑鼠可用的情景,一點都不願理會嗎?呃,那麼敬請期待筆者的下一篇文字。(^_^)

不然的話,歡迎進入自由教程《你所不知的OSG》的第一章。工欲善其事,必先利其器。現在就來嘗試瞭解一下——也許你還有所不知的輔助編譯工具,CMake。

1.1 CMake概述



善用兵者,役不再籍,糧不三載。

CMake也許就可以喻為這樣一位英武的大將。雖然看起來那麼麻煩,那麼深不可測,但是真正摸透它的脾氣稟性之後,卻能夠得心應手,進而統領千軍萬馬,事半而功倍。

CMake的核心是指令碼配置檔案,也就是CMakeLists.txt這個簡單的指令碼檔案,瀏覽一下OpenSceneGraph的原始碼目錄就可以發現,從根目錄開始,幾乎每一個包含了子工程原始碼的目錄(src,examples,applications等)都會同時附帶一個CMakeLists.txt。在Windows下編譯OSG時,只要輕鬆地將根目錄的CMakeLists.txt拖動到CMake-GUI的視窗中,再進行相應的選項設定,就能夠生成OSG的VisualStudio工程檔案(或者,以筆者的喜好,生成nmake可用的Makefile檔案),進而編譯得到OSG動態連結庫。比如libcef的原始碼目錄中就有:


Linux使用者所需的工作如出一轍,在根目錄下執行:

# cmake . -DCMAKE_BUILD_TYPE=Release
然後直接呼叫生成的Makefile指令碼:
# make; make install
如此而已。 但是,試圖直接使用子目錄的CMakeLists.txt卻是無效的,原因很簡單,系統找不到許多在根目錄的CMakeLists檔案中配置的引數和巨集,因而會產生錯誤提示,無法繼續執行。
CMake可以針對不同的作業系統和IDE環境生成不同的指令碼或工程檔案,例如,VisualStudio解決方案,Mac OSX的XCode檔案,Unix/Linux系統的Makefile檔案等等。

說了這麼多,不知您從中摘出了多少對自己有用的資訊呢?也許您還在被那些惱人的問題折磨著吧——我怎麼生成不了FreeType外掛呢?OSG怎麼找不到我的第三方庫呢?那麼多的配置選項都是什麼意思呢?本文無力解答這麼多的問題,也許其中一些會在後繼的文字中得到解答,也許其中一些筆者和其他研究者們也未曾探究過,也許其中一些只有您自己鑽研得出答案……也許,也許您也曾一閃念想過,如果我的工程也使用CMake來配置,然後一個命令就整整齊齊地輸出連結庫和可執行檔案來,讓其他撓著頭皮的同事們乍舌不已——那該有多麼瀟灑呢?

那麼,這才是本文的編寫目的所在:就是設法幫助您,初步初步學會使用CMake編寫自己的工程配置指令碼,初步學會理解和閱讀他人的CMake配置指令碼程式碼,並因而能夠獨力閱讀和理解OpenSceneGraph那繁多的配置選項,並在不算浩瀚的CMake指令碼程式碼中(總比OSG的原始碼要簡單許多)找尋它們的芳蹤。

1.2 CMake指令碼基本知識

不知讀者朋友們學習一門新的程式語言時,第一想要了解的是它的哪一方面內容?語法?關鍵字?應用範圍?函式介面?這些當然都很重要,不過本文卻要首先詳解CMake指令碼語言的組織結構,這將有助於您對這個陌生工具的全面理解,並且在面對版本更替和新的功能實現時,不會一頭霧水,而是有的放矢,忙而不亂。

CMake包含了以下幾個基本概念:
  • CMakeLists.txt

之前已經簡單地介紹過了,這是CMake指令碼程式碼和配置引數的載體,原始碼目錄中沒有它的話,一個工程就不可能使用CMake的配置程式來完成自動Makefile指令碼的生成工作。

  • 原始碼樹和二進位制樹

原始碼樹(Source Tree)和二進位制樹(Binary Tree)的含義很好理解:前者表達了一個工程的所有標頭檔案(.h,.hxx,.hh,無副檔名,等等),原始檔(.c,.cc,.cpp,.cxx,等等),CMake指令碼(CMakeLists.txt),以及它們的目錄樹結構;後者則包括平臺相關的解決方案或Makefile指令碼,目標檔案(.obj),編譯後的動態/靜態庫和可執行檔案,以及其它編譯過程中生成的檔案等。

CMake允許“原始碼樹內生成”(in-source build)和“原始碼樹外生成”(out-of-source build)這兩種工作方式。前者將會在原始碼的同一目錄下生成對應的Makefile指令碼,目標檔案以及結果;後者則是在不同的目錄下執行編譯生成的工作,原始碼樹則保持原樣,十分有利於程式碼的版本更新,搜尋管理,以及打包再發布。

對於Windows使用者,可以在CMake-GUI的“Where to build binaries”欄中輸入新的工作路徑以實現out-of-source的模式;Linux使用者則可以簡單地在外部目錄執行cmake指令,例如:

# cmake /home/myproject –DCMAKE_BUILD_TYPE=Release
這裡的/home/myproject即是工程的根目錄,其中必須包含有CMakeLists.txt檔案。

對於發展和功能增補十分迅速的OSG而言,“原始碼樹外生成”當然是首選的編譯方案。這樣的話,當我們不滿於動輒上G的臨時檔案容量之時,只需要隨手刪除其所在目錄即可,不會影響到OSG原始碼分毫。

  • CMakeModules模組

一個工程需要依賴於另一個工程的標頭檔案和庫檔案(.lib),無論對商業還是開源軟體的開發流程來說,這都是不可或缺的一部分:GUI開發庫Qt的部分功能依賴於libJPEG、libPNG;商業GIS引擎Skyline依賴於GDAL;就連微軟的一些大型遊戲都會依賴於開源工程OpenAL。

那麼,如何告訴我們的工程,這些標頭檔案和LIB檔案的位置呢?熟悉Visual Studio環境的朋友當然知道,在工程屬性的“C/C++”和“連結器”選項卡中,可以分別設定它們的路徑;而Linux程式設計時,則需要在指令碼中手動新增-I以及-L、-l引數,保證#include巨集不致無所適從,以及編譯器不會產生該死的LNK2001,LNK2019錯誤。

而對於使用CMake生成自動指令碼的開發者來說,尋找標頭檔案和庫檔案的工作,就交給CMakeModules中的各個模組來完成。

在OSG的根目錄下有一個不太引人注意的子目錄資料夾,就是這個CMakeModules。其中的檔案內容十分豐富,名稱則一目瞭然:FindFreeType.cmake,FindGDAL.cmake,諸如此類。倘若使用者機的設定得當,這些副檔名為.cmake的搜尋指令碼可以自動獲取依賴庫的路徑資訊(但是並不會主動將它們追加到工程屬性中);不然的話,我們在配置OSG時屢屢需要設定的FREETYPE_INCLUDE_DIR,GDAL_LIBRARY等選項,也是出自這些指令碼的手筆。

具體的搜尋指令碼閱讀和編寫方法稍後再說。感興趣的朋友不妨現在就用文字編輯工具開啟一瞧,沒準它們也並不像您想象的那樣複雜也說不定。

  • CMake基本巨集

細心的您想必已經發現了,前文我們在描述Linux下的CMake命令列時,有一個未作介紹的巨集引數:-DCMAKE_BUILD_TYPE=Release。它可以被簡單地分割為三個部分,-D是命令字首詞,CMAKE_BUILD_TYPE是巨集命令的關鍵字,而Release則是對其賦值。這個內建巨集標誌的含義應當說不言而喻,它設定了工程即將採用的編譯型別,可使用的值通常包括Debug、Release、RelWithDebInfo和MinSizeRel四種。和我們在Visual Studio等工具中所作的設定相似,這將改變工程的除錯等級和編譯生成的資訊等諸多內容。

除了CMAKE_BUILD_TYPE之外,CMake中還包含一些基本的內建巨集指令,典型的例如:

CMAKE_MODULE_PATH,設定搜尋CMakeModules模組(.cmake)的額外路徑。

CMAKE_INCLUDE_PATH,設定自動查詢依賴工程標頭檔案的額外路徑,預設為指令碼中指定的搜尋路徑。

CMAKE_LIBRARY_PATH,設定自動查詢依賴工程庫檔案的額外路徑,預設為指令碼中指定的搜尋路徑。

CMAKE_INSTALL_PREFIX,設定安裝時的路徑。這是一個重要的配置引數,當連結庫和可執行檔案的生成工作完畢時,往往需要將這些.lib,.dll,.exe和標頭檔案拷貝到一個獨立的資料夾下,以備呼叫和再次複製。在Visual Studio環境下我們通過INSTALL工程來完成這一安裝工作;而Unix/Linux下則是熟悉的make install。預設的安裝目錄為/usr/local/或者C:/Program Files/。

  • CMake快取資訊

當我們使用CMake生成了工程的解決方案或者Makefile指令碼之後,再進入二進位制樹目錄,也就是編譯過程檔案儲存的位置(in-source模式為原始碼同一目錄,out-of-source模式為使用者自行指定的資料夾),可以看到新生成的CMakeCache.txt檔案,即快取資訊檔案。

CMakeCache.txt中儲存了所有自動搜尋或者手動配置的路徑和指令碼引數。當我們更新了工程的原始碼,並準備重新進行編譯時;使用這種快取資訊檔案可以有效地加速CMake配置的過程,方法是直接將這個檔案拖動到CMake-GUI視窗中,或者在命令列方式下執行:
# cmake –C CMakeCache.txt
此時系統將自動讀入上一次配置的所有資訊,使用CMake-GUI的使用者可以在對話方塊中再次進行引數的修改,並生成新的解決方案或者Makefile檔案,以供下一步的工程編譯生成工作。

1.3 你好,世界

CMake是一種可擴充套件的指令碼語言,要學會閱讀和編寫CMake指令碼程式碼,就必須要理解它的基本詞法和語法,以及理解它的介面擴充法則。而這一切的學習又都是建立在實踐的基礎上的,否則再好的教程課本和參考文件都只是廢紙一張。

那麼,是先羅列枯燥的關鍵字好呢?還是先開啟任意的文字編輯器,小試牛刀一把好呢?筆者竊以為後者是通往CMake入門者殿堂的更快途徑。

那麼就讓我們在不瞭解任何CMake指令碼規範條目的前提下,開始CMake工程涉及的旅程吧。是不是有點瘋狂呢?沒關係,我們就用開發者最喜歡的“你好,世界”(Hello World)作為第一個實踐的專案。編碼過程中所涉及的各種詞法和語法規則,我們僅僅稍作解釋,只求給讀者留下CMake指令碼開發的初步印象,以便在閱讀下一小節時能夠更加得心應手。

現在我們假設有這樣一個工程,它包括一個名為HelloLib的動態連結庫,以及一個依賴於這個庫的Test可執行程式。其資料夾結構為:

HelloLib子工程定義並實現了一個名為Hello的類,這個類只有一個公有方法sayHello(),作用是在螢幕上列印“Hello CMake”這一行簡單的字元。為此,這個目錄下將包含標頭檔案Hello以及原始檔Hello.cpp,並期望能夠生成HelloLib.dll的動態連結庫,以便所有依賴於HelloLib的程式可以因此打印出友好的歡迎語句。(儘管這看起來很幼稚 ^_^)

Test子工程只有一個原始檔test.cpp,它的工作僅僅是在main函式中呼叫sayHello()方法並即刻結束自己的使命。Test因而要依賴於HelloLib庫存在,並期望生成一個名為Test.exe的可執行檔案,在控制檯視窗中執行自己的簡單任務。

這三個檔案的原始碼如下:

    /* Hello */
    #ifndef H_HELLOWORLD
    #define H_HELLOWORLD
    #if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
    #    ifdef HELLOWORLD_LIBRARY
    #        define HELLOWORLD_EXPORT __declspec(dllexport)
    #    else
    #        define HELLOWORLD_EXPORT __declspec(dllimport)
    #    endif
    #else
    #    define HELLOWORLD_EXPORT
    #endif
    class HELLOWORLD_EXPORT Hello
    {
    public:
        void sayHello();
    };
    #endif
 
    /* Hello.cpp */
    #include <iostream>
    #include "Hello"
    void Hello::sayHello()
    {
        std::cout << "Hello CMake!" << std::endl;
    }
    /* test.cpp */
    #include <Hello>
    int main( int argc, char** argv )
    {
        Hello obj;
        obj.sayHello();
        return 0;
    }

現在我們給每一個資料夾中都追加一個CMakeLists.txt檔案(因此共有3個),從而形成完整的CMake自動編譯指令碼樹。這其中,工程根目錄下的CMakeLists.txt決定了工程的基本屬性,並使用ADD_SUBDIRECTORY,我們暫且稱之為“命令”(Command),指向每一個工程子目錄;而子目錄下的CMakeLists.txt則決定了當前工程的屬性,依賴關係,原始碼檔案以及編譯規則等等。

根目錄下的CMake指令碼實現程式碼如下:
    PROJECT( HelloWorld )
    CMAKE_MINIMUM_REQUIRED( VERSION 2.4.7 )
    ADD_SUBDIRECTORY( HelloLib )
    ADD_SUBDIRECTORY( Test )
不要急於看下面的內容,先看看這段CMake指令碼程式碼——也許您會發現它們其實很容易讀懂對不對?首先指定整個工程的名稱為HelloWorld,然後指定“所需的最低CMake版本”為2.4.7,並且新增兩個子目錄HelloLib和Test——這僅僅是我們根據英文關鍵字翻譯過來的內容,但也恰恰是這段指令碼想要表達的意思。這裡面的關鍵是ADD_SUBDIRECTORY命令,它指示系統到下一級子目錄去搜索CMakeLists.txt指令碼的位置,並執行具體子工程的生成任務。

子工程HelloLib的任務是:生成動態連結庫HelloLib.dll(或者libHelloLib.so,Unix/Linux系統中),定義一個Hello類並指示動態連結庫將其輸出,以便依賴於HelloLib庫的程式可以宣告其例項並呼叫它的功能。

它的指令碼實現程式碼如下:
    ADD_DEFINITIONS( -DHELLOWORLD_LIBRARY )
    ADD_LIBRARY( HelloLib SHARED
        Hello.cpp
    )
這裡出現了另一個重要的命令:ADD_DEFINITIONS,用於定義程式中所需的預編譯巨集,其固有引數格式通常是-D加上巨集的名稱。例如此處定義了一個HELLOWORLD_LIBRARY巨集,進而在程式中設定了Hello類的輸出方式。(Win32下往往使用dllexport來指定函式和類的輸出,其它系統則通常不必特殊指示)當然使用#define來進行定義也是相同的作用,但是能夠在編譯指令碼中有選擇地完成此類工作的話,自然會給工程帶來更大的靈活性和平臺相容能力。

第二個重要的命令是ADD_LIBRARY,很明顯,它的任務是指示CMake系統新增一個新的連結庫(Library)子工程,其引數格式為:
( 庫名稱 庫型別 原始檔 )
庫名稱為HelloLib,這也是最終生成的連結庫的名稱;型別為SHARED,即動態連結庫(.dll或.so),而STATIC自然就表示生成靜態連結庫了(.lib或.a);庫所需的原始碼檔案只有一個,即Hello.cpp,其中所包含的標頭檔案Hello因為和.cpp檔案處於同一目錄下,因此不必再特地指定。

不要在意這裡ADD_LIBRARY書寫的縮排格式,甚至不必在意其大小寫,它只是一種排版和增加易讀性的方式而已,並無強制要求。

就這麼簡單,一個新的連結庫工程就建立完成了。如果使用CMake自動生成Visual Studio解決方案的話,應該可以看到這個子工程的身影了。什麼?您的做法是選擇Visual Studio選單的“檔案->新建->工程”,並且認為這樣更加簡單?目前也許如此,不過為何不晚些再下定論呢?

那麼,按照我們之前的約定,現在要建立一個名為Test的可執行工程(.exe),並通過它來呼叫Hello::sayHello()方法,列印字串“Hello CMake!”。

使用Visual Studio應該如何來操作呢?在同一個解決方案中再次選擇“檔案->新建->工程”;選擇建立一個Win32控制檯工程,將test.cpp拖動到原始檔目錄;下一步,在“工程屬性->C/C++”中指定“附加標頭檔案目錄”為Hello所在的目錄;在“工程屬性->連結器”中指定“附加庫檔案”為HelloLib.dll;然後指定HelloLib和Test兩者的依賴關係,編譯生成,一切完畢——嗯,有些麻煩對不對?也許此時您會稍作期盼,CMake的做法能否像剛剛建立連結庫那樣簡單呢?您說對了,就是那樣簡單:
    INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/HelloLib )
    ADD_EXECUTABLE( Test
        test.cpp
    )
    TARGET_LINK_LIBRARIES( Test HelloLib )
這裡涉及到一個“變數”的概念,即${PROJECT_SOURCE_DIR}。對於精通C/C++程式設計的您來說,這類情形其實再熟悉不過,例如:
    std::string str1 = “abc”;
    std::string str2 = str1 + “def”;
    std::string str3 = “str1 + def”;
您一定知道,這裡str2的賦值為“abcdef”,而str3則是令人匪夷所思的“str1+def”。變數str1的職責和作用範圍也因此不言而喻。

CMake中的變數也是如此:我們可以使用SET命令來設定和傳遞各種使用者變數,也可以直接使用系統內建的全域性變數,例如此處的PROJECT_SOURCE_DIR。注意所有對於變數值的使用都需要遵循“${……}”的格式,否則它會被識別為普通的字串,就像str3中儲存的結果那樣;但是對於CMake而言,就算是被引號包含,也同樣可以使用“${……}”來指定使用變數中的內容,例如:
    SET( MY_SYSTEM “CMake building system” )
    MESSAGE( “${MY_SYSTEM} is good for developers.” )
將顯示“CMake building system is good for developers.”這一句完整的對白,而非毫無意義的MY_SYSTEM符號。當然,聰明的您也不需要筆者過多解釋此處MESSAGE命令的意思——它想必是用來顯示除錯或警告資訊的,通過控制檯視窗或者對話方塊。

注意,CMake的變數是可以“自省”的。如果我們現在有一個名為MY_NAME的變數賦值為“WANG”,那麼${MY_NAME}_LIB變數也就等同於WANG_LIB變數,在指令碼中對於${${MY_NAME}_LIB}的使用也就等同於對${WANG_LIB}的使用。

還有一點需要注意,CMake中的變數型別只有•字串•這一種!但是它卻可以被不同的指令碼命令靈活地識別為字串、布林型、整型或浮點型,這樣也省卻了型別轉換的種種麻煩。

這樣繁瑣的講解是否有助於您的學習理解呢,抑或是囉嗦得使您覺得厭煩了?那麼我們回到指令碼程式碼中來。明白了PROJECT_SOURCE_DIR的含義,您自然也能猜到這個變數中的內容是什麼,也就是整個工程的根目錄了。它由系統自動檢測和賦值,不需要我們操心;而這個變數對於各個子工程之間的依賴關係設定,以及標頭檔案和原始檔路徑設定顯然有著至關重要的作用!這一點不言自明。

在Test子工程的CMake指令碼中,我們首先使用INCLUDE_DIRECTORIES命令設定附加標頭檔案目錄的位置;然後用ADD_EXECUTABLE指定要編譯的可執行程式名稱和相關原始檔;最後使用TARGET_LINK_LIBRARIES設定Test所依賴的連結庫檔案,即剛剛設定生成的HelloLib庫。

一切就是如此。那麼,啟動您的CMake-GUI視窗或命令列,生成您鍾愛的工程或者Makefile,並且編譯執行。結果精緻而簡單,過程也不復雜,收穫不多也不少——這樣的感覺,不是很愜意嗎?

相關推薦

CMake初步1

原文地址:http://blog.csdn.net/zxgis/article/details/7069493本章的主要目的並非介紹OpenSceneGraph的常用類和功能,而是介紹它的一個重要夥伴,抑或說,是一個被愈來愈多的開源軟體所青睞的強勁的輔助開發工具——CMak

ajax初步1

request get lin tel sogo 調用 oca head sta 搭建服務器環境,創建一個文件夾,本篇搭建為wamp環境,在www目錄下,創建ajax文件夾。 ajax概念: AJAX 指異步JavaScript及XML(Asynchronous JavaS

線段樹初步1

建立 命令 ase img rom div roman 字符串 當我 蒟蒻終於要開始好好學線段樹了…… 線段樹是一種二叉樹形結構(二叉搜索樹),屬於平衡樹的一種。它將線段區間組織成樹形的結構,並用每個節點來表示一條線段[a,b]。每個節點的左右兒子線段分別是該線段的左半[a

斜率優化實現初步1 [BZOJ][1010][HNOI2008]玩具裝箱toy

name spa \n get pre 斜率 pri ace mes #include<bits/stdc++.h> using namespace std; #define int long long const int MAXN=5e4+233

執行緒初步1—— 執行緒的建立、引數和返回值、結束、狀態、取消

1執行緒(thread)的概念和特點   網路一般都需要實現程式碼的並行。程式碼的並行必須藉助多程序/多執行緒。   主流作業系統中都是支援多程序,而在每個程序的內部,都支援多執行緒並行。   程序,重量級的,擁有自己獨立的記憶體空間。   執行緒,輕量

CMake初步2

1.4 詞法和語法 在開始本節的學習之前,我們先總結一下之前所瞭解到的CMake基本詞法和命令。 CMake命令通常使用如下的格式: COMMAND( ARG1 ARG2 … ) 複製程式碼 命令關鍵字之後使用括號來包含所有的引數;各個引數之間使用空格或者換行符分隔;

CMAKE總結1 .lib .dll .a .so libx.dll libx.dll.a

開發十年,就只剩下這套架構體系了! >>>   

Cmake新手使用日記1【C++11下的初體驗】

pen 如何 其他 err ++ targe 使用 可執行文件 使用教程   第一次使用Cmake,搜索了很多使用教程,包括《Cmake實踐》、《Cmake手冊》等,但是在針對最新的C++11條件下編程還是會存在一點點問題,需要實驗很多次錯誤並搜索大量文章才能解決問題。這裏

Django初步實現第一個項目1

127.0.0.1 mil img span 9.png settings info ima div 1.安裝Django最新版 pip install django==2.1.1 2.查看Django版本 3.創建第一個Django項目 4.創建一個app模塊

SQL Server On Linux4——Linux 初步配置1

接上文:SQL Server On Linux(3)——SQL Server 2019 For Linux 下載並部署示例資料庫 本文聊一下Linux,因為這個系列是Linux上的SQL Server,所以我們有必要初步瞭解一下這個基石,地基不穩那麼上面搭建的東西也必然搖搖晃

Android Studio JNI (影象變灰過程使用cmake 1

Android Studio JNI (影象變灰過程)使用cmake (1) 1.開始建立第一個AS 工程; 2.選擇完畢後下一步 3.再下一步後直接點選完成,然後我們開始執行一下,即可看到Hello from JNI 4.下面我們看下CMakeLists.txt檔案 CMak

Novaproject version:2017-5 版原始碼初步閱讀1

一、關於Manager 1.功能用法: 看一下作者怎麼說:Managers are responsible for a certain aspect of the system. It is a logical grouping of code relatin

bind9的初步使用1

本文首發於我的部落格:bind9的初步使用(1) 前言 週五把自己的電腦重灌了一下,還是使用的經典的windows+vmware+ubuntu的經典方式(對我來說)。但是我不想每次都修改host檔案來實現我的域名訪問,所以我在想有沒有一個更好的方式,可以讓我實現域名對映。這個時候我想到了自己架設

STL 小白學習1 初步認識

1 #include <iostream> 2 using namespace std; 3 #include <vector> //動態陣列 4 #include <algorithm>//演算法 5 6 void PrintVector(in

【代碼筆記】Java文件的輸入輸出1——Java.io包的初步理解

對象 eclips 是什麽 reader optional 傳輸 gre 用戶界面 cep Java裏面文件的輸入輸出全部在java.io包裏面。 Java.io包裏面所有的類都需要掌握。 java.io包裏面所有的東西都在上面了。 包裏面的相關類

基於IMX6Q的u-boot-2017.11的移植1->初步移植

1.下載u-boot 2.tar -xjvf u-boot-2017.11.tar.bz2 3.cd cd u-boot-2017.11/ 4.進入到配置資料夾cd configs/ 5.ls mx6q* mx6qarm2_defconfig mx6qarm2_l

開始寫博客,學習Linq1

設計 查詢 lin 數據源 任務 集成 部分 程序 編程   摘自《linq實戰》原文:   軟件很簡單。它可以歸結為兩件事情:代碼和數據。   開發軟件卻並非那麽簡單,其中很重要的一項任務就是編寫處理數據的代碼。   無論選擇了哪種語言,在程序開發得某個時候你將不得不開始

GuozhongCrawler系列教程 1 三大PageDownloader

特點 string null 瀏覽器兼容 ror down odi 系列 lan GuozhongCrawler QQ群 202568714 教程源代碼下載地址:http://pan.baidu.com/s/1pJBmerL GuozhongCrawl

正則表達式1

表達式 正則表達式是計算機科學中的一個重要概念。正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。在很多文本編輯器中,正則表達式通常被用來檢索、替換符合某個模式的文本。許多程序設計語言都支持利用正則表達式進行字符串操作。(grep、sed、awk) 為什麽要學習正則表達式?

Angular 4 - The Basics 筆記1: Install

install rst logs nod first log 筆記 npm app Install Node.js Install Angular CLI sudo npm install -g @angular/cli Set-up new app