比如,我们可以在项目中,内嵌一些 png/jpg 资源文件到代码中。
target("console") set_kind("binart") add_rules("utils.bin2c", {extensions = {".png", ".jpg"}}) add_files("src/*.c") add_files("res/*.png", "res/*.jpg")注:extensions 的设置是可选的,默认后缀名是 .bin
然后,我们就可以通过 #include "filename.png.h" 的方式引入进来使用,xmake 会自动帮你生成对应的头文件,并且添加对应的搜索目录。
static unsigned char g_png_data[] = { #include "image.png.h" }; int main(int argc, char** argv) { printf("image.png: %s, size: %d\n", g_png_data, sizeof(g_png_data)); return 0; }生成头文件内容类似:
cat build/.gens/test/macosx/x86_64/release/rules/c++/bin2c/image.png.h 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x78, 0x6D, 0x61, 0x6B, 0x65, 0x21, 0x0A, 0x00 新增 iOS/macOS 应用 Metal 编译支持我们知道 xcode.application 规则可以编译 iOS/macOS 应用程序,生成 .app/.ipa 程序包,并同时完成签名操作。
不过之前它不支持对带有 .metal 代码的编译,而新版本中,我们新增了 xcode.metal 规则,并默认关联到 xcode.application 规则中去来默认支持 metal 编译。
xmake 会自动编译 .metal 然后打包生成 default.metallib 文件,并且自动内置到 .app/.ipa 里面。
如果用户的 metal 是通过 [_device newDefaultLibrary] 来访问的,那么就能自动支持,就跟使用 xcode 编译一样。
这里是我们提供的一个完整的:项目例子。
add_rules("mode.debug", "mode.release") target("HelloTriangle") add_rules("xcode.application") add_includedirs("Renderer") add_frameworks("MetalKit") add_mflags("-fmodules") add_files("Renderer/*.m", "Renderer/*.metal") ------- 添加 metal 文件 if is_plat("macosx") then add_files("Application/main.m") add_files("Application/AAPLViewController.m") add_files("Application/macOS/Info.plist") add_files("Application/macOS/Base.lproj/*.storyboard") add_defines("TARGET_MACOS") add_frameworks("AppKit") elseif is_plat("iphoneos") then add_files("Application/*.m") add_files("Application/iOS/Info.plist") add_files("Application/iOS/Base.lproj/*.storyboard") add_frameworks("UIKit") add_defines("TARGET_IOS")比如,在 macOS 上,编译运行后,就会通过 metal 渲染出需要的效果。
如果,我们的项目没有使用默认的 metal library,我们也可以通过上面提到的 utils.bin2c 规则,作为源文件的方式内嵌到代码库中,例如:
add_rules("utils.bin2c", {extensions = ".metal"}) add_files("Renderer/*.metal")然后代码中,我们就能访问了:
static unsigned char g_metal_data[] = { #include "xxx.metal.h" }; id<MTLLibrary> library = [_device newLibraryWithSource:[[NSString stringWithUTF8String:g_metal_data]] options:nil error:&error]; 改进 add_repositories如果我们通过内置在项目中的本地仓库,我们之前是通过 add_repositories("myrepo repodir") 的方式来引入。
但是,它并不像 add_files() 那样是基于当前 xmake.lua 文件目录的相对目录,也没有路径的自动转换,因此容易遇到找不到 repo 的问题。
因此,我么你改进了下它,可以通过额外的 rootdir 参数指定对应的根目录位置,比如相对当前 xmake.lua 的脚本目录。
add_repositories("myrepo repodir", {rootdir = os.scriptdir()}) os.cp 支持符号链接之前的版本,os.cp 接口不能很好的处理符号链接的复制,他会自动展开链接,复制实际的文件内容,只会导致复制后,符号链接丢失。
如果想要复制后,原样保留符号链接,只需要设置下参数:{symlink = true}
os.cp("/xxx/symlink", "/xxx/dstlink", {symlink = true}) 更方便地编译自动生成的代码有时候,我们会有这样一个需求,在编译前,自动生成一些源文件参与后期的代码编译。但是由于 add_files 添加的文件在执行编译时候,就已经确定,无法在编译过程中动态添加它们(因为需要并行编译)。
因此,要实现这个需求,我们通常需要自定义一个 rule,然后里面主动调用编译器模块去处理生成代码的编译,对象文件的注入,依赖更新等一系列问题。
这对于 xmake 开发者本身没什么大问题,但是对于用户来说,这还是比较繁琐了,不好上手。
新版本中,我们改进了对 add_files 的支持,并添加了 {always_added = true} 配置来告诉 xmake 我们始终需要添加指定的源文件,即使它还不存在。