生成IDE工程文件

简介

XMake跟cmake, premake等其他一些构建工具的区别在于:

xmake默认是直接构建运行的,生成第三方的IDE的工程文件仅仅作为插件来提供。

这样做的一个好处是:插件更加容易扩展,维护也更加独立和方便。

生成Makefile

  1. $ xmake project -k makefile

生成CMakelists.txt

  1. $ xmake project -k cmakelists

生成build.ninja

!> 2.3.1以上版本才支持

  1. $ xmake project -k ninja

生成compiler_flags

  1. $ xmake project -k compiler_flags

生成compiler_commands

导出每个源文件的编译信息,生成基于clang的编译数据库文件,json格式,可用于跟ide,编辑器,静态分析工具进行交互。

  1. $ xmake project -k compile_commands

输出的内容格式如下:

  1. [
  2. { "directory": "/home/user/llvm/build",
  3. "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc",
  4. "file": "file.cc" },
  5. ...
  6. ]

对于compile_commands的详细说明见:JSONCompilationDatabase

生成VisualStudio工程

使用xmake集成编译

v2.2.8以上版本,提供了新版本的vs工程生成插件扩展,跟之前的生成vs的插件处理模式上有很大的不同,之前生成的vs工程是吧所有文件的编译展开后,转交给vs来处理编译。

但是这种模式,对xmake的rules是没法支持的。因为xmake的rules里面用了很多的on_build此类自定义脚本,无法展开,所以像qt, wdk此类的项目就没法支持导出到vs里面进行编译了。

因此,为了解决这个问题,新版本的vs生成插件通过在vs下直接调用xmake命令,去执行编译操作,并且对intellsence和定义跳转,还有断点调试也做了支持。

具体使用方式跟老版本类似:

  1. $ xmake project -k [vsxmake2010|vsxmake2013|vsxmake2015|..] -m "debug;release"

如果没指明版本,那么xmake会自动探测当前已有的vs版本来生成:

  1. $ xmake project -k vsxmake -m "debug;release"

内置插件 - 图1

另外,vsxmake插件还会额外生成一个自定义的配置属性页,用于在vs里面,方便灵活的修改和追加一些xmake编译配置,甚至可以在里面配置切换到其他交叉工具链,实现在vs中对android, linux等其他平台的交叉编译。

内置插件 - 图2

使用vs内置编译机制

!> 建议尽量使用上文提到的v2.2.8之后提供的新版的vs生成插件,支持更加完善,此处的生成方式不支持xmake的rules,以及对qt等工程的生成。

  1. $ xmake project -k [vs2008|vs2013|vs2015|..]

v2.1.2以上版本,增强了vs201x版本工程的生成,支持多模式+多架构生成,生成的时候只需要指定:

  1. $ xmake project -k vs2017 -m "debug,release"

生成后的工程文件,同时支持debug|x86, debug|x64, release|x86, release|x64四种配置模式。

如果不想每次生成的时候,指定模式,可以把模式配置加到xmake.lua的中,例如:

  1. -- 配置当前的工程,支持哪些编译模式
  2. add_rules("mode.debug", "mode.release")

运行自定义lua脚本

这个跟宏脚本类似,只是省去了导入导出操作,直接指定lua脚本来加载运行,这对于想要快速测试一些接口模块,验证自己的某些思路,都是一个不错的方式。

运行指定的脚本文件

我们先写个简单的lua脚本:

  1. function main()
  2. print("hello xmake!")
  3. end

然后直接运行它就行了:

  1. $ xmake lua /tmp/test.lua

当然,你也可以像宏脚本那样,使用import接口导入扩展模块,实现复杂的功能。

运行内置的脚本命令

你可以运行 xmake lua -l 来列举所有内置的脚本名,例如:

  1. $ xmake lua -l
  2. scripts:
  3. cat
  4. cp
  5. echo
  6. versioninfo
  7. ...

并且运行它们:

  1. $ xmake lua cat ~/file.txt
  2. $ xmake lua echo "hello xmake"
  3. $ xmake lua cp /tmp/file /tmp/file2
  4. $ xmake lua versioninfo

运行交互命令 (REPL)

