尝试使用其他构建系统构建

xmake v2.3.1以上版本直接对接了其他第三方构建系统,即使其他项目中没有使用xmake.lua来维护,xmake也可以直接调用其他构建工具来完成编译。

那用户直接调用使用第三方构建工具来编译不就行了,为啥还要用xmake去调用呢?主要有以下好处:

  1. 完全的行为一致,简化编译流程,不管用了哪个其他构建系统,都只需要执行xmake这个命令就可以编译,用户不再需要去研究其他工具的不同的编译流程
  2. 完全对接xmake config的配置环境,复用xmake的平台探测和sdk环境检测,简化平台配置
  3. 对接交叉编译环境,即使是用autotools维护的项目,也能通过xmake快速实现交叉编译

目前已支持的构建系统:

  • autotools(已完全对接xmake的交叉编译环境)
  • xcodebuild
  • cmake
  • make
  • msbuild
  • scons
  • meson
  • bazel
  • ndkbuild
  • ninja

自动探测构建系统并编译

例如,对于一个使用cmake维护的项目,直接在项目根目录执行xmake,就会自动触发探测机制,检测到CMakeLists.txt,然后提示用户是否需要使用cmake来继续完成编译。

  1. $ xmake
  2. note: CMakeLists.txt found, try building it (pass -y or --confirm=y/n/d to skip confirm)?
  3. please input: y (y/n)
  4. -- Symbol prefix:
  5. -- Configuring done
  6. -- Generating done
  7. -- Build files have been written to: /Users/ruki/Downloads/libpng-1.6.35/build
  8. [ 7%] Built target png-fix-itxt
  9. [ 21%] Built target genfiles
  10. [ 81%] Built target png
  11. [ 83%] Built target png_static
  12. ...
  13. output to /Users/ruki/Downloads/libpng-1.6.35/build/artifacts
  14. build ok!

无缝对接xmake命令

目前支持xmake clean, xmake --rebuildxmake config等常用命令与第三方系统的无缝对接。

我们可以直接清理cmake维护项目的编译输出文件

  1. $ xmake clean
  2. $ xmake clean --all

如果带上--all执行清理,会清除autotools/cmake生成的所有文件,不仅仅只清理对象文件。

默认xmake对接的是增量构建行为,不过我们也可以强制快速重建:

  1. $ xmake --rebuild

手动切换指定构建系统

如果一个项目下有多个构建系统同时在维护,比如libpng项目,自带autotools/cmake/makefile等构建系统维护,xmake默认优先探测使用了autotools,如果想要强制切换其他构建系统,可以执行:

  1. $ xmake f --trybuild=[autotools|cmake|make|msbuild| ..]
  2. $ xmake

另外,配置了--trybuild=参数手动指定了默认的构建系统,后续的build过程就不会额外提示用户选择了。

实现快速交叉编译

众所周知,autotools维护的项目虽然很多都支持交叉编译,但是交叉编译的配置过程很复杂,不同的工具链处理方式还有很多的差异,中途会踩到很多的坑。

即使跑通了一个工具链的交叉编译,如果切到另外一个工具链环境,可能又要折腾好久,而如果使用xmake,通常只需要两条简单的命令即可:

!> 目前就autotools对接支持了xmake的交叉编译,后期还会对cmake等其他构建系统加上支持。

交叉编译android平台

  1. $ xmake f -p android --trybuild=autotools [--ndk=xxx]
  2. $ xmake

!> 其中,—ndk参数配置是可选的,如果用户设置了ANDROID_NDK_HOME环境变量,或者ndk放置在~/Library/Android/sdk/ndk-bundle,xmake都能自动检测到。

是不是很简单?如果你觉得这没啥,那么可以对比下直接操作./configure去配置交叉编译,可以看下这篇文档对比下:将NDK 与其他编译系统配合使用

说白了,你大概得这样,还不一定一次就能搞定:

  1. $ export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
  2. $ export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
  3. $ export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
  4. $ export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang
  5. $ export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++
  6. $ export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
  7. $ export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
  8. $ export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
  9. $ ./configure --host aarch64-linux-android
  10. $ make

交叉编译iphoneos平台

  1. $ xmake f -p iphoneos --trybuild=autotools
  2. $ xmake

交叉编译mingw平台

  1. $ xmake f -p mingw --trybuild=autotools [--mingw=xxx]
  2. $ xmake

