① 如何使用CMAKE生成makefile文件
CMake是一個跨平台的安裝(編譯)工具,可以用簡單的語句來描述所有平台的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project文件,能測試編譯器所支持的C++特性。只是 CMake 的組態檔取名為 CmakeLists.txt。Cmake 並不直接建構出最終的軟體,而是產生標準的建構檔(如 linux 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然後再依一般的建構方式使用。
在 linux 平台下使用 CMake 生成 Makefile 並編譯的流程如下:
編寫 CmakeLists.txt。
執行命令 「cmake PATH」 或者 「ccmake PATH」 生成 Makefile ( PATH 是 CMakeLists.txt 所在的目錄 )。
使用 make 命令進行編譯
工程實例:
一. 編寫各層CMakeLists.txt
主目錄的主程序main.cpp
#include "hello.h"
extern Hello hello;
int main()
{
hello.Print();
return 0;
}
主目錄的CMakeLists.txt
# to the root binary directory of the project as ${MAIN_BINARY_DIR}.
project (MAIN)
#version support
cmake_minimum_required(VERSION 2.8)
# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
# cause another cmake executable to run. The same process will walk through
# the project's entire directory structure.
add_subdirectory (Hello)
add_subdirectory (Demo)
# Make sure the compiler can find include files from our Hello library.
include_directories (${MAIN_SOURCE_DIR}/Hello)
# Make sure the linker can find the Hello Demo library once it is built.
link_directories (${HELLO_BINARY_DIR}/Hello)
link_directories (${HELLO_BINARY_DIR}/Demo)
#define the source coedes of current directory as DIR_SRCS
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
# Add executable called "MAIN" that is built from the source files
add_executable (Main ${DIR_SRCS})
# Link the executable to the Hello Demo library.
target_link_libraries (Main Hello Demo)
定義項目名project(MAIN),使得當前目錄可以用${MAIN_SOURCE_DIR},由於有2個子目錄,所以需要add_subdirectory它們。由於主程序會使用到其他庫,因而也需要指定連接庫所在目錄。
主目錄下的作用是利用add_executable將當前目錄下的源文件編譯成Main程序,然後通過target_link_libraries鏈接Hello和Demo庫。由於主程序文件使用了hello.h文件,所以要include_directories該目錄。
---------------------------------------------------------------------------------------------------
子目錄Demo的子程序demo.c
#include "hello.h"
Hello hello;
子目錄Demo的CMakeLists.txt
# Make sure the compiler can find include files from our Hello library.
include_directories (${MAIN_SOURCE_DIR}/Hello)
#define the source coedes of current directory as DIR_DEMO_SRCS
AUX_SOURCE_DIRECTORY(. DIR_DEMO_SRCS)
# Add library called "Demo" that is built from the source files
add_library (Demo ${DIR_DEMO_SRCS})
Demo目錄下的CMakeLists主要作用是利用add_library將當前目錄源碼編譯成Demo庫,由於該庫使用到hello.h文件,所以要include_directories該目錄。
---------------------------------------------------------------------------------------------------
子目錄Hello的子程序hello.h
#ifndef _hello_h
#define _hello_h
class Hello
{
public:
void Print();
};
#endif
子目錄Hello的子程序hello.c
#include "hello.h"
#include <stdio.h>
void Hello::Print()
{
printf("Hello, World!\n");
}
子目錄Hello的CMakeLists.txt
#define the source coedes of current directory as DIR_HELLO_SRCS
AUX_SOURCE_DIRECTORY(. DIR_HELLO_SRCS)
# Add library called "hello" that is built from the source files
add_library (Hello ${DIR_HELLO_SRCS})
Hello目錄下的CMakeLists主要作用是利用add_library將當前目錄源碼編譯成Hello庫。
---------------------------------------------------------------------------------------------------
二. 執行cmake命令
至此我們完成了項目中所有 CMakeLists.txt 文件的編寫,進入目錄 step2 中依次執行命令
#cmake .
默認當前目錄,生產makefile
#make
最後編譯程序
② 用makefile編輯的文件怎麼編譯
我們在linux下進行編程的時候,會發現我們沒有工程文件,然後,我們在不同目錄下
的文件如此雜亂無章,讓我們感到頭疼,怎麼可以把它們進行同步在一起,然後,一起進行編譯呢,
這里,就是我們需要用到的工具了,makefile文件的作用了,makefile可以有效地組織文件和目錄,
把處於不同目錄下的文件進行同時編譯,而不會因為目錄的不同,而有所差別。
這里,我來分享一下makefile的簡單的用法。
1:基本的格式:
magproc:magproc.o dbproc.o
$(EC) -o $(BINPATH)/$@ $? $(LIB)
可執行文件名:鏈接文件
編譯工具 (參數) (鏈接庫) 文件名
2:工程文件Make.defines
3:makefile文件
http://jingyan..com/article/48206aeaf9e82e216ad6b335.html
③ 如何在Windows下通過Cmake編譯和使用PCRE
CMake是一個比make更高級的編譯配置工具,它可以根據不同平台、不同的編譯器,生成相應的Makefile或者vcproj項目。
通過編寫CMakeLists.txt,可以控制生成的Makefile,從而控制編譯過程。CMake自動生成的Makefile不僅可以通過make命令構建項目生成目標文件,還支持安裝(make install)、測試安裝的程序是否能正確執行(make test,或者ctest)、生成當前平台的安裝包(make package)、生成源碼包(make package_source)、產生Dashboard顯示數據並上傳等高級功能,只要在CMakeLists.txt中簡單配置,就可以完成很多復雜的功能,包括寫測試用例。
如果有嵌套目錄,子目錄下可以有自己的CMakeLists.txt。
總之,CMake是一個非常強大的編譯自動配置工具,支持各種平台,KDE也是用它編譯的,感興趣的可以試用一下。
准備活動:
(1)安裝cmake。
下載地址:
根據自己的需要下載相應的包即可,Windows下可以下載zip壓縮的綠色版本,還可以下載源代碼。
Windows下CMake的使用
(2)運行cmake的方法。(GUI、命令行)
CMake使用步驟:
運行GUI的cmake界面:
cmake-2.8.1-win32-x86\bin\cmake-gui.exe
Windows下CMake的使用
執行Configure:
運行之後,生成了如下文件:
Windows下CMake的使用
生成Makefile:
執行Generate之後生成如下文件:
Windows下CMake的使用
運行make進行編譯:
Windows下CMake的使用
編譯完成後,在build目錄生成Tutorial.exe,運行Tutorial.exe 25就可以看到運行結果:
Windows下CMake的使用
運行make install安裝程序:
Windows下CMake的使用
運行make test進行測試:
Windows下CMake的使用
通過cmake tutorial學習CMake配置方法
可以在源代碼的Tests/Turorial目錄中找到這個手冊對應的代碼。
Windows下CMake的使用
1、Step1。
(如果不知道如何使用cmake,以及如何使用編譯產生的Turorial.exe,可先看下前面「CMake使用步驟」的說明,它以Step4為例詳細介紹了使用過程,Step1的配置可能不夠完全,比如無法運行make install,無法運行make test,但可以參考。)
簡單的程序編譯。
(1)運行GUI的cmake,指定要編譯的源代碼路徑和二進制文件路徑(會自動創建)。
Windows下CMake的使用
(2)點擊Configure,配置成功後,再點擊Generate。
配置需要選擇合適的編譯器,雖然我安裝了VC2008,但沒有配置成功;選擇Unix Makefiles,配置成功,它自動找到了DevC++下的gcc.exe等編譯器。
Windows下CMake的使用
(3)在build3目錄執行make,就能夠編譯生成Turorial.exe了。
D:\Projects\Lab\testngpp\cmake-2.8.1\Tests\Tutorial\Step1\build3>make
Linking CXX executable Tutorial.exe
[100%] Built target Tutorial
可以運行一下Turorial.exe:
D:\Projects\Lab\testngpp\cmake-2.8.1\Tests\Tutorial\Step1\build3>Tutorial.exe
Tutorial.exe Version 1.0
Usage: Tutorial.exe number
D:\Projects\Lab\testngpp\cmake-2.8.1\Tests\Tutorial\Step1\build3>Tutorial.exe 4
The square root of 4 is 2
2、Step2
把子目錄編譯為庫,並且鏈接到最終的可執行文件。
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions) # 使得子目錄MathFunctions也能被編譯
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)
產生makefile:
在GUI上點擊Configure,之後Generate還是灰色,再次點擊Configure,Generate就可以點擊了。
編譯:
④ 如何使用CMake進行交叉編譯
cmake交叉編譯配置
很多時候,我們在開發的時候是面對嵌入式平台,因此由於資源的限制需要用到相關的交叉編譯。即在你host宿主機上要生成target目標機的程序。裡面牽扯到相關頭文件的切換和編譯器的選擇以及環境變數的改變等,我今天僅僅簡單介紹下相關CMake在面對交叉編譯的時候,需要做的一些准備工作。
CMake給交叉編譯預留了一個很好的變數CMAKE_TOOLCHAIN_FILE,它定義了一個文件的路徑,這個文件即toolChain,裡面set了一系列你需要改變的變數和屬性,包括C_COMPILER,CXX_COMPILER,如果用Qt的話需要更改QT_QMAKE_EXECUTABLE以及如果用BOOST的話需要更改的BOOST_ROOT(具體查看相關Findxxx.cmake裡面指定的路徑)。CMake為了不讓用戶每次交叉編譯都要重新輸入這些命令,因此它帶來toolChain機制,簡而言之就是一個cmake腳本,內嵌了你需要改變以及需要set的所有交叉環境的設置。
toolChain腳本中設置的幾個重要變數
1.CMAKE_SYSTEM_NAME:
即你目標機target所在的操作系統名稱,比如ARM或者Linux你就需要寫"Linux",如果Windows平台你就寫"Windows",如果你的嵌入式平台沒有相關OS你即需要寫成"Generic",只有當CMAKE_SYSTEM_NAME這個變數被設置了,CMake才認為此時正在交叉編譯,它會額外設置一個變數CMAKE_CROSSCOMPILING為TRUE.
2. CMAKE_C_COMPILER:
顧名思義,即C語言編譯器,這里可以將變數設置成完整路徑或者文件名,設置成完整路徑有一個好處就是CMake會去這個路徑下去尋找編譯相關的其他工具比如linker,binutils等,如果你寫的文件名帶有arm-elf等等前綴,CMake會識別到並且去尋找相關的交叉編譯器。
3. CMAKE_CXX_COMPILER:
同上,此時代表的是C++編譯器。
4. CMAKE_FIND_ROOT_PATH:
指定了一個或者多個優先於其他搜索路徑的搜索路徑。比如你設置了/opt/arm/,所有的Find_xxx.cmake都會優先根據這個路徑下的/usr/lib,/lib等進行查找,然後才會去你自己的/usr/lib和/lib進行查找,如果你有一些庫是不被包含在/opt/arm裡面的,你也可以顯示指定多個值給CMAKE_FIND_ROOT_PATH,比如
set(CMAKE_FIND_ROOT_PATH /opt/arm /opt/inst)
該變數能夠有效地重新定位在給定位置下進行搜索的根路徑。該變數默認為空。當使用交叉編譯時,該變數十分有用:用該變數指向目標環境的根目錄,然後CMake將會在那裡查找。
5. CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:
對FIND_PROGRAM()起作用,有三種取值,NEVER,ONLY,BOTH,第一個表示不在你CMAKE_FIND_ROOT_PATH下進行查找,第二個表示只在這個路徑下查找,第三個表示先查找這個路徑,再查找全局路徑,對於這個變數來說,一般都是調用宿主機的程序,所以一般都設置成NEVER
6. CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:
對FIND_LIBRARY()起作用,表示在鏈接的時候的庫的相關選項,因此這里需要設置成ONLY來保證我們的庫是在交叉環境中找的.
7. CMAKE_FIND_ROOT_PATH_MODE_INCLUDE:
對FIND_PATH()和FIND_FILE()起作用,一般來說也是ONLY,如果你想改變,一般也是在相關的FIND命令中增加option來改變局部設置,有NO_CMAKE_FIND_ROOT_PATH,ONLY_CMAKE_FIND_ROOT_PATH,BOTH_CMAKE_FIND_ROOT_PATH
8. BOOST_ROOT:
對於需要boost庫的用戶來說,相關的boost庫路徑配置也需要設置,因此這里的路徑即ARM下的boost路徑,裡面有include和lib。
9. QT_QMAKE_EXECUTABLE:
對於Qt用戶來說,需要更改相關的qmake命令切換成嵌入式版本,因此這里需要指定成相應的qmake路徑(指定到qmake本身)
toolChain demo
# this is required
SET(CMAKE_SYSTEM_NAME Linux)
# specify the cross compiler
SET(CMAKE_C_COMPILER /opt/arm/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER /opt/arm/usr/bin/ppc_74xx-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /opt/arm/ppc_74xx /home/rickk/arm_inst)
# search for programs in the build host directories (not necessary)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# configure Boost and Qt
SET(QT_QMAKE_EXECUTABLE /opt/qt-embedded/qmake)
SET(BOOST_ROOT /opt/boost_arm)
這樣就完成了相關toolChain的編寫,之後,你可以靈活的選擇到底採用宿主機版本還是開發機版本,之間的區別僅僅是一條-DCMAKE_TOOLCHAIN_FILE=./toolChain.cmake,更爽的是,如果你有很多程序需要做轉移,但目標平台是同一個,你僅僅需要寫一份toolChain放在一個地方,就可以給所有工程使用。
⑤ 如何寫一個簡單的makefile
一:makefile 雛形:
#makefile的撰寫是基於規則的,當然這個規則也是很簡單的,就是:
#target : prerequisites
command//任意的shell 命令
實例如下:
makefile:
helloworld : main.o print.o #helloword 就是我們要生成的目標
# main.o print.o是生成此目標的先決條件
gcc -o helloworld main.o print.o#shell命令,最前面的一定是一個tab鍵
mian.o : mian.c print.h
gcc -c main.c
print.o : print.c print.h
gcc -c print.c
clean :
rm helloworld main.o print.o
OK,一個簡單的makefile製作完畢,現成我們輸入 make,自動調用Gcc編譯了,
輸入 make clean就會刪除 hellowworld mian.o print.o
二:小步改進:
在上面的例子中我們可以發現 main.o print.o 被定義了多處,
我們是不是可以向C語言中定義一個宏一樣定義它呢?當然可以:
makefile:
objects = main.o print.o #應該叫變數的聲明更合適
helloworld : $(objects) //聲明了變數以後使用就要$()了
gcc -o helloworld$(objects)
mian.o : mian.c print.h
gcc -c main.c
print.o : print.c print.h
gcc -c print.c
clean :
rm helloworld $(objects)
修改完畢,這樣使用了變數的話在很多文件的工程中就能體現出方便性了。
三:再進一步:
再看一下,為沒一個*.o文件都寫一句gcc -c main.c是不是顯得多餘了,
能不能把它幹掉?而且 main.c 和print.c都需要print.h,為每一個都寫上是
不是多餘了,能不能再改進?
能,當然能了:
makefile:
objects = main.o print.o
helloworld : $(objects)
gcc -o helloworld$(objects)
$(objects) : print.h # 都依賴print.h
mian.o : mian.c #幹掉了gcc -c main.c 讓Gun make自動推導了。
print.o : print.c
clean :
rm helloworld $(objects)
⑥ 如何使用Makefile自動編譯iPhone程序
makefile裡面所寫的內容其實就是你要編譯的命令,那麼,什麼是編譯命令呢?
假寫你已經寫好一個程序代碼,並將之存在一個.c文件中,如:hello.c,在終端上你可以這樣做!在終端上輸入gcc -o hello hello.c
然後回車,看一看有沒有什麼反映,如果沒有打出很多英文的話,恭喜你!你完美地完成了第一步!然後,在終端中輸入./hello 看看是不是有什麼輸出了?
現在來解釋一下編譯命令:上面的命令的意思就是,使用gcc編譯器編譯hello.c源代碼,生成的文件名稱叫做hello.最後,要看程序運行結果,就要運行生成的程序也就是「./hello」了,「./」的意思就是在當前的目錄下運行。
而makefile中內容的就是上面的編譯命令,如:在makefile文件中寫入
Hello:hello.c
gcc -o Hello hello.c
保存文件之後直接在終端中輸入make,就完成編譯了!makefile存在的意義只是讓編譯更加方便,也就說,可以把所以的編譯都寫在一個makefile文件中,然後在終端中輸入make就可以完成makefile文件里的命令!
建議還是先將C語言入門,然後再學使用makefile編譯程序吧!因為剛開始的時候不用編譯很多文件,如果一個文件要編寫一個makefile文件的話,那豈不是很繁?
⑦ 如何使用cmake編譯軟體項目3
1. 在主程序所在目錄的CMakeLists.txt中定義要編譯的主程序和輸出的可執行文件名:
#定義主程序名稱
add_executable(輸出的可執行文件名稱 源文件列表)
#定義鏈接庫
target_link_libraries(輸出的可執行文件名稱 鏈接庫1 鏈接庫2 ...)
2.在庫文件所在目錄中的CMakeLists.txt中告訴cmake將其所有庫文件編譯成動態庫:
#通過set命令自定義變數LIB_SRC包括那些源文件,這些文件將編譯到動態庫
set (LIB_SRC
libsrc1.cpp
libsrc2.cpp
libsrc3.cpp
)
#將上述文件編譯到庫中
add_library (庫名稱 SHARED ${LIB_SRC})
#定義庫的輸出位置, 如果在根目錄下的CMakeLists.txt中已經定義,此處可注釋掉。
set(LIBRARY_OUTPUT_PATH 具體的目錄位置)
⑧ 如何用makefile進行編譯
假設有下面幾個c++文件:wherewhen.h wherewhen.c countdown.h countdown.c 包含了math.h, 需要連接庫文件 main.c 主函數, main.c 包含了兩個頭文件 wherewhen.h and countdown.h 1、第一種編譯方法:g++ -Wall -g wherewhen.c countdown.c main.c -lm -o myprogram 生成可執行文件myprogram 2、第二中編譯方法, 分別編譯各個文件:g++ -Wall -g -c wherewhen.c g++ -Wall -g -c countdown.c g++ -Wall -g -c main.c g++ -g wherewhen.o countdown.o main.o -lm -o myprogram
⑨ 在VC里如何用Makefile文件編譯
運行cmd.exe (or command.com in win9x)->進到vc/bin目錄->運行vc-vars32.bat->進到makefile 所在的目錄->nmake /f makefile
從sourceforge上下載下來的libjpeg源代碼中有一個makefile.vc的文件,可以通過nmake /f makefile.vc [nodebug=1]來編譯libjpeg,但是只能編譯靜態庫,如果需要編譯dll以便在emacs等程序中使用的話,需要修改makefile.vc和jmorecfg.h文件。在makefile.vc文件中添加編譯dll規則:
以下內容為程序代碼:
libjpeg.lib: $(LIBOBJECTS) $(RM) libjpeg.lib lib -out:libjpeg.lib $(LIBOBJECTS) #
添加以下這行 libjpeg.dll: $(LIBOBJECTS) $(RM) libjpeg.dll link -dll -out:libjpeg.dll $(LIBOBJECTS) 在jmorecfg.h中添加#define _WIN32_#define JPEG_DLL 然後nmake /f makefile.vc nodebug=1就可以編譯了。
將makefile復制為一個.mak文件,然後用VC打開即可!
.mak 就是一個makefile
可以指定怎樣編譯(命令行,必須先設置VC命令行環境)
vcvars32.bat可設置環境,在vc98/bin下 nmake /f XXXX.mak
如果有一個makefile就只要nmake就可以了。
⑩ 如何使用makefile
以hello_test.c文件為例
1.創建程序
在linux控制台界面下 ,輸入vi hello_test.c,輸入i進入編輯插入模式,輸入代碼如下:
#include <stdio.h>
int main(void)
{
printf("Hello,Word!/n");
return 0;
}
用gcc編譯程序
輸入命令:gcc hello_test.c
輸入命令:ls
顯示:a.out hello_test.c
輸入命令:./a.out //執行程序
2.使用Makefile
(1)創建Makefile,在hello_test.c所在目錄輸入 vi Makefile
(2)輸入Makefile內容。在vi插入模式下輸入:
hello_test : hello_test.c
gcc -o hello_test hello_test.c //特別注意 gcc前面不是空格,而是tab間隔符,否則會出現makefile:2: *** 遺漏分隔符錯誤
clean :
rm -fr hello_test *.o *.core
(3)輸入make,屏幕輸出 gcc -o hello_test hello_test.c,表示編譯已經通過。
生成 hello_test。