天天看點

bin檔案對比_xmake vs cmake對比分析

首先,不得不承認,cmake很強大,發展了這麼多年,整個生态已經相當完善,功能也相當豐富,這點xmake目前是比不了的。

當初我做xmake的目的,也并不是為了完全替代cmake,這沒啥意義,隻是覺得cmake的文法和易用性滿足不了我,我還是更喜歡更簡單直覺的方式去描述和維護項目,在不同平台下提供近乎一緻的使用體驗。

是以,xmake的文法描述和使用體驗還是非常好的,這也是xmake最大的亮點之一,我在這塊設計上做了很多改進,為了降低學習和項目維護門檻,也更容易快速上手。

在這裡,我隻拿xmake中一些比較占優的特性去跟cmake作對比,僅僅隻是為了突出說明xmake在某些方面的優勢和易用性,并沒有任何貶低cmake的意思。

如果大家看完此篇文章的對比分析,覺得xmake确實好用,能夠滿足部分項目維護上的需求,解決一些痛點,提高項目維護效率的話,不妨試試體驗下。

  • 項目源碼
  • 官方文檔
  • xmake v2.2.6 釋出, Qt/Android編譯支援

特性支援

我先羅列下建構工具的一些主要基礎特性對比,大部分特性兩者都是支援的,而xmake的優勢主要還是在:文法、包倉庫管理、建構體驗上

bin檔案對比_xmake vs cmake對比分析

文法對比

空工程

xmake

target("test")
    set_kind("binary")
    add_files("src/main.c")
           

cmake

add_executable(test "")
target_sources(test PRIVATE src/main.c)
           

源檔案添加

xmake

xmake支援通配符比對的方式,添加一批源檔案進來,

*.c

比對目前目錄下所有檔案,

**.c

比對遞歸目錄下所有檔案。

這種方式,對于平常項目中新增一些檔案編譯,就不需要每次修改xmake.lua了,自動同步,可以節省不少時間。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_files("test/*.c", "example/**.cpp")
           

xmake的

add_files()

是非常靈活強大的,不僅可以支援各種不同類型源檔案添加,還可以在添加的同時排除一些指定檔案。

比如:遞歸添加src下的所有c檔案,但是不包括src/impl/下的所有c檔案。

add_files("src/**.c|impl/*.c")
           

更多關于這個接口的使用說明,見相關文檔:add_files接口文檔

cmake

cmake似乎需要先周遊檔案清單到對應變量,再添加到對應的target中去才行,稍微繁瑣些。

add_executable(test "")
file(GLOB SRC_FILES "src/*.c")
file(GLOB TEST_FILES "test/*.c")
file(GLOB_RECURSE EXAMPLE_FILES "example/*.cpp")
target_sources(test PRIVATE 
    ${SRC_FILES}
    ${TEST_FILES}
    ${EXAMPLE_FILES}
)
           

條件編譯

xmake

target("test")
    set_kind("binary")
    add_files("src/main.c")
    if is_plat("macosx", "linux") then
        add_defines("TEST1", "TEST2")
    end
    if is_plat("windows") and is_mode("release") then
        add_cxflags("-Ox", "-fp:fast")
    end
           

cmake

add_executable(test "")
if (APPLE OR LINUX)
    target_compile_definitions(test PRIVATE TEST1 TEST2)
endif()
if (WIN32)
    target_compile_options(test PRIVATE $<$<CONFIG:Release>:-Ox -fp:fast>)
endif()
target_sources(test PRIVATE
    src/main.c
)
           

自定義腳本

xmake

xmake可以在編譯建構的不同階段(包括編譯、安裝、打包、運作),友善的插入一段自定義腳本來處理自己的邏輯,比如編譯完成之後列印一行輸出:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    after_build(function (target)
        print("target file: %s", target:targetfile())
    end)
           

或者自定義運作和安裝邏輯:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_install(function (target)
        os.cp(target:targetfile(), "/usr/local/bin")
    end)
    on_run(function (target)
        os.run("%s --help", target:targetfile())
    end)
           

在自定義腳本中,使用者可以寫各種複雜腳本,通過import接口,可以導入各種擴充子產品來使用。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    before_build(function (target)
        import("net.http")
        import("devel.git")
        http.download("https://xmake.io", "/tmp/index.html")
        git.clone("[email protected]:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"})
    end)
           

cmake

cmake也可以通過

add_custom_command

來實作:

add_executable(test "")
target_sources(test PRIVATE src/main.c)
add_custom_command(TARGET test POST_BUILD
    COMMENT "hello cmake!"
)
           

不過看了下,不同階段,自定義腳本的方式并不完全一樣,

add_custom_command

隻能用于建構階段的自定義,如果要對安裝階段進行自定義,得:

install(SCRIPT cmake_install.cmake)
           

并且隻能整個替換安裝邏輯,無法對安裝前後的實作一些自定義邏輯,另外像打包、運作等其他階段的自定義似乎不支援。

建構方式

編譯預設平台

xmake