使用其他交叉编译工具链

  1. $ xmake f -p cross --trybuild=autotools --sdk=/xxxx
  2. $ xmake

关于更多交叉编译的配置细节,请参考文档:交叉编译,除了多了一个--trybuild=参数,其他交叉编译配置参数都是完全通用的。

传递用户配置参数

我们可以通过--tryconfigs=来传递用户额外的配置参数到对应的第三方构建系统,比如:autotools会传递给./configure,cmake会传递给cmake命令。

  1. $ xmake f --trybuild=autotools --tryconfigs="--enable-shared=no"
  2. $ xmake

比如上述命令,传递--enable-shared=no./configure,来禁用动态库编译。

另外,对于--cflags, --includedirs--ldflags等参数,不需要通过--tryconfigs,通过xmake config --cflags=等内置参数就可透传过去。

编译其他构建系统过程示例

通用编译方式

大多数情况下,每个构建系统对接后的编译方式都是一致的,除了--trybuild=配置参数除外。

  1. $ xmake f --trybuild=[autotools|cmake|meson|ninja|bazel|make|msbuild|xcodebuild]
  2. $ xmake

!> 我们还需要确保—trybuild指定的构建工具已经安装能够正常使用。

构建Android jni程序

如果当前项目下存在jni/Android.mk,那么xmake可以直接调用ndk-build来构建jni库。

  1. $ xmake f -p android --trybuild=ndkbuild [--ndk=]
  2. $ xmake

自动扫描源码生成xmake.lua

对于一份工程源码,可以不用编写makefile,也不用编写各种make相关的工程描述文件(例如:xmake.lua,makefile.am, cmakelist.txt等)

xmake就可以直接编译他们,这是如何做到的呢,简单来说下实现原理:

  1. 首先扫描当前目录下,xmake所以支持的所有源代码文件
  2. 分析代码,检测哪些代码拥有main入口函数
  3. 所有没有main入口的代码编译成静态库
  4. 带有main入口的代码,编译成可执行程序,同时链接其他静态库程序

这种代码扫描和智能编译,非常简单,目前xmake还不支持多级目录扫描,只对单级目录的代码进行扫描编译。。

使用场景

  1. 临时快速编译和运行一些零散的测试代码
  2. 尝试对其他开源库做移植编译
  3. 快速基于现有代码创建新xmake工程

如何使用

直接在带有源码的目录(没有xmake.lua)下执行xmake,然后根据提示操作:

  1. $ xmake
  2. note: xmake.lua not found, try generating it (pass -y or --confirm=y/n/d to skip confirm)?
  3. please input: n (y/n)
  4. y

开源代码的移植和编译

虽然这种方式,并不是非常智能,限制也不少,但是对于想临时写些代码进行编译运行,或者临时想交叉编译一些简单的开源库代码

这种方式已经足够使用了,下面看下一个实际的例子:

我下载了一份zlib-1.2.10的源码,想要编译它,只需要进入zlib的源码目录执行:

  1. $ cd zlib-1.2.10
  2. $ xmake
  3. note: xmake.lua not found, try generating it (pass -y or --confirm=y/n/d to skip confirm)?
  4. please input: n (y/n)
  5. y

