CMake和Make之間的區別

本文翻譯的是一篇英文文檔,主要講述的是CMake和Make之間的區別。下文中首先列出文章的中文翻譯,然後緊接着的是英文原文。

下面是中文翻譯部分:

編程人員已經使用CMake和Make很長一段時間了。當你加入一家大公司或者開始在一個具有大量代碼的工程上開展工作時,你需要注意所有的構建。你需要看到處跳轉的”CMakeLists.txt”文件。你應該會在終端使用”cmake”和”make”。很多人都是盲目的跟着操作說明而並不在意我們已何種方式去做我們需要做的事。構建的整個過程是什麼?爲什麼要用這種方式去組織?Cmake和Make之間有什麼區別?這有關係嗎?他們可以互相轉換嗎?
事實證明,它們之間有很多的不同。理解它們之間的不同很重要,這樣你可以確保在使用的過程中不會陷入麻煩。在講述它們之間的區別之前,我們首先來看看它們是什麼。


** Make **
要設計一個軟件系統,我們首先編寫源碼,然後通過編譯器編譯和創建可執行文件。可執行文件就是要實現最終功能的文件。“Make”是一個工具,它控制可執行程序和程序源文件中非源碼文件的生成。
“Make”工具需要清楚的知道如何構建程序。 它通過一個叫做“makefile”的文件知曉如何構建你的程序。這個文件列出了所有的非源碼文件以及如何由別的文件來計算它。當你編寫了一個程序,你應該爲它寫一個makefile文件,這樣纔有可能通過使用“Make”來構建和安裝你的程序。 很簡單的事情。如果你不理解的話,多讀幾遍這一段文字,因爲理解這一段文字對於接下來的篇幅很重要。


**爲什麼需要“Make” **
需要”make”的一個原因是,它可以使得終端用戶構建和安裝你的應用包,而不用去詳細的瞭解它具體是如何做到的。每一個工程都有它自己的規則和細微的差別,這會使得每次在複用的時候會變得很痛苦。這就是我們創建這個makefile文件的原因。 構建步驟精確的記錄在你提供的這個makefile文件中。“Make” 當源碼文件發生變化時自動的指出哪一個文件需要更新。 同時它也自動確定以適當的順序進行更新文件,當一個非源碼文件依賴的另一個非源碼文件發生改變時。
每次當我們改變了系統中的一小部分源碼的時候,重新編譯整個程序的效率是很低的。因此,黨我們改變了一小部分的源碼文件的時候重新執行“Make”,它將不會重新編譯整個程序。它僅僅更新那些直接或者間接依賴這些改變了的源碼文件的非源碼文件。很酷吧!“Make” 不侷限於具體的語言。對於程序中的每一個非源碼文件,makefile文件詳細的說明了執行需要的shell命令。這些shell命令能夠啓動編譯器產生目標文件,鏈接器產生可執行文件,ar更新庫,鏡像生成器格式化文檔,等等。。。Make不僅僅侷限於構建一個包。你也可以安裝或者卸載一個包,生成索引表或者其他一些你經常做的值得你寫下來怎麼去做的事情。


**CMake **
CMake支持跨平臺Make。 CMake 辨別使用那種編譯器去編譯給出的源碼種類。如果你不知道使用何種編譯器,你不能使用相同的編譯器去編譯所有不同種類的源碼。你可以手動的指用何種編譯器,但是這將變得繁瑣和痛苦。CMake爲每一種類型的目標平臺按照正確的順序調用命令。因此,將有很多非顯式的命令,比如$(CC).
如果你是代碼強迫症,請繼續往下讀。如果你不喜歡這一切,你可以跳過這一部分。一般的編譯/鏈接標識處理頭文件、庫文件、以及重定位其他平臺無關和構建系統獨立命令。調試標識被包含,通過設置變量CMAKE_BUILD_TYPE 爲“debug”,或者在調用程序的使用傳遞給CMake:cmake -DCMAKE——BUILD——TYPE:STRING=Debug。
CMake也提供平臺無關的包含,通過‘-fPIC’標誌(POSITION_INDEPENDENT_CODE屬性)。因此,更多隱式的設置能夠在CMake命令中實現,在makefile文件中也可以(通過使用COMPILE_FLAGS或者相關的屬性)。當然,CMake在集成第三方庫(像OpenGL)方面也變得更加輕便。


