【问题标题】:CMake Adding Headers to ProjectfileCMake将标题添加到项目文件
【发布时间】:2014-02-09 03:25:05
【问题描述】:

好的,我的根目录/CMakeLists.txt 中有以下代码。

cmake_minimum_required(VERSION 2.8)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release CACHE STRING "Debug or Release" FORCE)
endif()

if(CMAKE_CONFIGURATION_TYPES)
    set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configurations" FORCE)
    mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
endif()

execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory install)
SET(CMAKE_INSTALL_PREFIX install)

project(efge)

# include
add_definitions(-DEFGE_EXPORTS)
include_directories("${CMAKE_SOURCE_DIR}/include/EFGE/"
            "${CMAKE_SOURCE_DIR}/include/EFGE/Math"
            "${CMAKE_SOURCE_DIR}/include/EFGE/System")

# preconf
set(EFGE_SHARED_LIBS TRUE CACHE BOOL "Shared libraries (needs shared SFML libraries, too)")

if(WIN32)
    set(EFGE_STATIC_STD_LIBS FALSE CACHE BOOL "Statically linked runtime/standard libraries? Must match with SFML-Option.")
    if(EFGE_STATIC_STD_LIBS)
        if(EFGE_SHARED_LIBS)
            message("\nEFGE_STATIC_STD_LIBS and EFGE_SHARED_LIBS aren\'t compatible!")
        elseif(MSVC)
            foreach(flag CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
                if(${flag} MATCHES "/MD")
                    string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
                endif()
            endforeach()
        elseif(CMAKE_COMPILER_IS_GNUCXX)
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
        endif()
    endif()
endif()

if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CSS_FLAGS} -std=c++0x")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++")
    add_definitions(-DEFGE_USE_STD_RANDOMENGINE)
endif()

set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules/;${CMAKE_MODULE_PATH}")

if(NOT EFGE_SHARED_LIBS)
    set(SFML_STATIC_LIBRARIES TRUE)
endif()
find_package(SFML 2 COMPONENTS audio graphics window system)

if(SFML_FOUND)
    include_directories(${SFML_INCLUDE_DIR})
else()
    set(SFML_ROOT "" CACHE PATH "SFML top-level directory")
    message("\n SFML directory not found. Please set SFML_ROOT to SFML top-level path, wich contains /include/ and /lib/ directories.")
    message("Make sure SFML libraries have the same configuration.")
endif()

# linking sfml
macro(efge_link_sfml EFGE_TARGET)
    target_link_libraries(${EFGE_TARGET} ${SFML_LIBRARIES})
endmacro()
macro(efge_link_sfml_dependencies EFGE_TARGET)
    target_link_libraries(${EFGE_TARGET} ${SFML_DEPENDENCIES})
endmacro()

macro(efge_link_efge EFGE_TARGET)
    target_link_libraries(${EFGE_TARGET} efge)
endmacro()

# source
add_subdirectory(src)

# include
install(DIRECTORY include
        DESTINATION .)

如果这很重要,我的文件结构如下:

+-- include
       +-- Math
            +--- *.hpp files
       +-- System
            +--- *.hpp files
       +--- *.hpp files
+-- src
     +--- *.cpp files
     +--- CMakeLists.txt
+--- CMakeLists.txt

如何将标头添加到我生成的项目文件(例如 CodeBlocks)中? Makefile 似乎工作正常。像set_group 这样的东西不会影响项目文件。 我想不通,第一次使用 CMake。谢谢!

【问题讨论】:

  • 通常 CMake 不会对头文件做任何事情(不像 MSVC 明确列出它们),它在 include_directories 级别上运行。您可以另外提及它们,例如形成正确的安装顺序。您需要它们用于哪些目的?
  • 我刚刚在另一个添加的项目中看到了它们,并认为这是有必要的。 CMake 是否会做一些特殊的事情以使其变得不必要?
  • 好吧,从技术上讲,构建系统只传递给编译器的源文件 (.c/.cpp) 和包含目录,其余部分由编译器本身执行(更准确地说,它的预处理器,cpp )。安装阶段可能需要稍后的头文件,您可能需要在install CMake 指令中指定它们。正如我之前所说,各种 IDE 不同地对待/显示项目文件和其他实体。例如 KDevelop 和 Eclipse CDT 显示位于项目目录中的所有文件。
  • 而 Code::Blocks 根本就没有?这是一种奇怪的行为......

标签: cmake


【解决方案1】:

我刚刚检查了以下组合:

  1. CMake 2.8.12.1
  2. 代码块 13.12

CodeBlocks 项目生成如下:

mkdir build
cd build
cmake -G 'CodeBlocks - Unix Makefiles' ..

我确实看到生成器生成了一个 .cbp 文件,其中列出了所有头文件。因此您可以查看 .cbp 文件并检查是否列出了头文件。如果不是,那么您应该检查您的 CMake 是否足够新鲜。

更新

啊哈,我明白了。看来我已经用生成器重现了您的问题。这是最小的非工作示例:

project/
   CMakeLists.txt
   src/
        CMakeLists.txt
        test.cpp
   include/test.h

项目/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)

project(TestProject)

include_directories(include)

add_subdirectory(src)

项目/src/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)

project(TestProjectSources)

set(SOURCES test.cpp)

add_executable(test ${SOURCES})

项目/src/test.cpp

#include "test.h"

int main(void) {
    TestRun r;
    r.run();
    return 0;
}

项目/包含/test.h:

#ifndef _TEST_H_
#define _TEST_H_

#include <iostream>

class TestRun {
public:
    TestRun() { std::cout << "Hello World!" << std::endl; }
    void run() { std::cout << "Doing something useful" << std::endl; }
};

#endif // _TEST_H_

在这种情况下,生成器生成没有任何头文件的 TestProject.cbp。让我们看看如何解决这个问题。

Update2:好吧,我有一些坏消息要告诉你。不幸的是,负责搜索和添加头文件的 CodeBlocks 生成器的代码块太简单,无法正确处理您的情况。这是来自 CMake 来源的 Source/cmExtraCodeBlocksGenerator.cxx 的评论:

// The following loop tries to add header files matching to implementation
// files to the project. It does that by iterating over all source files,
// replacing the file name extension with ".h" and checks whether such a
// file exists. If it does, it is inserted into the map of files.
// A very similar version of that code exists also in the kdevelop
// project generator.

因此,您可能会看到这种方法只有在 test.cpptest.h 并排位于一个目录中时才有用。所以这是进一步改进的方向。我可以建议与此论坛帖子http://forums.codeblocks.org/index.php?topic=16892.0 的人联系,并讨论如何改善这种情况。也许在项目生成中涉及gcc -MM -I&lt;include directories&gt; test.cpp 调用是合理的,但是这种方法很昂贵,并且如果目前无法编译代码可能很容易中断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多