xmake v2.2.5新特性詳解

第三方包管理器支持

新版本對內(nèi)置的包管理進(jìn)行了重構(gòu),已經(jīng)支持的非常完善了,我們可以通過

add_requires("libuv master", "ffmpeg", "zlib 1.20.*")`

方便的安裝使用依賴包,但是官方的包倉庫xmake-repo目前收錄的包還非常少,因此為了擴(kuò)充xmake的包倉庫,
xmake新增了對第三方包管理器的內(nèi)置支持,通過包命名空間顯式指定其他包管理器中的包,目前支持對conan::brew::vcpkg::包管理中的包進(jìn)行安裝。

安裝homebrew的依賴包

add_requires("brew::zlib", {alias = "zlib"}})
add_requires("brew::pcre2/libpcre2-8", {alias = "pcre2"}})

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("pcre2", "zlib")

安裝vcpkg的依賴包

add_requires("vcpkg::zlib", "vcpkg::pcre2")

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("vcpkg::zlib", "vcpkg::pcre2")

不過需要注意的是,使用vcpkg,需要先對vcpkg與xmake進(jìn)行集成才行,詳細(xì)操作如下:

windows上用戶裝完vcpkg后,執(zhí)行$ vcpkg integrate install,xmake就能自動從系統(tǒng)中檢測到vcpkg的根路徑,然后自動適配里面包。

當(dāng)然,我們也可以手動指定vcpkg的根路徑來支持:

$ xmake f --vcpkg=f:\vcpkg

安裝conan的依賴包

新版本實(shí)現(xiàn)了對conan的generator,來集成獲取conan中的包信息,我們在xmake中使用也是非常的方便,并且可以傳遞conan包的所有配置參數(shù)。

add_requires("conan::zlib/1.2.11@conan/stable", {alias = "zlib", debug = true})
add_requires("conan::OpenSSL/1.0.2n@conan/stable", {alias = "openssl", configs = {options = "OpenSSL:shared=True"}})

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("openssl", "zlib")

執(zhí)行xmake進(jìn)行編譯后:

ruki:test_package ruki$ xmake
checking for the architecture ... x86_64
checking for the Xcode directory ... /Applications/Xcode.app
checking for the SDK version of Xcode ... 10.14
note: try installing these packages (pass -y to skip confirm)?
  -> conan::zlib/1.2.11@conan/stable  (debug)
  -> conan::OpenSSL/1.0.2n@conan/stable  
please input: y (y/n)

  => installing conan::zlib/1.2.11@conan/stable .. ok
  => installing conan::OpenSSL/1.0.2n@conan/stable .. ok

[  0%]: ccache compiling.release src/main.c
[100%]: linking.release test

內(nèi)置依賴包查找支持

之前的版本提供了lib.detect.find_package來對依賴庫進(jìn)行查找,但是這需要通過import后才能使用,并且一次只能查找一個(gè)包,比較繁瑣:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_load(function (target)
        import("lib.detect.find_package")
        target:add(find_package("openssl"))
        target:add(find_package("zlib"))
    end)

而新版本中通過內(nèi)置find_packages接口,對lib.detect.find_package進(jìn)行了進(jìn)一步的封裝,來提升易用性:

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

并且還支持從指定的第三方包管理器中進(jìn)行查找:

find_packages("conan::OpenSSL/1.0.2n@conan/stable", "brew::zlib")

參數(shù)配置依賴包安裝

新版本中對內(nèi)置的包管理進(jìn)行了大規(guī)模重構(gòu)和升級,并且對參數(shù)可配置編譯安裝依賴包進(jìn)行了更好的支持,我們可以在包倉庫中定義一些編譯安裝配置參數(shù),來定制安裝包。

例如, 我們以pcre2的包為例:


package("pcre2")

    set_homepage("https://www.pcre.org/")
    set_description("A Perl Compatible Regular Expressions Library")

    set_urls("https://ftp.pcre.org/pub/pcre/pcre2-$(version).zip",
             "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-$(version).zip")

    add_versions("10.23", "6301a525a8a7e63a5fac0c2fbfa0374d3eb133e511d886771e097e427707094a")
    add_versions("10.30", "3677ce17854fffa68fce6b66442858f48f0de1f537f18439e4bd2771f8b4c7fb")
    add_versions("10.31", "b4b40695a5347a770407d492c1749e35ba3970ca03fe83eb2c35d44343a5a444")

    add_configs("shared", {description = "Enable shared library.", default = false, type = "boolean"})
    add_configs("jit", {description = "Enable jit.", default = true, type = "boolean"})
    add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8", "16", "32"}})

上面我們通過add_configs定義了三個(gè)條件配置參數(shù),使得用戶在集成使用pcre2庫的時(shí)候,可以定制化選擇是否需要啟用jit版本、bit位寬版本等,例如:

add_requires("pcre2", {configs = {jit = true, bitwidth = 8}})

而且,配置參數(shù)是強(qiáng)約束檢測的,如果傳的值不對,會提示報(bào)錯(cuò),避免傳遞無效的參數(shù)進(jìn)來,像bitwidth參數(shù)配置,被限制了只能在values = {"8", "16", "32"}里面取值。

那么,用戶如何知道我們的包當(dāng)前支持哪些配置參數(shù)呢,很簡單,我們可以通過下面的命令,快速查看pcre2包的所有信息:

$ xmake require --info pcre2

輸出結(jié)果如下:

The package info of project:
    require(pcre2): 
      -> description: A Perl Compatible Regular Expressions Library
      -> version: 10.31
      -> urls:
         -> https://ftp.pcre.org/pub/pcre/pcre2-10.31.zip
            -> b4b40695a5347a770407d492c1749e35ba3970ca03fe83eb2c35d44343a5a444
         -> ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-10.31.zip
            -> b4b40695a5347a770407d492c1749e35ba3970ca03fe83eb2c35d44343a5a444
      -> repo: local-repo /Users/ruki/projects/personal/xmake-repo/ 
      -> cachedir: /Users/ruki/.xmake/cache/packages/p/pcre2/10.31
      -> installdir: /Users/ruki/.xmake/packages/p/pcre2/10.31/23b52ca1c6c8634f5f935903c9e7ea0e
      -> fetchinfo: 10.31, system, optional
          -> linkdirs: /usr/local/Cellar/pcre2/10.32/lib
          -> defines: PCRE2_CODE_UNIT_WIDTH=8
          -> links: pcre2-8
          -> version: 10.32
          -> includedirs: /usr/local/Cellar/pcre2/10.32/include
      -> platforms: linux, macosx
      -> requires:
         -> plat: macosx
         -> arch: x86_64
         -> configs:
            -> vs_runtime: MT
            -> shared: false
            -> jit: true
            -> bitwidth: 8
            -> debug: false
      -> configs:
         -> shared: Enable shared library. (default: false)
         -> jit: Enable jit. (default: true)
         -> bitwidth: Set the code unit width. (default: 8)
            -> values: {"8","16","32"}
      -> configs (builtin):
         -> debug: Enable debug symbols. (default: false)
         -> cflags: Set the C compiler flags.
         -> cxflags: Set the C/C++ compiler flags.
         -> cxxflags: Set the C++ compiler flags.
         -> asflags: Set the assembler flags.
         -> vs_runtime: Set vs compiler runtime. (default: MT)
            -> values: {"MT","MD"}

其中,里面的configs:部分,就是目前可提供配置的參數(shù)描述以及取值范圍,而configs (builtin):中是一些xmake內(nèi)置的配置參數(shù),用戶也可直接配置使用。

例如最常用的debug模式包:

add_requires("pcre2", {configs = {debug = true}})

由于這個(gè)太過于常用,xmake提供了更方便的配置支持:

add_requires("pcre2", {debug = true})

另外requires:里面的內(nèi)容,就是當(dāng)前依賴包的配置狀態(tài),方便用戶查看當(dāng)前使用了哪個(gè)模式的包。

預(yù)處理模板配置文件

xmake提供了三個(gè)新的接口api,用于在編譯前,添加一些需要預(yù)處理的配置文件,用于替代set_config_header等老接口。

  • add_configfiles
  • set_configdir
  • set_configvar

其中add_configfiles相當(dāng)于cmake中的configure_file接口,xmake中參考了它的api設(shè)計(jì),并且在其基礎(chǔ)上進(jìn)行了擴(kuò)展支持,提供更多的靈活性。

此接口相比以前的set_config_header更加的通用,不僅用于處理config.h的自動生成和預(yù)處理,還可以處理各種文件類型,而set_config_header僅用于處理頭文件,并且不支持模板變量替換。

先來一個(gè)簡單的例子:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    set_configdir("$(buildir)/config")
    add_configfiles("src/config.h.in")

上面的設(shè)置,會在編譯前,自動的將config.h.in這個(gè)頭文件配置模板,經(jīng)過預(yù)處理后,生成輸出到指定的build/config/config.h

這個(gè)接口的一個(gè)最重要的特性就是,可以在預(yù)處理的時(shí)候,對里面的一些模板變量進(jìn)行預(yù)處理替換,例如:

config.h.in

#define VAR1 "${VAR1}"
#define VAR2 "${VAR2}"
#define HELLO "${HELLO}"
set_configvar("VAR1", "1")

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

    set_configvar("VAR2", 2)
    add_configfiles("config.h.in", {variables = {hello = "xmake"}})
    add_configfiles("*.man", {copyonly = true})

通過set_configvar接口設(shè)置模板變量,裹著通過{variables = {xxx = ""}}中設(shè)置的變量進(jìn)行替換處理。

預(yù)處理后的文件config.h內(nèi)容為:

#define VAR1 "1"
#define VAR2 "2"
#define HELLO "xmake"

{copyonly = true}設(shè)置,會強(qiáng)制將*.man作為普通文件處理,僅在預(yù)處理階段copy文件,不進(jìn)行變量替換。

默認(rèn)的模板變量匹配模式為${var},當(dāng)然我們也可以設(shè)置其他的匹配模式,例如,改為@var@匹配規(guī)則:

target("test")
    add_configfiles("config.h.in", {pattern = "@(.-)@"})

我們也有提供了一些內(nèi)置的變量,即使不通過此接口設(shè)置,也是可以進(jìn)行默認(rèn)變量替換的:

${VERSION} -> 1.6.3
${VERSION_MAJOR} -> 1
${VERSION_MINOR} -> 6
${VERSION_ALTER} -> 3
${VERSION_BUILD} -> set_version("1.6.3", {build = "%Y%m%d%H%M"}) -> 201902031421
${PLAT} and ${plat} -> MACOS and macosx
${ARCH} and ${arch} -> ARM and arm
${MODE} and ${mode} -> DEBUG/RELEASE and debug/release
${DEBUG} and ${debug} -> 1 or 0
${OS} and ${os} -> IOS or ios

例如:

config.h.in

#define CONFIG_VERSION "${VERSION}"
#define CONFIG_VERSION_MAJOR ${VERSION_MAJOR}
#define CONFIG_VERSION_MINOR ${VERSION_MINOR}
#define CONFIG_VERSION_ALTER ${VERSION_ALTER}
#define CONFIG_VERSION_BUILD ${VERSION_BUILD}

config.h

#define CONFIG_VERSION "1.6.3"
#define CONFIG_VERSION_MAJOR 1
#define CONFIG_VERSION_MINOR 6
#define CONFIG_VERSION_ALTER 3
#define CONFIG_VERSION_BUILD 201902031401

我們還可以對#define定義進(jìn)行一些變量狀態(tài)控制處理:

config.h.in

${define FOO_ENABLE}
set_configvar("FOO_ENABLE", 1) -- or pass true
set_configvar("FOO_STRING", "foo")

通過上面的變量設(shè)置后,${define xxx}就會替換成:

#define FOO_ENABLE 1
#define FOO_STRING "foo"

或者(設(shè)置為0禁用的時(shí)候)

/* #undef FOO_ENABLE */
/* #undef FOO_STRING */

這種方式,對于一些自動檢測生成config.h非常有用,比如配合option來做自動檢測:

option("foo")
    set_default(true)
    set_description("Enable Foo")
    set_configvar("FOO_ENABLE", 1) -- 或者傳遞true,啟用FOO_ENABLE變量
    set_configvar("FOO_STRING", "foo")

target("test")
    add_configfiles("config.h.in")

    -- 如果啟用foo選項(xiàng) -> 天劍 FOO_ENABLE 和 FOO_STRING 定義
    add_options("foo") 

config.h.in

${define FOO_ENABLE}
${define FOO_STRING}

config.h

#define FOO_ENABLE 1
#define FOO_STRING "foo"

關(guān)于option選項(xiàng)檢測,以及config.h的自動生成,有一些輔助函數(shù),可以看下:https://github.com/xmake-io/xmake/issues/342

除了#define,如果想要對其他非#define xxx也做狀態(tài)切換處理,可以使用 ${default xxx 0} 模式,設(shè)置默認(rèn)值,例如:

HAVE_SSE2 equ ${default VAR_HAVE_SSE2 0}

通過set_configvar("HAVE_SSE2", 1)啟用變量后,變?yōu)?code>HAVE_SSE2 equ 1,如果沒有設(shè)置變量,則使用默認(rèn)值:HAVE_SSE2 equ 0

關(guān)于這個(gè)的詳細(xì)說明,見:https://github.com/xmake-io/xmake/issues/320

更加方便的特性檢測

我們通過add_configfiles配合option檢測,可以做到檢測一些頭文件、接口函數(shù)、類型、編譯器特性是否存在,如果存在則自動寫入config.h中,例如:

option("foo")
    set_default(true)
    set_description("Has pthread library")
    add_cincludes("pthread.h")
    add_cfuncs("pthread_create")
    add_links("pthread")
    set_configvar("HAS_PTHREAD", 1) 

target("test")
    add_configfiles("config.h.in")
    add_options("pthread") 

config.h.in

${define HAS_PTHREAD}

config.h

#define HAS_PTHREAD 1

上面的配置,我們通過option檢測pthread.h里面的接口以及l(fā)ink庫是否都存在,如果能正常使用pthread庫,那么自動在config.h中定義HAS_PTHREAD,并且test target中追加上相關(guān)的links。

上面的option可以支持各種檢測,但是配置上少許復(fù)雜繁瑣了些,為了讓xmake.lua更加的簡潔直觀,對于一些常用檢測,xmake通過擴(kuò)展includes接口,
提供了一些內(nèi)置封裝好的輔助接口函數(shù),來快速實(shí)現(xiàn)上面的option檢測,寫入config.h的功能。

上面的代碼我們可以簡化為:

includes("check_cfuncs.lua")
target("test")
    add_configfiles("config.h.in")
    configvar_check_cfuncs("HAS_PTHREAD", "pthread_create", {includes = "pthread.h", links = "pthread"})

除了configvar_check_cfuncs,我們還有check_cfuncs函數(shù),僅吧檢測結(jié)果直接在編譯時(shí)候追加,不再寫入configfiles文件中。

我們再來看個(gè)綜合性的例子:

includes("check_links.lua")
includes("check_ctypes.lua")
includes("check_cfuncs.lua")
includes("check_features.lua")
includes("check_csnippets.lua")
includes("check_cincludes.lua")

target("test")
    set_kind("binary")
    add_files("*.c")
    add_configfiles("config.h.in")

    configvar_check_ctypes("HAS_WCHAR", "wchar_t")
    configvar_check_cincludes("HAS_STRING_H", "string.h")
    configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
    configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
    configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"})
    configvar_check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");")
    configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}})
    configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr")
    configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr", "c_static_assert"}, {languages = "c++11"})

config.h.in

${define HAS_STRING_H}
${define HAS_STRING_AND_STDIO_H}
${define HAS_WCHAR}
${define HAS_WCHAR_AND_FLOAT}
${define HAS_PTHREAD}
${define HAS_STATIC_ASSERT}
${define HAS_SETJMP}
${define HAS_CONSTEXPR}
${define HAS_CONSEXPR_AND_STATIC_ASSERT}

config.h

/* #undef HAS_STRING_H */
#define HAS_STRING_AND_STDIO_H 1
/* #undef HAS_WCHAR */
/* #undef HAS_WCHAR_AND_FLOAT */
#define HAS_PTHREAD 1
#define HAS_STATIC_ASSERT 1
#define HAS_SETJMP 1
/* #undef HAS_CONSTEXPR */
#define HAS_CONSEXPR_AND_STATIC_ASSERT 1

可以看到,xmake還提供了其他的輔助函數(shù),用于檢測:c/c++類型,c/c++代碼片段,c/c++函數(shù)接口,鏈接庫,頭文件是否存在,甚至是c/c++編譯器特性支持力度等。

關(guān)于這塊的更加完整的說明,可以看下:https://github.com/xmake-io/xmake/issues/342

配置自定義安裝文件

對于xmake install/uninstall命令,xmake新增了add_installfiles接口來設(shè)置一些安裝文件,比起on_install,此接口用起來更加的方便簡潔,基本能夠滿足大部分安裝需求。

比如我們可以指定安裝各種類型的文件到安裝目錄:

target("test")
    add_installfiles("src/*.h")
    add_installfiles("doc/*.md")

默認(rèn)在linux等系統(tǒng)上,我們會安裝到/usr/local/*.h, /usr/local/*.md,不過我們也可以指定安裝到特定子目錄:

target("test")
    add_installfiles("src/*.h", {prefixdir = "include"})
    add_installfiles("doc/*.md", {prefixdir = "share/doc"})

上面的設(shè)置,我們會安裝到/usr/local/include/*.h, /usr/local/share/doc/*.md

我們也可以通過()去提取源文件中的子目錄來安裝,例如:

target("test")
    add_installfiles("src/(tbox/*.h)", {prefixdir = "include"})
    add_installfiles("doc/(tbox/*.md)", {prefixdir = "share/doc"})

我們把src/tbox/*.h中的文件,提取tbox/*.h子目錄結(jié)構(gòu)后,在進(jìn)行安裝:/usr/local/include/tbox/*.h, /usr/local/share/doc/tbox/*.md

當(dāng)然,用戶也可以通過set_installdir接口,來配合使用。

關(guān)于此接口的詳細(xì)說明,見:https://github.com/xmake-io/xmake/issues/318

CMakelists.txt導(dǎo)出

新版本對xmake project工程生成插件進(jìn)行了擴(kuò)展,新增了對CMakelists.txt文件的導(dǎo)出支持,方便使用xmake的用戶可以快速導(dǎo)出CMakelists.txt提供給cmake,
以及CLion等一些支持cmake的工具使用,使用方式如下:

$ xmake project -k cmakelists

即可在當(dāng)前工程目錄下,生成對應(yīng)的CMakelists.txt文件。

原文出處:https://tboox.org/cn/2019/04/01/xmake-v2.2.5-new-features/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,737評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內(nèi)容

  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,882評論 0 5
  • 2.1.5版本現(xiàn)已進(jìn)入收尾階段,此版本加入了一大波新特性,目前正在進(jìn)行穩(wěn)定性測試和修復(fù),在這里,先來介紹下新版本中...
    waruqi閱讀 879評論 0 51
  • 命令簡介 cmd是command的縮寫.即命令行 。 雖然隨著計(jì)算機(jī)產(chǎn)業(yè)的發(fā)展,Windows 操作系統(tǒng)的應(yīng)用越來...
    Littleston閱讀 3,334評論 0 12
  • 0×1.幀中繼概述Frame Relay,簡稱FR,可以將它看做X.25協(xié)議的簡化版本,幀中繼網(wǎng)絡(luò)中不考慮傳輸差錯(cuò)...
    Zero___閱讀 2,308評論 0 2
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,711評論 0 3