**它們之間有什麼不同點? **
如果你要使用編譯腳本,構建的過程中有一個步驟,也就是需要在命令行中輸入”make”。 對於CMake,需要進行2步:第一,你需要配置你的編譯環境(可以通過在你的編譯目錄中輸入cmake ,也可以通過使用GUI客戶端)。這將創建一個等效的,依賴你選擇的編譯環境的編譯腳本或其他。編譯系統可以傳遞給CMake一個參數。總之,CMake根據你的系統配置選擇合理的的默認的選擇。第二,你在你選擇的編譯系統中執行實際的構建。
你將進入GNU構建系統領域。 如果你不熟悉這個,這一段對於你來說就是碎碎唸了。現在,說完了一些嚴肅的警告,往下走把! 我們可以使用Autotool來比較CMake。當我們這樣做的時候,我們會發現Make的缺點,而且這就是Autotool產生的理由了。我們可以看到CMake明顯比Make優越的理由了。Autoconf 解決了一個重要的問題,也就是說與系統有關的構建和運行時信息的的可信賴發現。但是,這僅僅是輕便軟件的開發中的一小部分。作爲結尾,GNU工程已經開發了一系列集成的實用程序,用於完成Autoconf開始之後的工作:GNU構建系統中最重要的組件是Autoconf, Automake, and Libtool.
“Make”就不能那樣做了,至少不修改任何東西是做不到的。你可以自己做所有的跨平臺工作,但是這將花費很多時間。CMake解決了這個問題,但是與此同時,它比GNU構建系統更有優勢:

  • 用於編寫CMakeLists.txt文件的語言具有可讀性和很容易理解。
  • 不僅可以使用“Make” 來構建工程。
  • 支持多種生產工具,比如Xcode, Eclipse, Visual Studio, etc.

CMake與Make對比具有以下優點:

  • 自動發現跨平臺系統庫。
  • 自動發現和管理的工具集
  • 更容易將文件編譯進共享庫, 以一種平臺無關的方式或者以比make更容易使用的的生成方式.

CMake不僅僅只“make”,所以它變得更復雜。從長遠來看,最好能夠學會使用它。如果你僅僅在一個平臺上構建小的工程,“Make”更適合完成這部分工作。

以下爲英文原文:

