程序编译安装与卸载
本文最后更新于 2025年2月19日 上午
本文主要分享了程序编译、安装与卸载的知识点。
编写CmakeLists.txt
在CmakeLists.txt里指定第三方库所在的路径
在CmakeLists.txt
里指定第三方库所在的路径,即指定其编译安装后.cmake
文件所在的路径,例如:
1 |
|
1
find_library(flowfilter_gpu_LIBS NAMES flowfilter_gpu PATHS /usr/local/include)
首先,
set(OpenCV_DIR /usr/local/opencv/opencv345/share/OpenCV)
这行代码设置了一个变量OpenCV_DIR
,它指向OpenCV库的安装位置。在这个例子中,OpenCV库被安装在/usr/local/opencv/opencv345/share/OpenCV
这个路径下。OpenCV_DIR
这个变量通常用于指定OpenCV的cmake配置文件的位置,这个文件包含了OpenCV库的版本信息、编译选项等信息。然后,
find_package(OpenCV REQUIRED)
这行代码告诉CMake去查找OpenCV库。REQUIRED
关键字表示如果CMake不能找到OpenCV库,那么CMake应该停止配置过程并显示错误信息。如果CMake成功找到了OpenCV库,那么它将设置一些变量,例如OpenCV_INCLUDE_DIRS
和OpenCV_LIBS
,这些变量分别包含了OpenCV的头文件路径和库文件路径,可以在后续的target_include_directories
和target_link_libraries
命令中使用。
如果没有设置
OpenCV_DIR
,find_package
命令会在默认的路径下查找OpenCV库。这些默认的路径包括:
- CMake的模块路径(
CMAKE_MODULE_PATH
)- CMake的安装前缀(
CMAKE_PREFIX_PATH
)- 系统的环境变量路径
具体来说,
find_package
会查找名为OpenCVConfig.cmake
或opencv-config.cmake
的文件,这个文件通常位于OpenCV库的安装目录中。如果你的OpenCV库安装在非标准的位置,或者你有多个版本的OpenCV库并且想要选择一个特定的版本,那么你可以通过设置
OpenCV_DIR
来指定OpenCV库的路径。如果没有设置OpenCV_DIR
,CMake可能会找到错误的版本或者找不到OpenCV库。
OpenCV_DIR
和OpenCV_INCLUDE_DIR
是两个不同的变量,它们在CMake中的作用也不同。
OpenCV_DIR
是用于指定OpenCV的cmake配置文件位置的变量。find_package
命令会使用OpenCV_DIR
变量的值作为查找OpenCV配置文件的起始路径。如果OpenCV_DIR
被设置,find_package
就会直接在这个路径下查找配置文件,而不会在其他路径下查找。
OpenCV_INCLUDE_DIR
通常是find_package
命令找到OpenCV库后设置的一个变量,它包含了OpenCV的头文件路径。这个变量通常用于target_include_directories
命令,以便你的项目可以找到OpenCV的头文件。如果你设置了
OpenCV_INCLUDE_DIR
,而不是OpenCV_DIR
,然后调用find_package(OpenCV REQUIRED)
,那么find_package
命令可能无法找到正确的OpenCV库,因为它不知道在哪里查找OpenCV的配置文件。在这种情况下,find_package
命令可能会找到错误的OpenCV版本,或者找不到OpenCV库。find_package
命令找到的结果会覆盖你设置的OpenCV_INCLUDE_DIR
变量。总的来说,如果你想要指定OpenCV库的位置,你应该设置
OpenCV_DIR
,而不是OpenCV_INCLUDE_DIR
。
(在ROS中)编译第三方开源软件需要下载的问题
注意
CmakeList.txt
里有没有指定具体版本。在package.xml
里也可以看到指定的版本。
其实就类似于在系统中
cmake
、make
和make install
的步骤,只不过这里的第三方库是安装在了ROS工作区里被相互调用,catkin clean
后也就删除掉了,而没有安装在系统环境里。也方便使用指定版本的第三方库。
1 |
|
或者,将src
(这个文件是原本解压下载的第三方源码source的地方,具体名称要看CMakeLists.txt
中SOURCE_DIR的设置)中的各个第三方源码都解压好,放到src对应的文件夹中。例如catkin_ws/build/xxx/xxx_src-prefix/src/xxx.tar.gz
。
cmake
一般流程
1 |
|
我个人推荐把第三方库安装在
/usr/local
文件夹下进行管理。例如,在/usr/local
文件夹下新建文件夹eigen3
,后在eigen3
文件夹下新建文件夹eigen330
、eigen340
。
定义编译参数
可在cmake
命令后加参数:
1 |
|
也可以在CMakeLists.txt
文件中定义,例如,启用参数EFFT_USE_FFTW3
:
1 |
|
或,在CMakeLists.txt
文件中:
1 |
|
保存cmake输出
ROS:
cmake build
的输出在catkin_ws/logs/your_package_name/build.cmake.log、build.make.log
里。
cmake
命令的输出信息通常在终端中显示,而不是保存在文件中。这些信息包括配置过程中的警告、错误以及其他重要信息。
然而,你可以将cmake
命令的输出重定向到一个文件中。例如,你可以使用以下命令将输出保存到一个名为output.txt
的文件中:
1 |
|
在这个命令中,>
操作符将cmake
命令的输出重定向到output.txt
文件中。如果output.txt
文件已经存在,这个命令将覆盖它的内容。如果你想要追加输出到文件中,而不是覆盖它,你可以使用>>
操作符,如下所示:
1 |
|
请注意,这些命令只会捕获标准输出,而不会捕获错误输出。如果你也想要捕获错误输出,你可以使用2>&1
,如下所示:
1 |
|
在这个命令中,2>&1
将错误输出重定向到标准输出,然后>
操作符将标准输出重定向到output.txt
文件中。这样,output.txt
文件将包含所有的输出,包括错误信息。
make
1 |
|
cmake --install .
与make install
的区别:
cmake --install .
和make install
都是用来安装编译好的程序的命令,但它们在使用的构建系统和工作方式上有所不同。
make install
是GNU Make的命令,它依赖于Makefile中的install
目标。这个install
目标通常会将编译好的二进制文件、库文件、头文件等复制到系统的指定位置,如/usr/local/bin
、/usr/local/lib
等。这个命令通常在使用GNU Autotools或者手写Makefile的项目中使用。
cmake --install .
是CMake的命令,它会执行CMakeLists.txt文件中定义的安装规则。这个命令在CMake 3.15及以后的版本中可用,它是cmake -P cmake_install.cmake
的一个更简洁的替代。这个命令的好处是它不依赖于特定的构建系统,可以在任何CMake支持的构建系统中使用。总的来说,这两个命令的功能是类似的,但
cmake --install .
更加通用,不依赖于特定的构建系统。
卸载
如果因为反复./configure xx
然后make
会导致安装路径混乱,sudo make install
失败。所以如果路径设错了又已经make
完,需要make clean
来清除一下。如果想把自己刚刚make install
安装的卸载掉,可以在那个目录里直接用sudo make uninstall
。
1 |
|
make uninstall
是一个常见的 makefile 目标,它的主要作用是删除由make install
命令安装的文件。当你运行
make install
命令时,通常会将一些文件(例如可执行文件、库文件、头文件等)复制到系统的某些目录下(例如/usr/local/bin
、/usr/local/lib
等)。make uninstall
命令就是用来删除这些文件的。然而,需要注意的是,并不是所有的 makefile 都提供
make uninstall
目标。如果 makefile 没有提供这个目标,运行make uninstall
命令将会导致错误。在运行
make uninstall
命令之前,你应该查看 makefile 或者相关的文档,以确认这个命令是否可用,以及它会删除哪些文件。
cat install_manifest.txt | sudo xargs rm
和sudo make uninstall
都是用来删除由make install
命令安装的文件的。然而,它们的工作方式有所不同。
cat install_manifest.txt | sudo xargs rm
:这个命令会读取install_manifest.txt
文件,这个文件通常由make install
命令生成,包含了所有被安装的文件的列表。然后,它会使用xargs rm
命令删除这些文件。这个命令不依赖于 makefile,只要install_manifest.txt
文件存在,就可以使用。sudo make uninstall
:这个命令会执行 makefile 中的uninstall
目标。这个目标通常会删除所有被make install
命令安装的文件。然而,需要注意的是,并不是所有的 makefile 都提供uninstall
目标。如果 makefile 没有提供这个目标,运行sudo make uninstall
命令将会导致错误。总的来说,这两个命令的功能是相似的,但是
cat install_manifest.txt | sudo xargs rm
命令更为直接,不依赖于 makefile。而sudo make uninstall
命令则需要 makefile 提供uninstall
目标。
make clean
和make distclean
是两个常见的 makefile 目标,它们的功能取决于 makefile 的编写者如何定义它们。但是,通常它们的功能如下:
make clean
:这个命令通常用于删除所有由 makefile 生成的文件。这通常包括编译产生的对象文件(.o 或 .obj 文件)和编译器生成的中间文件。但是,它通常不会删除配置文件或者 makefile 文件。make distclean
:这个命令通常用于将目录恢复到初始状态。除了删除make clean
会删除的文件,它还会删除配置文件和 makefile 文件。这个命令通常在你想要重新配置和编译一个项目时使用。需要注意的是,这两个命令的具体行为取决于 makefile 的编写者。在使用这些命令之前,你应该查看 makefile 或者相关的文档,以了解这些命令的具体行为。