就行了,输入y确认后,输出结果如下:

  1. target(zlib-1.2): static
  2. [+]: ./adler32.c
  3. [+]: ./compress.c
  4. [+]: ./crc32.c
  5. [+]: ./deflate.c
  6. [+]: ./gzclose.c
  7. [+]: ./gzlib.c
  8. [+]: ./gzread.c
  9. [+]: ./gzwrite.c
  10. [+]: ./infback.c
  11. [+]: ./inffast.c
  12. [+]: ./inflate.c
  13. [+]: ./inftrees.c
  14. [+]: ./trees.c
  15. [+]: ./uncompr.c
  16. [+]: ./zutil.c
  17. xmake.lua generated, scan ok!👌
  18. checking for the architecture ... x86_64
  19. checking for the Xcode SDK version for macosx ... 10.12
  20. checking for the target minimal version ... 10.12
  21. checking for the c compiler (cc) ... xcrun -sdk macosx clang
  22. checking for the c++ compiler (cxx) ... xcrun -sdk macosx clang
  23. checking for the objc compiler (mm) ... xcrun -sdk macosx clang
  24. checking for the objc++ compiler (mxx) ... xcrun -sdk macosx clang++
  25. checking for the swift compiler (sc) ... xcrun -sdk macosx swiftc
  26. checking for the assember (as) ... xcrun -sdk macosx clang
  27. checking for the linker (ld) ... xcrun -sdk macosx clang++
  28. checking for the static library archiver (ar) ... xcrun -sdk macosx ar
  29. checking for the static library extractor (ex) ... xcrun -sdk macosx ar
  30. checking for the shared library linker (sh) ... xcrun -sdk macosx clang++
  31. checking for the debugger (dd) ... xcrun -sdk macosx lldb
  32. checking for the golang compiler (go) ... go
  33. configure
  34. {
  35. ex = "xcrun -sdk macosx ar"
  36. , sh = "xcrun -sdk macosx clang++"
  37. , host = "macosx"
  38. , ar = "xcrun -sdk macosx ar"
  39. , buildir = "build"
  40. , as = "xcrun -sdk macosx clang"
  41. , plat = "macosx"
  42. , xcode_dir = "/Applications/Xcode.app"
  43. , arch = "x86_64"
  44. , mxx = "xcrun -sdk macosx clang++"
  45. , go = "go"
  46. , target_minver = "10.12"
  47. , ccache = "ccache"
  48. , mode = "release"
  49. , clean = true
  50. , cxx = "xcrun -sdk macosx clang"
  51. , cc = "xcrun -sdk macosx clang"
  52. , dd = "xcrun -sdk macosx lldb"
  53. , kind = "static"
  54. , ld = "xcrun -sdk macosx clang++"
  55. , xcode_sdkver = "10.12"
  56. , sc = "xcrun -sdk macosx swiftc"
  57. , mm = "xcrun -sdk macosx clang"
  58. }
  59. configure ok!
  60. clean ok!
  61. [00%]: ccache compiling.release ./adler32.c
  62. [06%]: ccache compiling.release ./compress.c
  63. [13%]: ccache compiling.release ./crc32.c
  64. [20%]: ccache compiling.release ./deflate.c
  65. [26%]: ccache compiling.release ./gzclose.c
  66. [33%]: ccache compiling.release ./gzlib.c
  67. [40%]: ccache compiling.release ./gzread.c
  68. [46%]: ccache compiling.release ./gzwrite.c
  69. [53%]: ccache compiling.release ./infback.c
  70. [60%]: ccache compiling.release ./inffast.c
  71. [66%]: ccache compiling.release ./inflate.c
  72. [73%]: ccache compiling.release ./inftrees.c
  73. [80%]: ccache compiling.release ./trees.c
  74. [86%]: ccache compiling.release ./uncompr.c
  75. [93%]: ccache compiling.release ./zutil.c
  76. [100%]: archiving.release libzlib-1.2.a
  77. build ok!👌

通过输出结果,可以看到,xmake会去检测扫描当前目录下的所有.c代码,发现没有main入口,应该是静态库程序,因此执行xmake后,就直接编译成静态库libzlib-1.2.a了

连xmake.lua都没有编写,其实xmake在扫描完成后,会去自动在当前目录下生成一份xmake.lua,下次编译就不需要重新扫描检测了。

自动生成的xmake.lua内容如下:

  1. -- define target
  2. target("zlib-1.2")
  3. -- set kind
  4. set_kind("static")
  5. -- add files
  6. add_files("./adler32.c")
  7. add_files("./compress.c")
  8. add_files("./crc32.c")
  9. add_files("./deflate.c")
  10. add_files("./gzclose.c")
  11. add_files("./gzlib.c")
  12. add_files("./gzread.c")
  13. add_files("./gzwrite.c")
  14. add_files("./infback.c")
  15. add_files("./inffast.c")
  16. add_files("./inflate.c")
  17. add_files("./inftrees.c")
  18. add_files("./trees.c")
  19. add_files("./uncompr.c")
  20. add_files("./zutil.c")

也许你会说,像这种开源库,直接configure; make不就好了吗,他们自己也有提供makefile来直接编译的,的确是这样,我这里只是举个例子而已。。

当然,很多开源库在交叉编译的时候,通过自带的configure,处理起来还是很繁琐的,用xmake进行交叉编译会更方便些。。

即时地代码编写和编译运行

