TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2009年12月11日 星期五

CMake to QMake note

前幾天腦袋壞掉把手上的 Qt project 全換成 CMake,原因是 QMake 的功能實在是不太夠用。最糟糕的一點是建置的彈性太差,你很難在 qmake 的執行選項裡更改專案的設定,通常你要直接修改 *.pro files。然後是它的 install 和設定相依性的能力也很差,跟前述的問題一樣,都是寫死的。
CMake 做為一個建置系統(應該說前端)就還算是優秀,對於相依性的處理可以自己寫一套 script 來自動設定,找不到也可以讓使用者手動設定,雖然有些聲音認為 pkg-config 的方式較為方便,但是畢竟在 Windows(Mac 我不確定) 上這東西是不流行的,而且也不是每個專案都有附上 *.pc 設定。
以下是我從 QMake 到 CMake 轉換的對應處理:
前置動作
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
這會檢查 Qt4 的設定,然後把該有的 macro 和變數引入。
子專案設定
TEMPLATE = subdirs
SUBDIRS = dir1 dir2
轉換為
add_subdirectory(dir1)
add_subdirectory(dir2)
如果有
CONFIG += ordered
的子專案間相依設定的話,要在各子資料夾內加上設定
add_dependencies(A B)
執行檔的設定
SOURCES = a.cpp b.cpp # ... program sources
TARGET = exec
TEMPLATE = app
改為
set(SOURCES a.cpp b.cpp ... )
add_executable(exec ${SOURCES})
動態連結函式庫
TARGET = shared
TEMPLATE = lib
由於 add_library 預設是生成靜態連結函式庫,要明確指定 SHARED
add_library(shared SHARED ${SOURCES})
Qt plugin
TARGET = $$qtLibraryTarget(plugin)
TEMPLATE = lib
CONFIG += plugin
這裡要自己加上 Qt 的 flags
add_definitions(${QT_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED)
add_library(plugin SHARED ${SOURCES})
Qt 模組,預設是會打開 QtCore 和 QtGui 兩個。
QT += phonon
set(QT_USE_PHONON TRUE)
除了 QtCore 和 QtGui 分別是 QT_DONT_USE_QTCORE 和 QT_DONT_USE_QTGUI 外,其他的都是 QT_USE_XXX。如果發生找不到 header 或是連結錯誤的話,變數分別是 QT_XXX_INCLUDE_DIR 和 QT_XXX_LIBRARY。
QMake 會自動找需要 moc 的 header, 但是 CMake 在這個功能上還沒有完整支援,qt4_automoc macro 需要在原始碼最後加上 #include "header.moc"。如果你不是採用此做法,就只好手動加入需要 moc 的 header;怎麼找呢?找連結錯誤的 compile unit 就好了。
qt4_wrap_cpp(MOC_SOURCES a.h b.h)
add_executable(exe ${SOURCES} ${MOC_SOURCES})
Resource system
RESOURCES = a.qrc b.qrc
一樣要透過 wrapper
qt4_add_resources(RCC_SOURCES a.qrc b.qrc)
add_executable(exe ${SOURCES} ${RCC_SOURCES})
header 位置
INCLUDEPATH += src
include_directories(src)
連結
LIBS += -la -lb
記得也要連結 Qt 自己的 library
target_link_libraries(exe ${QT_LIBRARIES} a b)
如果什麼都沒做的話,在 MSVC 底下會出現多餘的 console prompt,需要做一點手腳
add_executable(exe WIN32 ${SOURCES})
target_link_libraries(exe ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY})
版本設定
VERSION = 1.2.3
set_target_properties(exe PROPERTIES VERSION 1.2.3)
set_target_properties(lib PROPERTIES VERSION 1.2.3 SOVERSION 1.2.3)
輸出路徑
DESTDIR = build
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/build")
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/build")
基本上是建議除非你真的很閒才轉啦 ...

2 則留言:

  1. http://www.cmake.org/Wiki/CMake:ConvertFromQmake

    從Qmake轉換到CMake的腳本

    回覆刪除
  2. 我有試過 ... 那個太粗糙了
    我的 project 轉出來的結果幾乎不能用

    回覆刪除