首页 > 其他 > 详细

学习cmake实践t6:自定义FindHELLO模块并使用这个模块构建工程时遇到的问题与解决方法

时间:2021-02-25 10:08:57      阅读:22      评论:0      收藏:0      [点我收藏+]

一、首先介绍cmake实践中的做法

在/backup/cmake/目录中建立t6目录,并在其中建立cmake 目录用于存放我们自己定义的FindHELLO.cmake模块,同时建立src目录,用于存放我们的源文件。

1,定义 cmake/FindHELLO.cmake模块

 1 FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello/usr/local/include/hello)
 2 FIND_LIBRARY(HELLO_LIBRARY NAMES hello PATH /usr/lib/usr/local/lib)
 3 IF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
 4     SET(HELLO_FOUND TRUE)
 5 ENDIF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
 6 IF (HELLO_FOUND)
 7     IF (NOT HELLO_FIND_QUIETLY)
 8         MESSAGE(STATUS "Found Hello: ${HELLO_LIBRARY}")
 9     ENDIF (NOT HELLO_FIND_QUIETLY)
10 ELSE (HELLO_FOUND)
11     IF (HELLO_FIND_REQUIRED)
12         MESSAGE(FATAL_ERROR "Could not find hello library")
13     ENDIF (HELLO_FIND_REQUIRED)
14 ENDIF (HELLO_FOUND) 

以上代码为CMake Practice中的做法,1~2行首先查找之前的例子t3中安装的头文件和库文件,3~5行若查找结果为真,设置HELLO_FOUND的值为TRUE。6~14行则是根据查找结果输出是否查找到hello库文件的消息。

2,建立src/main.c和该文件夹下的CMakeLists.txt

src/main.c中的内容为

1 #include <hello.h>
2 int main()
3 {
4     HelloFunc();
5     return 0;
6 }

建立src/CMakeLists.txt 文件,内容如下:

1 FIND_PACKAGE(HELLO)
2 IF(HELLO_FOUND)
3     ADD_EXECUTABLE(hello main.c)
4     INCLUDE_DIRECTORIES(${HELLO_INCLUDE_DIR})
5     TARGET_LINK_LIBRARIES(hello ${HELLO_LIBRARY})
6 ENDIF(HELLO_FOUND)

为了能够让工程找到FindHELLO.cmake模块(存放在工程中的 cmake目录),我们在主工程文件CMakeLists.txt 中加入:
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

3,使用自定义的FindHELLO 模块构建工程,仍然采用外部编译的方式,建立build 目录,进入目录运行:cmake ..

我们可以从输出中看到:Found Hello: /usr/lib/libhello.so

接下来就可以使用make命令构建工程,运行:
./src/hello可以得到输出:Hello World。
说明工程成功构建。

二、下面介绍我遇到的问题和解决方法

由于本人在t3的例子中安装路径为自定义的路径,因此我最初将1~2行中的路径改为了自定义的路径,然后构建工程,但是遇到了以下三个问题。

第1个问题:

CMake Warning at src/CMakeLists.txt:3 (find_package):
  By not providing "FindHELLO.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "HELLO", but
  CMake did not find one.

  Could not find a package configuration file provided by "HELLO" with any of
  the following names:

    HELLOConfig.cmake
    hello-config.cmake

  Add the installation prefix of "HELLO" to CMAKE_PREFIX_PATH or set
  "HELLO_DIR" to a directory containing one of the above files.  If "HELLO"
  provides a separate development package or SDK, be sure it has been
  installed.

通过查阅网上的资料我找到了问题所在,这是由于主工程文件CMakeLists.txt 中SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)放在了add_subdirectory(src)位置的后面,导致src文件夹中的CMakeLists.txt文件查找HELLO时没有指定FindHELLO.cmake,因此将SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)放在add_subdirectory(src)之前即可。

第2个问题:

src/CMakeLists.txt 文件中的IF(HELLO_FOUND)始终没有成立,导致工程始终无法构建成功。如下图所示,首先cmake ..时没有提示“Found Hello: ${HELLO_LIBRARY}”或者"Could not find hello library",其次make时没有任何反应。

技术分享图片

 

 

 

追溯到FindHELLO.cmake文件中,我认为是最开始查找路径没有成功,导致HELLO_FOUND变量没有设置为TRUE。经过一番周折,一个偶然的尝试我发现将cmake/FindHELLO.cmake模块中的1~2行修改为下面这两行的格式,其他的保持不变可以解决这个问题(其中的路径为自定义的头文件和库文件安装路径)。

1 FIND_PATH(HELLO_INCLUDE_DIR hello.h  /home/lwl/cmakepractice/include/hello)
2 FIND_LIBRARY(HELLO_LIBRARY hello  /home/lwl/cmakepractice/lib)

第3个问题:

当完成上述的内容后,我以为已经无误了,但是仍面临最后一个问题,这个问题是由于自定义安装位置引起的,在此前的CMake Practice案例中我也遇到过一次,因此仍有印象。

具体的问题表现为下图

技术分享图片

 

 

 这是由于src/CMakeLists.txt 文件中没有链接成功引起的,但如果按照作者的安装路径理论上没什么问题,由于我的安装路径为/home/lwl/cmakepractice/lib,属于非标准的共享库搜索路径,需要用到作者在t4中介绍的一个指令LINK_DIRECTORIES(directory1 directory2 ...)将该路径添加到src/CMakeLists.txt 文件中,因此修改后的此文件内容为

1 link_directories(/home/lwl/cmakepractice/lib)
2 find_package(HELLO)
3 if(HELLO_FOUND)
4     include_directories(${HELLO_INCLUDE_DIR})
5     add_executable(main main.cpp)
6     target_link_libraries(main libhello.so)
7     message(STATUS "HELLO library has found")
8 endif(HELLO_FOUND)

删除掉之前编译的中间文件,再次进入到build文件夹进行cmake ..

技术分享图片

 

 可以看到提示Found Hello:/home/lwl/cmakepractice/lib/libhello.so。同时make成功,正确输出“Hello World!”。

至此问题全部解决。

学习cmake实践t6:自定义FindHELLO模块并使用这个模块构建工程时遇到的问题与解决方法

原文:https://www.cnblogs.com/54lwl/p/14444332.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!