xmake的这个扫描代码编译特性,主要的目的:还是为了让我们在临时想写些测试代码的时候,不用考虑太多东西,直接上手敲代码,然后快速执行xmake run 来调试验证结果。。

例如:

我想写了个简单的main.c的测试程序,打印hello world!,如果要写makefile或者直接通过gcc命令来,就很繁琐了,你需要:

  1. gcc ./main.c -o demo
  2. ./demo

最快速的方式,也需要执行两行命令,而如果用xmake,只需要执行:

  1. xmake run

就行了,它会自动检测到代码后,自动生成对应的xmake.lua,自动编译,自动运行,然后输出:

  1. hello world!

如果你有十几个代码文件,用手敲gcc的方式,或者写makefile的方式,这个差距就更明显了,用xmake还是只需要一行命令:

  1. xmake run

多语言支持

这种代码检测和即时编译,是支持多语言的,不仅支持c/c++,还支持objc/swift,后期还会支持golang(正在开发中)

例如我下载了一份fmdb的ios开源框架代码:

  1. .
  2. ├── FMDB.h
  3. ├── FMDatabase.h
  4. ├── FMDatabase.m
  5. ├── FMDatabaseAdditions.h
  6. ├── FMDatabaseAdditions.m
  7. ├── FMDatabasePool.h
  8. ├── FMDatabasePool.m
  9. ├── FMDatabaseQueue.h
  10. ├── FMDatabaseQueue.m
  11. ├── FMResultSet.h
  12. └── FMResultSet.m

想要把它编译成ios的静态库,但是又不想写xmake.lua,或者makefile,那么只需要使用xmake的这个新特性,直接执行:

  1. $ xmake f -p iphoneos; xmake

就行了,输出结果如下:

  1. xmake.lua not found, scanning files ..
  2. target(FMDB): static
  3. [+]: ./FMDatabase.m
  4. [+]: ./FMDatabaseAdditions.m
  5. [+]: ./FMDatabasePool.m
  6. [+]: ./FMDatabaseQueue.m
  7. [+]: ./FMResultSet.m
  8. xmake.lua generated, scan ok!👌
  9. checking for the architecture ... armv7
  10. checking for the Xcode SDK version for iphoneos ... 10.1
  11. checking for the target minimal version ... 10.1
  12. checking for the c compiler (cc) ... xcrun -sdk iphoneos clang
  13. checking for the c++ compiler (cxx) ... xcrun -sdk iphoneos clang
  14. checking for the objc compiler (mm) ... xcrun -sdk iphoneos clang
  15. checking for the objc++ compiler (mxx) ... xcrun -sdk iphoneos clang++
  16. checking for the assember (as) ... gas-preprocessor.pl xcrun -sdk iphoneos clang
  17. checking for the linker (ld) ... xcrun -sdk iphoneos clang++
  18. checking for the static library archiver (ar) ... xcrun -sdk iphoneos ar
  19. checking for the static library extractor (ex) ... xcrun -sdk iphoneos ar
  20. checking for the shared library linker (sh) ... xcrun -sdk iphoneos clang++
  21. checking for the swift compiler (sc) ... xcrun -sdk iphoneos swiftc
  22. configure
  23. {
  24. ex = "xcrun -sdk iphoneos ar"
  25. , ccache = "ccache"
  26. , host = "macosx"
  27. , ar = "xcrun -sdk iphoneos ar"
  28. , buildir = "build"
  29. , as = "/usr/local/share/xmake/tools/utils/gas-preprocessor.pl xcrun -sdk iphoneos clang"
  30. , arch = "armv7"
  31. , mxx = "xcrun -sdk iphoneos clang++"
  32. , cxx = "xcrun -sdk iphoneos clang"
  33. , target_minver = "10.1"
  34. , xcode_dir = "/Applications/Xcode.app"
  35. , clean = true
  36. , sh = "xcrun -sdk iphoneos clang++"
  37. , cc = "xcrun -sdk iphoneos clang"
  38. , ld = "xcrun -sdk iphoneos clang++"
  39. , mode = "release"
  40. , kind = "static"
  41. , plat = "iphoneos"
  42. , xcode_sdkver = "10.1"
  43. , sc = "xcrun -sdk iphoneos swiftc"
  44. , mm = "xcrun -sdk iphoneos clang"
  45. }
  46. configure ok!
  47. clean ok!
  48. [00%]: ccache compiling.release ./FMDatabase.m
  49. [20%]: ccache compiling.release ./FMDatabaseAdditions.m
  50. [40%]: ccache compiling.release ./FMDatabasePool.m
  51. [60%]: ccache compiling.release ./FMDatabaseQueue.m
  52. [80%]: ccache compiling.release ./FMResultSet.m
  53. [100%]: archiving.release libFMDB.a
  54. build ok!👌

