CMake 支持“进行卸载”吗?

Posted

技术标签:

【中文标题】CMake 支持“进行卸载”吗?【英文标题】:CMake support "make uninstall"? 【发布时间】:2017-05-19 04:54:30 【问题描述】:

我正在尝试寻找一些sudo-free 解决方案,以使我的用户能够安装和卸载我的应用程序。使用

set(CMAKE_INSTALL_PREFIX "$ENVHOME/opt/$CPACK_PACKAGE_NAME-$CPACK_PACKAGE_VERSION/")
SET(CMAKE_INSTALL_RPATH "$ENVHOME/$CPACK_PACKAGE_NAME-$CPACK_PACKAGE_VERSION/")

我可以将文件定向到用户的主目录,并且

make install

工作正常。参考 What's the opposite of 'make install', ie. how do you uninstall a library in Linux? 我没有找到任何想法,这是sudo-free,对于非系统管理员来说并不复杂。

    CMake 是否支持make uninstall

    我的卸载非常简单:所有文件都放在用户主目录的子目录中。原则上,删除新的子目录可以解决问题。有make install,上面的参数,有什么副作用,或者我可以在我的用户指南中写下新生成的子目录可以作为“卸载”删除?

【问题讨论】:

可能重复:***.com/questions/19921017/… Cleaning CMake installed files的可能重复 【参考方案1】:

如果您想添加 卸载 目标,可以查看官方 CMake 常见问题解答

https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake

如果您只想快速卸载所有文件,只需运行:

xargs rm < install_manifest.txt

install_manifest.txt 文件在您运行 make install 时创建。

【讨论】:

但这只会删除文件而不是目录。如果你只有头文件和库,那没关系,但如果你安装了一个 python 包,你必须创建像/home/user/.local/miniconda3/envs/galario3/lib/python3.6/site-packages/galario/ 这样的目录。简单的xargs ... 不会删除它们,因此您必须手动添加逻辑,例如在uninstall 目标中 感谢您提供解决 cmake 众多明显愚蠢问题之一的方法。一个卸载目标很重要。【参考方案2】:

不,没有。见FAQ from CMake wiki:

默认情况下,CMake 不提供“make uninstall”目标,所以你 不能这样做。我们不希望“make uninstall”删除有用的文件 来自系统。

如果您想在项目中添加“卸载”目标, 那么没有人阻止你提供一个。您需要删除 install_manifest.txt 文件中列出的文件。 [后面是一些示例代码]

【讨论】:

我很高兴看到有人相信如果在开发过程中安装了一个文件,它将永远存在。感谢您的提示,我将使用示例代码。顺便说一句:我想你也回答了我的第二个问题:简单地删除包含文件的目录不会有副作用。【参考方案3】:

从 cmake 项目中删除 make install 添加的文件和文件夹(仅限空):

cat install_manifest.txt | sudo xargs rm
cat install_manifest.txt | xargs -L1 dirname | sudo xargs rmdir -p

第二个命令将打印一堆错误,因为它递归地删除文件夹,直到找到一个不为空的文件夹。我喜欢看到这些错误以了解留下了哪些文件夹。如果您想隐藏这些错误,您可以将--ignore-fail-on-non-empty 添加到 rmdir。

【讨论】:

似乎第一个命令中的 xargs 文件名中的 handle spaces 不正确。 是的,它需要一些调整来支持它。但至少好的一点是它只会出错,并且不会因为空格字符而删除一堆不相关的文件。 绝对不会!如果路径确实存在,它不会出错。示例:如果工作目录是 ~ 并且 xargs 传递了 /tmp/school work,则这将被解释为 /tmp/schoolwork。开心康复~/work! -- rm 如果发现它是一个目录,它可能会停止。 rm 不会如果它是一个目录则不会删除它。 rmdir 仅在它是空目录时删除。 (当然,除非你为这些命令做了一些别名)。所以我的评论仍然成立。它唯一可以删除的是与空格字符之间的确切名称匹配的单个文件。 AFAIK 使用xargs -I "" -- rm -- '' 应该可以解决空白问题【参考方案4】:

从源文件夹:

    打开 install_manifest.txt(由make install 创建)

    删除所有列出的目录/文件

    删除您遗漏的所有剩余文件:

    xargs rm &lt; install_manifest.txt

    删除所有隐藏的目录/文件:

    $rm -rf ~/.packagename

删除源文件夹。

【讨论】:

【参考方案5】:
# make uninstall
add_custom_target("uninstall" COMMENT "Uninstall installed files")
add_custom_command(
    TARGET "uninstall"
    POST_BUILD
    COMMENT "Uninstall files with install_manifest.txt"
    COMMAND xargs rm -vf < install_manifest.txt || echo Nothing in
            install_manifest.txt to be uninstalled!
)

将此添加到CMakeLists.txt,然后手动制作uninstall 目标。

【讨论】:

以上是关于CMake 支持“进行卸载”吗?的主要内容,如果未能解决你的问题,请参考以下文章

CMake可以生成配置文件吗?

linux里用cmake安装的软件要怎么卸载

cmake脚本模式支持啥,不支持啥

cmake编译后能给vs使用吗

CMake 中的 Cppcheck 支持

将vscode打造成无敌的IDE(11) vscode增加文件后缀类型的支持,例如cmake支持识别cmake.in