脚本宝典收集整理的这篇文章主要介绍了

quotes and \-es.”” -c -o file.o file.cc””

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

2.1.5版本现已进入收尾阶段,此版本加入了一大波新特性,目前正在进行稳定性测试和修复,在这里,先来介绍下新版本中引入了哪些新特性和改进。

1. 提供类似cmake的find_*系列接口,实现各种查找,例如:find_package, find_library, find_file, ...
2. 提供模块接口,实现编译器的各种检测,例如:has_features, has_flags, has_cincludes, has_cfuncs, ...
3. 实现大量扩展模块,提供文件下载、解压缩、git操作等接口
4. 支持预编译头文件支持,改进c++编译效率
5. 支持在工程中自定义模块进行扩展
6. 提供代码片段检测接口,实现更加灵活定制化的检测需求
7. 改进option和target,提供更加动态化的配置
8. 通过find_package实现包依赖管理2.0版本
9. 改进root权限问题,实现更加安全的root下运行
10. 提供compile_commands.json导出插件
11. 改进vs201x工程生成插件,支持多模式、多架构同时构建和自由切换不干扰

利用find_package查找依赖包

此接口参考了cmake对于find_*系列接口的设计,实现在项目中动态的查找和添加包依赖。

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

上述描述代码,通过lib.detect.find_package来查找包,如果找到zlib包,则将links, includedirslinkdirs等信息添加到target中去。

实现包管理2.0

2.1.4版本之前,xmake对于包管理,是通过在项目内置pkg/zlib.pkg方式,来检测链接的,虽然也支持自动检测,但是查找功能有限,并且内置的各个架构的二进制库到项目,对git并不是很友好。

现在通过find_packageoption,我们可以实现更好的包管理:

option("zlib")
    set_showmenu(true)
    before_check(function (option)
        import("lib.detect.find_package")
        option:add(find_package("zlib"))
    end)

target("test")
    add_options("zlib")

通过定义一个名为zlib的选项作为包,关联到target,在选项被检测之前,先从系统中查找zlib包,如果存在,则添加对应的links, linkdirs等配置信息,然后进行选项检测,如果选项检测通过,这个target在编译的时候就会启用zlib。

如果要手动禁用这个zlib包,使其不参与自动检测和链接,只需要:

$ xmake f --zlib=n 
$ xmake

注:2.2.1版本将会实现包管理3.0,更加自动化的依赖包管理和使用,具体详情见:Remote package management

例如:

add_requires("mbedtls master optional")
add_requires("pcre2 >=1.2.0", "zlib >= 1.2.11")
add_requires("git@github.com:glennrp/libpng.git@libpng >=1.6.28")
target("test")
    add_packages("pcre2", "zlib", "libpng", "mbedtls")

目前正在努力开发中,尽情期待。。

模块的自定义扩展

我们可以通过在工程的xmake.lua文件的开头指定下扩展modules的目录:

add_moduledirs("$(projectdir)/xmake/modules")

这样xmake就能找到自定义的扩展模块了,例如:

projectdir
 - xmake
   - modules
     - detect/package/find_openssl.lua

通过在自定义的工程模块目录,添加一个find_openssl.lua的脚本,就可以扩展find_package,使得包查找更加精准。

这里顺便总结下,find_package的查找顺序:

  1. 如果指定{packagedirs = ""}参数,优先从这个参数指定的路径中查找本地包*.pkg
  2. 如果在xmake/modules下面存在detect.packages.find_xxx脚本,那么尝试调用此脚本来改进查找结果
  3. 如果系统存在pkg-config,并且查找的是系统环境的库,则尝试使用pkg-config提供的路径和链接信息进行查找
  4. 如果系统存在homebrew,并且查找的是系统环境的库,则尝试使用brew --prefix xxx提供的信息进行查找
  5. 从参数中指定的pathes路径和一些已知的系统路径/usr/lib, /usr/include中进行查找

快速判断编译器特性检测支持

通过core.tool.compiler模块的compiler.has_features接口,在xmake.lua中预先判断当前编译期支持的语言特性,实现条件编译。

此处也是参考了cmake的设计,具体详情见:issues#83

target("test")
    on_load(function (target)
        import("core.tool.compiler")
        if compiler.has_features("cxx_constexpr") then
            target:add("defines", "HAS_CXX_CONSTEXPR=1")
        end
    end)

上述代码,在加载target的时候,判断当前编译器是否支持c++的常量表达式语法特性,如果支持则添加宏定义:HAS_CXX_CONSTEXPR=1

我们也可以在判断时候,追加一些参数控制编译选项,例如上述特性需要c++11支持,我们可以启用它:

if compiler.has_features({"c_static_assert", "cxx_constexpr"}, {languages = "cxx11"}) then
    -- ok
end

如果之前对这个target已经设置了c++11,那么我们也可以传入target对象,继承target的所有设置:

if compiler.has_features("cxx_constexpr", {target = target, defines = "..", includedirs = ".."}) then
    -- ok
end

所有的c/c++编译器特性列表,见:compiler.features