同时编译多个可执行文件

输出结果的开头部分,就是对代码的分析结果,虽然目前只支持单级目录结构的代码扫描,但是还是可以同时支持检测和编译多个可执行文件的

我们以libjpeg的开源库为例:

我们进入jpeg-6b目录后,执行:

  1. $ xmake

输出如下:

  1. xmake.lua not found, scanning files ..
  2. target(jpeg-6b): static
  3. [+]: ./cdjpeg.c
  4. [+]: ./example.c
  5. [+]: ./jcapimin.c
  6. [+]: ./jcapistd.c
  7. [+]: ./jccoefct.c
  8. [+]: ./jccolor.c
  9. [+]: ./jcdctmgr.c
  10. [+]: ./jchuff.c
  11. [+]: ./jcinit.c
  12. [+]: ./jcmainct.c
  13. [+]: ./jcmarker.c
  14. [+]: ./jcmaster.c
  15. [+]: ./jcomapi.c
  16. [+]: ./jcparam.c
  17. [+]: ./jcphuff.c
  18. [+]: ./jcprepct.c
  19. [+]: ./jcsample.c
  20. [+]: ./jctrans.c
  21. [+]: ./jdapimin.c
  22. [+]: ./jdapistd.c
  23. [+]: ./jdatadst.c
  24. [+]: ./jdatasrc.c
  25. [+]: ./jdcoefct.c
  26. [+]: ./jdcolor.c
  27. [+]: ./jddctmgr.c
  28. [+]: ./jdhuff.c
  29. [+]: ./jdinput.c
  30. [+]: ./jdmainct.c
  31. [+]: ./jdmarker.c
  32. [+]: ./jdmaster.c
  33. [+]: ./jdmerge.c
  34. [+]: ./jdphuff.c
  35. [+]: ./jdpostct.c
  36. [+]: ./jdsample.c
  37. [+]: ./jdtrans.c
  38. [+]: ./jerror.c
  39. [+]: ./jfdctflt.c
  40. [+]: ./jfdctfst.c
  41. [+]: ./jfdctint.c
  42. [+]: ./jidctflt.c
  43. [+]: ./jidctfst.c
  44. [+]: ./jidctint.c
  45. [+]: ./jidctred.c
  46. [+]: ./jmemansi.c
  47. [+]: ./jmemmgr.c
  48. [+]: ./jmemname.c
  49. [+]: ./jmemnobs.c
  50. [+]: ./jquant1.c
  51. [+]: ./jquant2.c
  52. [+]: ./jutils.c
  53. [+]: ./rdbmp.c
  54. [+]: ./rdcolmap.c
  55. [+]: ./rdgif.c
  56. [+]: ./rdppm.c
  57. [+]: ./rdrle.c
  58. [+]: ./rdswitch.c
  59. [+]: ./rdtarga.c
  60. [+]: ./transupp.c
  61. [+]: ./wrbmp.c
  62. [+]: ./wrgif.c
  63. [+]: ./wrppm.c
  64. [+]: ./wrrle.c
  65. [+]: ./wrtarga.c
  66. target(ansi2knr): binary
  67. [+]: ./ansi2knr.c
  68. target(cjpeg): binary
  69. [+]: ./cjpeg.c
  70. target(ckconfig): binary
  71. [+]: ./ckconfig.c
  72. target(djpeg): binary
  73. [+]: ./djpeg.c
  74. target(jpegtran): binary
  75. [+]: ./jpegtran.c
  76. target(rdjpgcom): binary
  77. [+]: ./rdjpgcom.c
  78. target(wrjpgcom): binary
  79. [+]: ./wrjpgcom.c
  80. xmake.lua generated, scan ok!👌
  81. checking for the architecture ... x86_64
  82. checking for the Xcode SDK version for macosx ... 10.12
  83. checking for the target minimal version ... 10.12
  84. checking for the c compiler (cc) ... xcrun -sdk macosx clang
  85. checking for the c++ compiler (cxx) ... xcrun -sdk macosx clang
  86. checking for the objc compiler (mm) ... xcrun -sdk macosx clang
  87. checking for the objc++ compiler (mxx) ... xcrun -sdk macosx clang++
  88. checking for the swift compiler (sc) ... xcrun -sdk macosx swiftc
  89. checking for the assember (as) ... xcrun -sdk macosx clang
  90. checking for the linker (ld) ... xcrun -sdk macosx clang++
  91. checking for the static library archiver (ar) ... xcrun -sdk macosx ar
  92. checking for the static library extractor (ex) ... xcrun -sdk macosx ar
  93. checking for the shared library linker (sh) ... xcrun -sdk macosx clang++
  94. checking for the debugger (dd) ... xcrun -sdk macosx lldb
  95. checking for the golang compiler (go) ... go
  96. configure
  97. {
  98. ex = "xcrun -sdk macosx ar"
  99. , sh = "xcrun -sdk macosx clang++"
  100. , host = "macosx"
  101. , ar = "xcrun -sdk macosx ar"
  102. , buildir = "build"
  103. , as = "xcrun -sdk macosx clang"
  104. , plat = "macosx"
  105. , xcode_dir = "/Applications/Xcode.app"
  106. , arch = "x86_64"
  107. , mxx = "xcrun -sdk macosx clang++"
  108. , go = "go"
  109. , target_minver = "10.12"
  110. , ccache = "ccache"
  111. , mode = "release"
  112. , clean = true
  113. , cxx = "xcrun -sdk macosx clang"
  114. , cc = "xcrun -sdk macosx clang"
  115. , dd = "xcrun -sdk macosx lldb"
  116. , kind = "static"
  117. , ld = "xcrun -sdk macosx clang++"
  118. , xcode_sdkver = "10.12"
  119. , sc = "xcrun -sdk macosx swiftc"
  120. , mm = "xcrun -sdk macosx clang"
  121. }
  122. configure ok!
  123. clean ok!
  124. [00%]: ccache compiling.release ./cdjpeg.c
  125. [00%]: ccache compiling.release ./example.c
  126. [00%]: ccache compiling.release ./jcapimin.c
  127. [00%]: ccache compiling.release ./jcapistd.c
  128. [00%]: ccache compiling.release ./jccoefct.c
  129. [00%]: ccache compiling.release ./jccolor.c
  130. [01%]: ccache compiling.release ./jcdctmgr.c
  131. [01%]: ccache compiling.release ./jchuff.c
  132. [01%]: ccache compiling.release ./jcinit.c
  133. [01%]: ccache compiling.release ./jcmainct.c
  134. [01%]: ccache compiling.release ./jcmarker.c
  135. [02%]: ccache compiling.release ./jcmaster.c
  136. [02%]: ccache compiling.release ./jcomapi.c
  137. [02%]: ccache compiling.release ./jcparam.c
  138. [02%]: ccache compiling.release ./jcphuff.c
  139. [02%]: ccache compiling.release ./jcprepct.c
  140. [03%]: ccache compiling.release ./jcsample.c
  141. [03%]: ccache compiling.release ./jctrans.c
  142. [03%]: ccache compiling.release ./jdapimin.c
  143. [03%]: ccache compiling.release ./jdapistd.c
  144. [03%]: ccache compiling.release ./jdatadst.c
  145. [04%]: ccache compiling.release ./jdatasrc.c
  146. [04%]: ccache compiling.release ./jdcoefct.c
  147. [04%]: ccache compiling.release ./jdcolor.c
  148. [04%]: ccache compiling.release ./jddctmgr.c
  149. [04%]: ccache compiling.release ./jdhuff.c
  150. [05%]: ccache compiling.release ./jdinput.c
  151. [05%]: ccache compiling.release ./jdmainct.c
  152. [05%]: ccache compiling.release ./jdmarker.c
  153. [05%]: ccache compiling.release ./jdmaster.c
  154. [05%]: ccache compiling.release ./jdmerge.c
  155. [06%]: ccache compiling.release ./jdphuff.c
  156. [06%]: ccache compiling.release ./jdpostct.c
  157. [06%]: ccache compiling.release ./jdsample.c
  158. [06%]: ccache compiling.release ./jdtrans.c
  159. [06%]: ccache compiling.release ./jerror.c
  160. [07%]: ccache compiling.release ./jfdctflt.c
  161. [07%]: ccache compiling.release ./jfdctfst.c
  162. [07%]: ccache compiling.release ./jfdctint.c
  163. [07%]: ccache compiling.release ./jidctflt.c
  164. [07%]: ccache compiling.release ./jidctfst.c
  165. [08%]: ccache compiling.release ./jidctint.c
  166. [08%]: ccache compiling.release ./jidctred.c
  167. [08%]: ccache compiling.release ./jmemansi.c
  168. [08%]: ccache compiling.release ./jmemmgr.c
  169. [08%]: ccache compiling.release ./jmemname.c
  170. [09%]: ccache compiling.release ./jmemnobs.c
  171. [09%]: ccache compiling.release ./jquant1.c
  172. [09%]: ccache compiling.release ./jquant2.c
  173. [09%]: ccache compiling.release ./jutils.c
  174. [09%]: ccache compiling.release ./rdbmp.c
  175. [10%]: ccache compiling.release ./rdcolmap.c
  176. [10%]: ccache compiling.release ./rdgif.c
  177. [10%]: ccache compiling.release ./rdppm.c
  178. [10%]: ccache compiling.release ./rdrle.c
  179. [10%]: ccache compiling.release ./rdswitch.c
  180. [11%]: ccache compiling.release ./rdtarga.c
  181. [11%]: ccache compiling.release ./transupp.c
  182. [11%]: ccache compiling.release ./wrbmp.c
  183. [11%]: ccache compiling.release ./wrgif.c
  184. [11%]: ccache compiling.release ./wrppm.c
  185. [12%]: ccache compiling.release ./wrrle.c
  186. [12%]: ccache compiling.release ./wrtarga.c
  187. [12%]: archiving.release libjpeg-6b.a
  188. [12%]: ccache compiling.release ./wrjpgcom.c
  189. [25%]: linking.release wrjpgcom
  190. [25%]: ccache compiling.release ./ansi2knr.c
  191. [37%]: linking.release ansi2knr
  192. [37%]: ccache compiling.release ./jpegtran.c
  193. [50%]: linking.release jpegtran
  194. [50%]: ccache compiling.release ./djpeg.c
  195. [62%]: linking.release djpeg
  196. [62%]: ccache compiling.release ./ckconfig.c
  197. [75%]: linking.release ckconfig
  198. [75%]: ccache compiling.release ./rdjpgcom.c
  199. [87%]: linking.release rdjpgcom
  200. [87%]: ccache compiling.release ./cjpeg.c
  201. [100%]: linking.release cjpeg
  202. build ok!👌

