Cmake:如何构建自定义编译器二进制文件,然后将其用于某些目标? 我需要建立一个自定义的C++编译器二进制,然后将它用于项目中的一些目标。

Cmake:如何构建自定义编译器二进制文件,然后将其用于某些目标? 我需要建立一个自定义的C++编译器二进制,然后将它用于项目中的一些目标。,c++,cmake,C++,Cmake,在现代CMake中,最好的方法是什么 我从编译器目标中设置了一个依赖项,它按预期工作,但接下来呢,使用“生成器表达式”获取编译器目标二进制名称 set(CMAKE\u CXX\u编译器…——要么它不理解生成器表达式,要么我不知何故误用了它 有没有办法只为特定目标设置编译器?据我所知,set(CMAKE\u CXX\u编译器)适用于当前目录及其子目录。您可以使用工具链文件,该文件用于指定交叉编译器 下面是我从文档中获取的一个示例: set(CMAKE_SYSTEM_NAME Linux) set(

在现代CMake中,最好的方法是什么

我从编译器目标中设置了一个依赖项,它按预期工作,但接下来呢,使用“生成器表达式”获取编译器目标二进制名称

set(CMAKE\u CXX\u编译器…
——要么它不理解生成器表达式,要么我不知何故误用了它


有没有办法只为特定目标设置编译器?据我所知,
set(CMAKE\u CXX\u编译器)
适用于当前目录及其子目录。

您可以使用工具链文件,该文件用于指定交叉编译器

下面是我从文档中获取的一个示例:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)

set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
这没关系,因为它在工具链文件中。CMake用于正确处理工具链文件

您可以通过在命令行参数中指定它来使用它:

cmake .. -DCMAKE_TOOLCHAIN_FILE=your_toolchain.cmake

可以使用工具链文件,该文件用于指定交叉编译器

下面是我从文档中获取的一个示例:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(CMAKE_STAGING_PREFIX /home/devel/stage)

set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
这没关系,因为它在工具链文件中。CMake用于正确处理工具链文件

您可以通过在命令行参数中指定它来使用它:

cmake .. -DCMAKE_TOOLCHAIN_FILE=your_toolchain.cmake

我为一个样例应用程序(<代码> APP/APP.cc)使用非C++源代码(<代码> APP/TEXT.TXT</代码>),它必须通过中间C++源编译。 示例目录树:

└┬─ ./
├─── CMakeLists.txt
├─┬─ 应用程序/
│ ├─── CMakeLists.txt
│ ├─── app.cc
│ └─── text.txt
└─┬─ 工具/
├─── CMakeLists.txt
└─── tool.cc
文件
/CMakeLists.txt
是主项目文件(为VisualStudio提供解决方案):

<源代码>代码> //Too/Too.C.<代码>代码,用于生成C++源和文本文件的头:

// a sample tool converting a text file to a c++ source

#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char **argv)
{
  if (argc < 3) {
    std::cerr <<
      "ERROR in tool: Missing arguments!\n"
      "\n"
      "Usage:\n"
      "tool TXT_FILE CC_FILE\n";
    return -1;
  }
  std::ifstream fIn(argv[1]);
  if (!fIn.good()) {
    std::cerr << "ERROR: Cannot open '" << argv[1] << "' for reading!\n";
    return -1;
  }
  const std::string fileH = std::string(argv[2]) + ".h";
  std::ofstream fOutH(fileH);
  if (!fOutH.good()) {
    std::cerr << "ERROR: Cannot open '" << fileH << "' for writing!\n";
    return -1;
  }
  const std::string fileCC = std::string(argv[2]) + ".cc";
  std::ofstream fOutCC(fileCC);
  if (!fOutCC.good()) {
    std::cerr << "ERROR: Cannot open '" << fileCC << "' for writing!\n";
    return -1;
  }
  fOutCC << "#include \"" << fileH << "\"\n\n";
  for (std::string buffer; std::getline(fIn, buffer);) {
    const size_t i = buffer.find('=');
    if (i < buffer.size()) {
      fOutH << "extern const char *const " << buffer.substr(0, i) << ";\n";
      fOutCC << "const char *const " << buffer.substr(0, i)
        << " = \"" << buffer.substr(i + 1) << "\";\n";
    }
  }
  fOutH.close();
  if (!fOutH.good()) {
    std::cerr << "ERROR: Couldn't complete writing of '" << fileH << "'!\n";
    return -1;
  }
  fOutCC.close();
  if (!fOutCC.good()) {
    std::cerr << "ERROR: Couldn't complete writing of '" << fileCC << "'!\n";
    return -1;
  }
  return 0;
}
文件
/App/text.txt
——一个必须转换为生成源
text.cc
text.h
的文本文件:

text1=你好,世界。
text2=使用工具->VC生成的文本++
源代码
/App/App.cc
,其中包含
text.h

// a sample app using an indirect built source file

#include <iostream>

#include "text.h"

int main()
{
  std::cout << "text1: '" << text1 << "'\n";
  std::cout << "text2: '" << text2 << "'\n";
  return 0;
}
add_custom_命令
中使用
依赖工具
add_custom_命令
中的
输出
授予:

  • test.txt
    app的VS项目中被列为源代码
  • VS项目
    工具
    包含在VS解决方案
    应用程序中
  • 编译并链接
    tool
    ,然后在编译并链接
    app
    之前(成功)将
    test.txt
    转换为
    test.h
    test.cc
  • 生成的中间源显示在生成目录中(不要污染源目录)。因此,构建目录也必须设置为包含路径。否则,<>代码>包括“文本.h”/COD>(在<代码> App.cc>代码>中不起作用。< /P> < P>我用非C++源代码(<代码> APP/TeX.t/<代码>)编写了一个示例应用程序(<代码> APP/App.cc>代码>),该代码必须通过中间C++源编译。 示例目录树:

    └┬─ ./
    ├─── CMakeLists.txt
    ├─┬─ 应用程序/
    │ ├─── CMakeLists.txt
    │ ├─── app.cc
    │ └─── text.txt
    └─┬─ 工具/
    ├─── CMakeLists.txt
    └─── tool.cc
    
    文件
    /CMakeLists.txt
    是主项目文件(为VisualStudio提供解决方案):

    <源代码>代码> //Too/Too.C.<代码>代码,用于生成C++源和文本文件的头:

    // a sample tool converting a text file to a c++ source
    
    #include <fstream>
    #include <iostream>
    #include <string>
    
    int main(int argc, char **argv)
    {
      if (argc < 3) {
        std::cerr <<
          "ERROR in tool: Missing arguments!\n"
          "\n"
          "Usage:\n"
          "tool TXT_FILE CC_FILE\n";
        return -1;
      }
      std::ifstream fIn(argv[1]);
      if (!fIn.good()) {
        std::cerr << "ERROR: Cannot open '" << argv[1] << "' for reading!\n";
        return -1;
      }
      const std::string fileH = std::string(argv[2]) + ".h";
      std::ofstream fOutH(fileH);
      if (!fOutH.good()) {
        std::cerr << "ERROR: Cannot open '" << fileH << "' for writing!\n";
        return -1;
      }
      const std::string fileCC = std::string(argv[2]) + ".cc";
      std::ofstream fOutCC(fileCC);
      if (!fOutCC.good()) {
        std::cerr << "ERROR: Cannot open '" << fileCC << "' for writing!\n";
        return -1;
      }
      fOutCC << "#include \"" << fileH << "\"\n\n";
      for (std::string buffer; std::getline(fIn, buffer);) {
        const size_t i = buffer.find('=');
        if (i < buffer.size()) {
          fOutH << "extern const char *const " << buffer.substr(0, i) << ";\n";
          fOutCC << "const char *const " << buffer.substr(0, i)
            << " = \"" << buffer.substr(i + 1) << "\";\n";
        }
      }
      fOutH.close();
      if (!fOutH.good()) {
        std::cerr << "ERROR: Couldn't complete writing of '" << fileH << "'!\n";
        return -1;
      }
      fOutCC.close();
      if (!fOutCC.good()) {
        std::cerr << "ERROR: Couldn't complete writing of '" << fileCC << "'!\n";
        return -1;
      }
      return 0;
    }
    
    文件
    /App/text.txt
    ——一个必须转换为生成源
    text.cc
    text.h
    的文本文件:

    text1=你好,世界。
    text2=使用工具->VC生成的文本++
    
    源代码
    /App/App.cc
    ,其中包含
    text.h

    // a sample app using an indirect built source file
    
    #include <iostream>
    
    #include "text.h"
    
    int main()
    {
      std::cout << "text1: '" << text1 << "'\n";
      std::cout << "text2: '" << text2 << "'\n";
      return 0;
    }
    
    add_custom_命令
    中使用
    依赖工具
    add_custom_命令
    中的
    输出
    授予:

  • test.txt
    app的VS项目中被列为源代码
  • VS项目
    工具
    包含在VS解决方案
    应用程序中
  • 编译并链接
    tool
    ,然后在编译并链接
    app
    之前(成功)将
    test.txt
    转换为
    test.h
    test.cc

  • 生成的中间源显示在生成目录中(不要污染源目录)。因此,构建目录也必须设置为包含路径。否则,<>代码>包含“文本.h”/COD>(在<代码> App.cc>代码>中不起作用。< /p>您是否试图编译编译器,然后使用编译器在同一个项目中进行后续编译?自定义C++编译器是如何编译的?我担心如果它是C++代码本身,事情会变得复杂。我会使用<代码> ExcUTETyPrime<代码>来启动单独的<代码> Cuffs<代码>编译作业。然后另一个启动主
    cmake
    ,传递任何必需的参数和工具链文件(可能已生成,因为您现在知道第一个cmake的二进制目录)。@Gardener,是的,构建一个编译器(实际上只是一个命令行shell),然后在同一项目中进行后续编译,但是,对于不同的目标。@ Scheff,编译器本身只是一个命令行shell,不是真正的编译器,所以它不是那么复杂)你是在编译编译器,然后使用编译器在同一个项目中进行后续编译吗?编译的C++编译器是如何编译的?如果它是C++代码本身,事情会变得复杂。我会使用<代码> ExcUTETyPrime<代码>来启动单独的<代码> cMeave/Cudio>