**CMake vs Make **
Programmers have been using CMake and Make for a long time now. When you join a big company or start working on a project with a large codebase, there are all these builds that you need to take care of.You must have seen those “CMakeLists.txt” files floating around. You are supposed to run “cmake” and “make” commands on the terminal. A lot of people just follow the instructions blindly, not really caring about why we need to do things in a certain way. What is this whole build process and why is it structured this way? What are the differences between CMake and Make? Does it matter? Are they interchangeable? As it turns out, they are quite different. It is important to understand the differences between them to make sure you don’t get yourself in trouble. Before getting into the differences, let’s first see what they are.
**Make **
The way in which we design a software system is that we first write code, then the compiler compiles it and creates executable files. These executable files are the ones that carry out the actual task. “Make” is a tool that controls the generation of executables and other non-source files of a program from the program’s source files.
The “Make” tool needs to know how to build your program.It gets its knowledge of how to build your program from a file called the “makefile”. This makefile lists each of the non-source files and how to compute it from other files. When you write a program, you should write a makefile for it, so that it is possible to use “Make” to build and install the program.Simple stuff! If you didn’t understand it, go back and read the paragraph again because it’s important for the next part.
**Why do we need “Make”? **
The reason we need “Make” is because it enables the end user to build and install your package without knowing the details of how it’s done. Every project comes with its own rules and nuances, and it can get quite painful every time you have a new collaborator. That’s the reason we have this makefile.The details of the build process are actually recorded in the makefile that you supply. “Make” figures out automatically which files it needs to update, based on which source files have changed.It also automatically determines the proper order for updating the files, in case one non-source file depends on another non-source file.
Recompiling the entire program every time we change a small part of the system would be inefficient.Hence, if you change a few source files and then run “Make”, it doesn’t recompile the whole thing. It updates only those non-source files that depend directly or indirectly on the source files that you changed.Pretty neat!“Make” is not limited to any particular language. For each non-source file in the program, the makefile specifies the shell commands to compute it. These shell commands can run a compiler to produce an object file, the linker to produce an executable, ar to update a library, Makeinfo to format documentation, etc.“Make” is not limited to just building a package either. You can also use “Make” to control installing or uninstalling a package, generate tags tables for it, or anything else you want to do often enough to make it worth while writing down how to do it.
**CMake **
CMake stands for Cross-platform Make. CMake recognizes which compilers to use for a given kind of source.In case you didn’t know, you can’t use the same compiler to build all the different kinds of sources. You can do this manually every time you want to build your project, but it would be tedious and painful. CMake invokes the right sequence of commands for each type of target. Therefore, there is no explicit specification of commands like $(CC).
For coding junkies who really want the gory details, read on. If you are not into all that, you can skip to the next section. All the usual compiler/linker flags dealing with the inclusion of header files, libraries, etc are replaced by platform independent and build system independent commands.Debugging flags are included by either setting the variable CMAKE_BUILD_TYPE to “Debug”, or by passing it to CMake when invoking the program:cmake -DCMAKE_BUILD_TYPE:STRING=Debug.
CMake also offers the platform independent inclusion of the ‘-fPIC’ flag (via the POSITION_INDEPENDENT_CODE property) and many others. Still, more obscure settings can be implemented by hand in CMake just as well as in a Makefile (by using COMPILE_FLAGS and similar properties). Of course CMake really starts to shine when third party libraries (like OpenGL) are included in a portable manner.
**What is the difference? **
The build process has one step if you use a Makefile, namely typing “make” at the command line.For CMake, there are two steps: First, you need to setup your build environment (either by typing cmake in your build directory or by running some GUI client).This creates a makefile or something equivalent, depending on the build system of your choice (e.g. Make on *nix, VC++ or MinGW on Windows, etc). The build system can be passed to CMake as a parameter. However, CMake makes reasonable default choices depending on your system configuration. Second, you perform the actual build in the selected build system.
We are going to jump into the GNU build system territory here.If you are not familiar with that, this paragraph might look like jibber-jabber to you. Alright, now that I have given the statutory warning, let’s move on!We can compare CMake with Autotools. When we do that, we can see the shortcomings of Make, and they form the reason for the creation of Autotools. We can also see the obvious advantages of CMake over Make. Autoconf solves an important problem i.e. reliable discovery of system-specific build and runtime information. But this is only a small part in the development of portable software. To this end, the GNU project has developed a suite of integrated utilities to finish the job Autoconf started: the GNU build system, whose most important components are Autoconf, Automake, and Libtool.
“Make” can’t do that, at least not without modifying it anyway!You can make it do all that stuff but it would take a lot of time maintaining it across platforms. CMake solves the same problem, but at the same time, it has a few advantages over the GNU Build System:

  • The language used to write CMakeLists.txt files is readable and easier to understand.
  • It doesn’t only rely on “Make” to build the project.
  • It supports multiple generators like Xcode, Eclipse, Visual Studio, etc.

When comparing CMake with Make, there are several advantages of using Cmake:

  • Cross platform discovery of system libraries.
  • Easier to compile your files into a shared library in a platform agnostic way, and in general easier to use than make.
  • Automatic discovery and configuration of the toolchain. ** CMake does more than just “make”, so it can be more complex. In the long run, it’s better to learn how to use it. If you have just a small project on only one platform, then maybe “Make” can do a better job.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章