通常情況,編譯預設平台執行敲xmake,執行建構期間,xmake不會依賴其他第三方建構工具,連make也不依賴,也不會生成IDE/Makefile檔案, 而是直接調用的編譯工具鍊進行編譯,預設會根據cpu核數自動開啟多任務加速建構。

xmake
           

cmake

而cmake的通常是先生成對應IDE/Makefile等第三方建構檔案,然後調用make/msbuild等第三方建構工具去編譯。

cmake .
cmake --build .
           

編譯指定平台

xmake

xmake可以以近乎一緻的方式快速切換不同平台和架構來編譯。

xmake f -p [iphoneos|android|linux|windows|mingw] -a [arm64|armv7|i386|x86_64]
xmake
           

cmake

cmake似乎對不同平台和架構的編譯配置方式,差異性還是有些的,需要花點時間研究下才行。

cmake -G Xcode -DIOS_ARCH="arm64" .
cmake --build .
cmake -G "Visual Studio 9 2008" -A x64
cmake --build .
           

像android平台編譯,配置ndk的方式似乎也很繁瑣。

cmake .. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%buildcmakeandroid.toolchain.cmake -DCMAKE_SYSTEM_NAME="Android" -DANDROID_NDK=%ANDROID_NDK% -DANDROID_TOOLCHAIN=clang -DANDROID_PLATFORM=android-24
           

安裝目标

xmake

xmake install 
           

cmake

cmake -P cmake_install.cmake
           

運作目标

xmake

大部分情況下,xmake不需要寫自定義腳本就可以直接加載運作編譯生成的目标程式。

xmake run 
           

cmake

cmake我沒找到可以快速運作指定目标程式的方式,但是應該可以通過寫一個自定義腳本去加載運作它。

cmake -P cmake_run.cmake
           

依賴支援

查找依賴庫

xmake

xmake也是支援跟cmake的

find_package

類似的接口去直接查找系統庫,然後內建使用,找到庫後,會自動追加includedirs, links, linkdirs等相關設定。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_load(function (target)
        target:add(find_packages("openssl", "zlib"))
    end)
           

cmake

add_executable(test main.c)

find_package(OpenSSL REQUIRED)
if (OpenSSL_FOUND)
    target_include_directories(test ${OpenSSL_INCLUDE_DIRS})
    target_link_libraries(test ${OpenSSL_LIBRARIES})
endif() 

find_package(Zlib REQUIRED)
if (Zlib_FOUND)
    target_include_directories(test ${Zlib_INCLUDE_DIRS})
    target_link_libraries(test ${Zlib_LIBRARIES})
endif()
           

使用第三方庫(Conan)

xmake

xmake會自動調用conan工具去下載下傳安裝openssl庫,然後內建使用,隻需要執行xmake指令即可完成編譯。

add_requires("conan::OpenSSL/[email protected]/stable", {alias = "openssl"}) 
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("openssl")
           

cmake

if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
   message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
   file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.14/conan.cmake"
                 "${CMAKE_BINARY_DIR}/conan.cmake")
endif()

include(${CMAKE_BINARY_DIR}/conan.cmake)

conan_cmake_run(REQUIRES OpenSSL/[email protected]/stable
                BASIC_SETUP 
                BUILD missing)

add_executable(test main.c)
target_link_libraries(main ${CONAN_LIBS})
           

使用内建包倉庫

xmake

xmake有自建的包倉庫,雖然現在裡面包還不是很多,但後期會不斷完善:xmake-repo

我們隻需要添加相關需要的包就行了,非常友善,并且支援多版本選擇和語義版本控制哦。

甚至有些常用包支援多平台內建使用,例如:zlib庫等,即使編譯android/iphoneos/mingw等平台,也都可以直接下載下傳安裝使用。

add_requires("libuv master", "ffmpeg", "zlib 1.20.*")
add_requires("tbox >1.6.1", {optional = true, debug = true})
target("test")
    set_kind("shared")
    add_files("src/*.c")
    add_packages("libuv", "ffmpeg", "tbox", "zlib")
           

執行xmake指令後,會去自動從倉庫中下載下傳對應的包然後編譯安裝,內建連結進來,效果如下:

bin檔案對比_xmake vs cmake對比分析

除了官方的包倉庫,使用者也可以自己建立多個私有倉庫,用來內建使用一些私有包,這對于公司内部項目的依賴維護還是很有幫助的。

我們隻需要在xmake.lua加上自己的私有倉庫位址就行了:

add_repositories("my-repo [email protected]:myrepo/xmake-repo.git")
           

或者直接指令行添加:

xmake repo --add my-repo [email protected]:myrepo/xmake-repo.git
           

關于這塊的詳細說明可以看下相關文檔:

  • 遠端依賴模式
  • add_requires接口說明

最後,附帶一張xmake的依賴包管理架構圖:

bin檔案對比_xmake vs cmake對比分析

cmake

這塊我沒看到cmake有支援,不過cmake我用得并不多,如果有寫的不對的地方,大家可以指正。

原文出處:https://tboox.org/cn/2019/05/29/xmake-vs-cmake/