最近的工作是基於premake做一個適合我們公司的C++的編譯系統,了解一下已經比較成熟的CMake,是非常有參考價值的。
【CMake初印象】
CMake和premake一樣,都是meta build system,可以針對不同的平台產生相應的編譯系統,比如Windows上的VS Projects, Linux下的Makefile。但CMake要比premake更加成熟,這點可以從其支持的feature,使用的項目,以及完善的文檔、社區支持可以看出來,premake簡直就是一個小娃娃。
所以,讓我來評價,CMake之於premake,最大的優勢在於功能強大且久經考驗,除了基本的靜態庫、動態庫、可執行文件的創建,不同編譯系統文件的產生,還支持code generation, rpath handing等等,如此所列, 另外,CMake項目已經超出一個build system的范疇了,提供了測試的CTest,打包的CPack,以及管理report,CI的CDash,儼然成了一個完整的SDLC系統。如果要很快上馬一個項目,選CMake無疑是最舒心的,而選premake可能就需要一些波折了:你要么等那位作者(不錯,主要就一位)加feature,要么看是不是可以弄個workaround出來(premake用lua語言,所以擴這還是很靈活的)。
而premake之於CMake,優勢在於優良的基因, 不錯,premake采用了業界口碑最好,代碼簡單優美的lua語言:靈活、優美、知識復用 - 而CMake采用的則是一個自定義的格式,劣勢十分明顯。當然,這不能怪CMake,它當年出生的時候,還沒有lua這么好的一個選擇,當時最好的嵌入式語言是tcl,而如果采用tcl的話,罵都被人罵死了。
所以,premake雖然后來,但前途還是不可限量的。
【一些不錯的鏈接】
【編譯lua】
lua的基本情況在《用premake編譯lua》中已經說明,主要是三個binary,源代碼在同一個src目錄下,其CMakeLists.txt如下:
cmake_minimum_required (VERSION 2.6)
project (lua) # project here actually means solution in premake
if(WIN32)
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
endif()
# 1. lua static library
# how to rename library name?
add_library (lualib STATIC lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c)
set_target_properties(lualib PROPERTIES OUTPUT_NAME "lua") # rename the library output name
# 2. lua interpreter
link_directories (${LUA_BINARY_DIR})
add_executable (lua lua.c)
target_link_libraries (lua lualib)
if(UNIX)
target_link_libraries( lua m )
endif()
# 3. lua compiler
link_directories (${LUA_BINARY_DIR})
add_executable (luac luac.c)
target_link_libraries (luac lualib)
if(UNIX)
target_link_libraries( luac m )
endif()
編譯的時候,最好采用out-of-source模式,將文件產生到另外一個目錄下:
cd .. mkdir build cd build cmake -G "Visual Studio 9 2008" ../src
文件是產生到當前目錄的, 然后:
msbuild lua.sln
即可。
注意,這里對不同的系統設置,可以用:
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") add_definitions( -D_CRT_SECURE_NO_WARNINGS ) endif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
或者,一種簡化的方式:
if(WIN32) add_definitions( -D_CRT_SECURE_NO_WARNINGS ) endif()
而針對不同的target,則可以用set_target_properties, 這個可以用來設置編譯、鏈接的屬性,也可以改變產生的library的名字,如:
set_target_properties(lualib PROPERTIES OUTPUT_NAME "lua") # rename the library output name
因為lua的library的target名字是:liblua, 而lua的executable的target名字是lua,但我們又不同把兩個project的名字都設為lua,於是把lua library稱為lualib,但同時把其target設為最終的lua即可。