I'm not sure I fully understand your question, but I'll have a stab at an answer :)
You can create a new C++ project to be configured by CMake. CMake will write all the paths required by your C++ code into a C++ source file. Let's say the new project has the following structure:
/CMakeLists.txt
/PluginAlpha
/CMakeLists.txt
/...
/PluginBeta
/CMakeLists.txt
/...
/PluginGamma
/CMakeLists.txt
/...
/main.cpp
Your top-level CMakeLists.txt could do:
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")
So, as part of configuring the project, this writes a C++ header which defines a collection of build and source paths to each of the plugins - e.g.
#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_
You can then have main.cpp do something like:
#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;
}
Now if you run the program "Builder", it should configure and build each of the plugins.
This is a simplified example - you may well have to pass extra args to the CMake commands, or want to use something better than std::system
, but this might give you the general idea. I haven't gone into all the details of the code above since your question was pretty vague; feel free to ask further, more specific questions.