有时候在交互模式下,运行命令更加的方便测试和验证一些模块和api,也更加的灵活,不需要再去额外写一个脚本文件来加载。

我们先看下,如何进入交互模式:

  1. # 不带任何参数执行,就可以进入
  2. $ xmake lua
  3. >
  4. # 进行表达式计算
  5. > 1 + 2
  6. 3
  7. # 赋值和打印变量值
  8. > a = 1
  9. > a
  10. 1
  11. # 多行输入和执行
  12. > for _, v in pairs({1, 2, 3}) do
  13. >> print(v)
  14. >> end
  15. 1
  16. 2
  17. 3

我们也能够通过 import 来导入扩展模块:

  1. > task = import("core.project.task")
  2. > task.run("hello")
  3. hello xmake!

如果要中途取消多行输入,只需要输入字符:q 就行了

  1. > for _, v in ipairs({1, 2}) do
  2. >> print(v)
  3. >> q <-- 取消多行输入,清空先前的输入数据
  4. > 1 + 2
  5. 3

宏记录和回放

简介

我们可以通过这个插件,快速记录和回放我们平常频繁使用到的一些xmake操作,来简化我们日常的开发工作。

它提供了一些功能:

  • 手动记录和回放多条执行过的xmake命令
  • 支持快速的匿名宏创建和回放
  • 支持命名宏的长久记录和重用
  • 支持宏脚本的批量导入和导出
  • 支持宏脚本的删除、显示等管理功能
  • 支持自定义高级宏脚本,以及参数配置

记录操作

  1. # 开始记录宏
  2. $ xmake macro --begin
  3. # 执行一些xmake命令
  4. $ xmake f -p android --ndk=/xxx/ndk -a armv7-a
  5. $ xmake p
  6. $ xmake f -p mingw --sdk=/mingwsdk
  7. $ xmake p
  8. $ xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin
  9. $ xmake p
  10. $ xmake f -p iphoneos -a armv7
  11. $ xmake p
  12. $ xmake f -p iphoneos -a arm64
  13. $ xmake p
  14. $ xmake f -p iphoneos -a armv7s
  15. $ xmake p
  16. $ xmake f -p iphoneos -a i386
  17. $ xmake p
  18. $ xmake f -p iphoneos -a x86_64
  19. $ xmake p
  20. # 结束宏记录,这里不设置宏名字,所以记录的是一个匿名宏
  21. xmake macro --end

回放

  1. # 回放一个匿名宏
  2. $ xmake macro .

命名宏

匿名宏的好处就是快速记录,快速回放,如果需要长久保存,就需要给宏取个名字。

  1. $ xmake macro --begin
  2. $ ...
  3. $ xmake macro --end macroname
  4. $ xmake macro macroname

导入导出宏

导入指定的宏脚本或者宏目录:

  1. $ xmake macro --import=/xxx/macro.lua macroname
  2. $ xmake macro --import=/xxx/macrodir

导出指定的宏到脚本或者目录:

  1. $ xmake macro --export=/xxx/macro.lua macroname
  2. $ xmake macro --export=/xxx/macrodir

列举显示宏

列举所有xmake内置的宏脚本:

  1. $ xmake macro --list

显示指定的宏脚本内容:

  1. $ xmake macro --show macroname

自定义宏脚本

我们也可以自己编写个宏脚本 macro.lua 然后导入到xmake中去。

  1. function main()
  2. os.exec("xmake f -p android --ndk=/xxx/ndk -a armv7-a")
  3. os.exec("xmake p")
  4. os.exec("xmake f -p mingw --sdk=/mingwsdk")
  5. os.exec("xmake p")
  6. os.exec("xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin")
  7. os.exec("xmake p")
  8. os.exec("xmake f -p iphoneos -a armv7")
  9. os.exec("xmake p")
  10. os.exec("xmake f -p iphoneos -a arm64")
  11. os.exec("xmake p")
  12. os.exec("xmake f -p iphoneos -a armv7s")
  13. os.exec("xmake p")
  14. os.exec("xmake f -p iphoneos -a i386")
  15. os.exec("xmake p")
  16. os.exec("xmake f -p iphoneos -a x86_64")
  17. os.exec("xmake p")
  18. end

