Как запустить make & amp; CMake программно

Я работаю над роботизированной симуляцией, и для управления роботом (в симуляции) мы должны написать код C ++ в файле с именем Plugin.

Для компиляции плагина мы используем CMake и пишем команды в терминале.

Теперь я хочу собрать множество плагинов (сотни) один за другим для тестирования лучшего контроллера с использованием генетических алгоритмов.

Я не могу сделать это вручную (то есть для каждого плагина, напишите команду CMake в терминале), поэтому я хочу написать код C ++, который скомпилирует все плагины.

-9

Решение

Я не уверен, что полностью понимаю ваш вопрос, но я получу ответ на вопрос 🙂

Вы можете создать новый проект C ++ для настройки с помощью CMake. CMake запишет все пути, необходимые для вашего кода C ++, в исходный файл C ++. Допустим, новый проект имеет следующую структуру:

/CMakeLists.txt
/PluginAlpha
/CMakeLists.txt
/...
/PluginBeta
/CMakeLists.txt
/...
/PluginGamma
/CMakeLists.txt
/...
/main.cpp

Ваш CMakeLists.txt верхнего уровня может сделать:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(Builder)

set(Plugins PluginAlpha PluginBeta PluginGamma)
foreach(Plugin ${Plugins})
set(Contents "${Contents}\n  {\"\\\"${CMAKE_BINARY_DIR}/Build${Plugin}\\\"\", \"\\\"${CMAKE_SOURCE_DIR}/${Plugin}\\\"\"},")
endforeach()
string(REGEX REPLACE ",$" "" Contents "${Contents}")

file(WRITE "${CMAKE_BINARY_DIR}/always_updated/paths.hpp" "#ifndef PATHS_HPP_
#define PATHS_HPP_

#include <array>
#include <string>
#include <vector>

const std::vector<std::array<std::string, 2>> paths = {${Contents}
};

#endif  // PATHS_HPP_
")
configure_file("${CMAKE_BINARY_DIR}/always_updated/paths.hpp" "${CMAKE_BINARY_DIR}/generated/paths.hpp" COPYONLY)

add_executable(Builder main.cpp "${CMAKE_BINARY_DIR}/generated/paths.hpp")
target_include_directories(Builder PRIVATE "${CMAKE_BINARY_DIR}/generated")

Таким образом, в рамках настройки проекта записывается заголовок C ++, который определяет набор путей сборки и исходных кодов для каждого из плагинов — например,

#ifndef PATHS_HPP_
#define PATHS_HPP_

#include <array>
#include <string>
#include <vector>

const std::vector<std::array<std::string, 2>> paths = {
{"\"E:/build/BuildPluginAlpha\"", "\"E:/PluginAlpha\""},
{"\"E:/build/BuildPluginBeta\"", "\"E:/PluginBeta\""},
{"\"E:/build/BuildPluginGamma\"", "\"E:/PluginGamma\""}
};

#endif  // PATHS_HPP_

Затем вы можете сделать так, чтобы main.cpp сделал что-то вроде:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

#include "paths.hpp"  // Generated by CMake during configuration

struct Results {
std::string plugin_id;
int configure_result, build_result;
};

int main() {
std::vector<Results> results;
for (const auto& p : paths) {
const std::string& build_folder = p[0];
const std::string& source_folder = p[1];

results.emplace_back();
results.back().plugin_id = source_folder;

std::string command = "cmake -B" + build_folder + " -H" + source_folder;
results.back().configure_result = std::system(command.c_str());

command = "cmake --build " + build_folder + " --config Release";
results.back().build_result = std::system(command.c_str());
}

std::cout << "\n\n";
for (const auto& r : results) {
std::cout << "Results for " << r.plugin_id << ":\n";
std::cout << "  configure result: " << r.configure_result << '\n';
std::cout << "  build result:     " << r.build_result << '\n';
}
return 0;
}

Теперь, если вы запустите программу «Builder», она должна настроить и собрать каждый из плагинов.

Это упрощенный пример — вам, возможно, придется передать дополнительные аргументы командам CMake или использовать что-то лучше, чем std::system, но это может дать вам общее представление. Я не вдавался во все детали кода выше, так как ваш вопрос был довольно расплывчатым; не стесняйтесь задавать более конкретные вопросы.

0

Другие решения


По вопросам рекламы [email protected]