[✔️]cmake command 无法使用通配符匹配文件,只能检索下目录指定文件

360 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

问题背景

工程中使用了第三方库,在编译链接阶段,lib是不可缺少的,有2种方式可以保证编译链接的正常:

  • lib必须copy到库引用目录
  • 引用lib的绝对路径也行

但是当程序运行的时候,使用的是对应的dll,所以必须将对应的dll放在应用程序目录。

实际举例

比如cocos2dx使用的curl,在cmake中通过target_link_libraries引用lib的绝对路径

image.png

而对于dll,在非CMAKE生成的win32工程里面,是在生成事件里面配置了copy dll的逻辑,在copy的时候,是将整个目录copy了过去。

因为是手动配置的生成事件,并且里面可以使用bat脚本,而bat脚本是支持通配符的,所以我惊奇的发现,debug、release的生成事件是有差异的,这里就比较坑了,细节的配置。

这篇文章详细介绍如何解决cmake项目dll、lib的copy的问题,但是发布release版本的时候,只需要dll就行了,增加lib只会占用软件的包体。

比如上边的win32目录,但是这个目录里面同时包含了lib、dll,如果Command支持通配符的话,那么就没有后续问题了。

CMAKE的COMMAND大部分都是不支持通配符匹配的

add_custom_commandCOMMANDcopy_directoryremove都是不支持通配符的

解决办法

因为编译链接使用的lib是绝对路径,所以exe同目录有没有lib都不会影响编译。

要想exe同目录不出现lib,解决思路有:

  1. 不进行整个目录的copy,改用copy file
  2. 如果copy目录后,删除相应的lib

我这里选择了第二种方式,因为lib文件比较多,所以编写了个nodejs脚本处理:

const fs = require("fs")
const path = require("path")
const result = fs.readdirSync(__dirname)
let arr = [];
for (let i = 0; i < result.length; i++) {
    const r = result[i];
    const ext = path.extname(r)
    if (ext === '.lib') {
        arr.push(r);
    }

}
arr = arr.map(item => `$(outdir)${item}`);
console.log(arr.join(" "))

目前暂时没有找到更好的办法。