导入到xmake,并且定义宏名字:

  1. $ xmake macro --import=/xxx/macro.lua [macroname]

回放这个宏脚本:

  1. $ xmake macro [.|macroname]

内置的宏脚本

XMake 提供了一些内置的宏脚本,来简化我们的日常开发工作。

例如,我们可以使用 package 宏来对iphoneos平台的所有架构,一次性批量构建和打包:

  1. $ xmake macro package -p iphoneos

高级的宏脚本编写

以上面提到的package宏为例,我们看下其具体代码,里面通过import导入一些扩展模块,实现了复杂的脚本操作。

  1. -- imports
  2. import("core.base.option")
  3. import("core.project.config")
  4. import("core.project.project")
  5. import("core.platform.platform")
  6. -- the options
  7. local options =
  8. {
  9. {'p', "plat", "kv", os.host(), "Set the platform." }
  10. , {'f', "config", "kv", nil, "Pass the config arguments to \"xmake config\" .." }
  11. , {'o', "outputdir", "kv", nil, "Set the output directory of the package." }
  12. }
  13. -- package all
  14. --
  15. -- .e.g
  16. -- xmake m package
  17. -- xmake m package -f "-m debug"
  18. -- xmake m package -p linux
  19. -- xmake m package -p iphoneos -f "-m debug --xxx ..." -o /tmp/xxx
  20. -- xmake m package -f \"--mode=debug\"
  21. --
  22. function main(argv)
  23. -- parse arguments
  24. local args = option.parse(argv, options, "Package all architectures for the given the platform."
  25. , ""
  26. , "Usage: xmake macro package [options]")
  27. -- package all archs
  28. local plat = args.plat
  29. for _, arch in ipairs(platform.archs(plat)) do
  30. -- config it
  31. os.exec("xmake f -p %s -a %s %s -c %s", plat, arch, args.config or "", ifelse(option.get("verbose"), "-v", ""))
  32. -- package it
  33. if args.outputdir then
  34. os.exec("xmake p -o %s %s", args.outputdir, ifelse(option.get("verbose"), "-v", ""))
  35. else
  36. os.exec("xmake p %s", ifelse(option.get("verbose"), "-v", ""))
  37. end
  38. end
  39. -- package universal for iphoneos, watchos ...
  40. if plat == "iphoneos" or plat == "watchos" then
  41. -- load configure
  42. config.load()
  43. -- load project
  44. project.load()
  45. -- enter the project directory
  46. os.cd(project.directory())
  47. -- the outputdir directory
  48. local outputdir = args.outputdir or config.get("buildir")
  49. -- package all targets
  50. for _, target in pairs(project.targets()) do
  51. -- get all modes
  52. local modedirs = os.match(format("%s/%s.pkg/lib/*", outputdir, target:name()), true)
  53. for _, modedir in ipairs(modedirs) do
  54. -- get mode
  55. local mode = path.basename(modedir)
  56. -- make lipo arguments
  57. local lipoargs = nil
  58. for _, arch in ipairs(platform.archs(plat)) do
  59. local archfile = format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target:name(), mode, plat, arch, path.filename(target:targetfile()))
  60. if os.isfile(archfile) then
  61. lipoargs = format("%s -arch %s %s", lipoargs or "", arch, archfile)
  62. end
  63. end
  64. if lipoargs then
  65. -- make full lipo arguments
  66. lipoargs = format("-create %s -output %s/%s.pkg/lib/%s/%s/universal/%s", lipoargs, outputdir, target:name(), mode, plat, path.filename(target:targetfile()))
  67. -- make universal directory
  68. os.mkdir(format("%s/%s.pkg/lib/%s/%s/universal", outputdir, target:name(), mode, plat))
  69. -- package all archs
  70. os.execv("xmake", {"l", "lipo", lipoargs})
  71. end
  72. end
  73. end
  74. end
  75. end

如果你想要获取更多宏参数选项信息,请运行: xmake macro --help

生成doxygen文档

请先确保本机已安装doxygen工具,然后在工程目录下运行:

  1. $ xmake doxygen