判断指定c/c++头文件是否存在

通过lib.detect.has_cincludes来检测c头文件是否存在。

import("lib.detect.has_cincludes")

local ok = has_cincludes("stdio.h")
local ok = has_cincludes({"stdio.h", "stdlib.h"}, {target = target})
local ok = has_cincludes({"stdio.h", "stdlib.h"}, {defines = "_GNU_SOURCE=1", languages = "cxx11"})

c++头文件的检测,见:lib.detect.has_cxxincludes

判断指定c/c++函数是否存在

通过lib.detect.has_cfuncs来检测c函数是否存在。

import("lib.detect.has_cfuncs")

local ok = has_cfuncs("setjmp")
local ok = has_cfuncs({"sigsetjmp((void*)0, 0)", "setjmp"}, {includes = "setjmp.h"})

c++函数的检测,见:lib.detect.has_cxxfuncs

判断指定c/c++类型是否存在

通过lib.detect.has_ctypes来检测c函数是否存在。

import("lib.detect.has_ctypes")

local ok = has_ctypes("wchar_t")
local ok = has_ctypes({"char", "wchar_t"}, {includes = "stdio.h"})
local ok = has_ctypes("wchar_t", {includes = {"stdio.h", "stdlib.h"}, "defines = "_GNU_SOURCE=1", languages = "cxx11"})

c++类型的检测,见:lib.detect.has_cxxtypes

检测c/c++代码片段是否能够编译通过

通用的c/c++代码片段检测接口,通过传入多个代码片段列表,它会自动生成一个编译文件,然后常识对它进行编译,如果编译通过返回true。

对于一些复杂的编译器特性,连compiler.has_features都无法检测到的时候,可以通过此接口通过尝试编译来检测它。

import("lib.detect.check_cxsnippets")

local ok = check_cxsnippets("void test() {}")
local ok = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})

此接口是detect.has_cfuncs, detect.has_cincludesdetect.has_ctypes等接口的通用版本,也更加底层。

因此我们可以用它来检测:types, functions, includes 还有 links,或者是组合起来一起检测。

第一个参数为代码片段列表,一般用于一些自定义特性的检测,如果为空,则可以仅仅检测可选参数中条件,例如:

local ok = check_cxsnippets({}, {types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}})

上面那个调用,会去同时检测types, includes和funcs是否都满足,如果通过返回true。

更加强大的xmake lua插件

2.1.4版本的时候,此插件就已经支持REPL(read-eval-print),实现交互式运行来方便测试模块:

$ xmake lua
> 1 + 2
3

> a = 1
> a
1

> for _, v in pairs({1, 2, 3}) do
>> print(v)
>> end
1
2
3

现在可以通过一行命令,更加快速地测试模块接口:

$ xmake lua lib.detect.find_package openssl

返回结果如下:{links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}}

预编译头文件支持

xmake新增通过预编译头文件去加速c/c++程序编译,目前支持的编译器有:gcc, clang和msvc。

使用方式如下:

target("test")
    set_precompiled_header("header.h")

通常情况下,设置c头文件的预编译,这需要加上这个配置即可,如果是对c++头文件的预编译,改成:

target("test")
    set_precompiled_header("header.hpp")

其中的参数指定的是需要预编译的头文件路径,相对于当前xmake.lua所在的目录。

如果只是调用xmake命令行进行直接编译,那么上面的设置足够了,并且已经对各个编译器进行支持,但是有些情况下,上面的设置还不能满足需求:

  1. 如果要使用xmake project工程插件生成vs工程文件,那么还缺少一个类似stdafx.cpp的文件(上面的设置在msvc编译的时候会自动生成一个临时的,但是对IDE工程不友好)。
  2. 如果gcc/clang下,header.h想作为c++的预编译头文件就不支持了,除非改成header.hpp(默认会当做c头文件进行预编译)。

因此为了更加地通用跨平台,可以在工程里面创建一个类似vc中stdafx.cpp的源文件:header.cpp

target("test")
    set_precompiled_header("header.h", "header.cpp")

header.cpp的内容如下:

#include "header.h"

上面的设置,就可以很好地处理各种情况下的预编译处理,追加的header.cpp也告诉了xmake:header.h是作为c++来预编译的。

相对于经典的vc工程中的stdafx.cppstdafx.h,也能完美支持:

target("test")
    set_precompiled_header("stdafx.h", "stdafx.cpp")

生成compiler_commands插件

扩展xmake project工程生成插件,支持compiler_commands.json文件输出,用于导出每个源文件的编译信息,生成基于clang的编译数据库文件,json格式,可用于跟ide,编辑器,静态分析工具进行交互。

$ xmake project -k compile_commands

输出的内容格式如下:

[
{ "directory": "/home/user/llvm/build",
"command": "/usr/bin/clang++ -Irelative -DSOMEDEF="With spaces

总结

以上是脚本宝典为你收集整理的

quotes and \-es.”” -c -o file.o file.cc””

全部内容,希望文章能够帮你解决

quotes and \-es.”” -c -o file.o file.cc””

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过