可以看到,处理静态库,xmake还分析出了很多可执行的测试程序,剩下的代码统一编译成一个 libjpeg.a 的静态库,供哪些测试程序链接使用。。

  1. target(ansi2knr): binary
  2. [+]: ./ansi2knr.c
  3. target(cjpeg): binary
  4. [+]: ./cjpeg.c
  5. target(ckconfig): binary
  6. [+]: ./ckconfig.c
  7. target(djpeg): binary
  8. [+]: ./djpeg.c
  9. target(jpegtran): binary
  10. [+]: ./jpegtran.c
  11. target(rdjpgcom): binary
  12. [+]: ./rdjpgcom.c
  13. target(wrjpgcom): binary
  14. [+]: ./wrjpgcom.c

遇到的一些问题和限制

当前xmake的这种自动分析检测还不是非常智能,对于:

  1. 需要特殊的编译选项
  2. 需要依赖其他目录的头文件搜索
  3. 需要分条件编译不同源文件
  4. 同目录需要生成多个静态库
  5. 需要多级目录支持的源码库

以上这些情况,xmake暂时还没发自动化的智能处理,其中限制1,2还是可以解决的,通过半手动的方式,例如:

  1. $ xmake f --cxflags="" --ldflags="" --includedirs="" --linkdirs=""; xmake

在自动检测编译的时候,手动配置这个源码工程需要的特殊编译选项,就可以直接通过编译了

而限制3,暂时只能通过删源代码来解决了,就像刚才编译jpeg的代码,其实它的目录下面同时存在了:

  1. jmemdos.c
  2. jmemmac.c
  3. jmemansi.c

其中两个是没法编译过的,需要删掉后才行。。