使用带cmake的常量文件夹

时间:2015-11-17 13:57:56

标签: cmake

我的MYPROJECT文件中有一个常量~/.bashrc

export MYPROJECT = /home/loom/my_project

我可以看到在终端中定义了常量:

loom@loom$ ls -ld $MYPROJECT
drwxr-xr-x 25 loom loom 4096 Jul 21 22:12 /home/loom/my_project

我尝试在CMakeLists.txt中使用常量:

add_executable(booo src/main.cpp ${MYPROJECT}/foo/trunk/bar/File.h)

然而,它会产生错误:

CMake Error at CMakeLists.txt:17 (add_executable):
  Cannot find source file:

    /foo/trunk/bar/File.h

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx


CMake Error: CMake can not determine linker language for target: booo
CMake Error: Cannot determine link language for target "booo".

如果我使用了没有$MYPROJECT的显式路径:

,则处理时没有错误
add_executable(booo src/main.cpp /home/loom/my_project/foo/trunk/bar/File.h)

如何在cmake中使用.bashrc中定义的路径?

2 个答案:

答案 0 :(得分:2)

而不是

add_executable(booo src/main.cpp ${MYPROJECT}/foo/trunk/bar/File.h)

使用

add_executable(booo src/main.cpp $ENV{MYPROJECT}/foo/trunk/bar/File.h)

CMake文档声明:

  

使用语法$ ENV {VAR}来读取环境变量VAR。也可以看看   set()命令设置ENV {VAR}。

https://cmake.org/cmake/help/v3.4/variable/ENV.html

答案 1 :(得分:2)

将我的评论转化为答案

在CMake中有很多方法可以做到这一点。在CMake项目中直接使用环境变量的糟糕经验(它们不仅必须在第一次调用CMake配置/生成期间有效,而且在以后的所有连续生成期间都有效),我建议将常量转换为缓存的CMake变量

我在我的项目中使用以下方法之一:

  1. 通过-D option注入MYPROJECT CMake,例如

    cmake -DMYPROJECT:PATH=$MYPROJECT .. 
    

    然后CMake会将此值缓存在自己的MYPROJECT内部变量中。

  2. 当您从"外部"获得价值时如果没有提供任何价值或者它不是有效目录,您应该考虑该怎么做。抛出致命错误和/或使用默认值重试?

    以下示例仅显示转换步骤和完整性检查(无默认值重试):

    if (NOT DEFINED MYPROJECT OR NOT IS_DIRECTORY MYPROJECT)
        file(TO_CMAKE_PATH "$ENV{MYPROJECT}" _ENV_MYPROJECT_REL)
        get_filename_component(_ENV_MYPROJECT "${_ENV_MYPROJECT_REL}" ABSOLUTE)
        if (NOT _ENV_MYPROJECT)
            message(FATAL_ERROR "Environment variable MYPROJECT not provided.")
        else()
            set(MYPROJECT "${_ENV_MYPROJECT}" CACHE INTERNAL "")
        endif()
    endif()
    
  3. 使用find_path(),它也会缓存其结果:

    find_path(
        MYPROJECT_INCLUDE_DIR 
            NAMES File.h
            PATHS ENV MYPROJECT
                  /home/loom/my_project
            PATH_SUFFIXES foo/trunk/bar
    )
    if (NOT MYPROJECT_INCLUDE_DIR)
        ...
    
  4. 或者 - 假设您的外部项目不仅包含头文件,还包含foo.a之类的库 - 遵循CMake A Sample Find Module并扩展find_path()代码上面的:

    find_library(
         MYPROJECT_LIBRARY
            NAMES foo
            PATHS ENV MYPROJECT
            PATH_SUFFIXES foo/lib
    )        
    
    if(MYPROJECT_INCLUDE_DIR AND MYPROJECT_LIBRARY AND NOT TARGET MyProject::MyProject)
        add_library(MyProject::MyProject UNKNOWN IMPORTED)
        set_target_properties(
            MyProject::MyProject 
            PROPERTIES
                IMPORTED_LOCATION "${MYPROJECT_LIBRARY}"
                INTERFACE_INCLUDE_DIRECTORIES "${MYPROJECT_INCLUDE_DIR}"
        )
    endif()
    

    现在您可以将其直接用作

    的任何其他CMake目标
    add_executable(booo src/main.cpp)
    target_link_libraries(booo MyProject::MyProject)
    
  5. 更多参考资料