← index
cplusplus2x.Examples/C++20/mingw_deploy/main.cpp
Source: cplusplus2x.Examples/C++20/mingw_deploy/main.cpp
/*
    mingw-deploy
    written by Jared Bruni
    https://lostsidedead.biz

    Copy DLL from Mingw compiled EXE in MSYS2 to current directory

*/

#include "argz.hpp"

#include <algorithm>

#include <cstdio>

#include <cstdlib>

#include <iostream>

#include <optional>

#include <sstream>

#include <string>


std::optional<std::string> extractFilename(const std::string &path) {
    auto pos = path.find("=>");
    if (pos != std::string::npos) {
        std::string rightof = path.substr(pos + 2);
        auto pos2 = rightof.rfind("(");
        if (pos2 != std::string::npos) {
            std::string leftof = rightof.substr(0, pos2);
            return leftof;
        }
    }
    return std::nullopt;
}

int main(int argc, char **argv) {
    Argz<std::string> argz(argc, argv);
    argz.addOptionSingleValue('i', "input filename")
        .addOptionSingle('h', "print out help")
        .addOptionSingleValue('o', "output directory ")
        .addOptionDoubleValue('I', "input", "input filename")
        .addOptionDoubleValue('O', "output", "output directory");
    int value = 0;
    Argument<std::string> arg;
    std::string input_exe;
    std::string output_dir = ".";
    try {
        while ((value = argz.proc(arg)) != -1) {
            switch (value) {
            case 'h':
                argz.help(std::cout);
                break;
            case 'i':
            case 'I':
                input_exe = arg.arg_value;
                break;
            case 'o':
            case 'O':
                output_dir = arg.arg_value;
                break;
            }
        }
    } catch (const ArgException<std::string> &e) {
        std::cerr << "Syntax Error: " << e.text() << "\n";
    }
    if (input_exe.empty()) {
        std::cerr << "Error requires input EXE path with -i.\n";
        argz.help(std::cout);
        std::cerr.flush();
        exit(EXIT_FAILURE);
    }
    std::ostringstream stream;
    stream << "ldd " << input_exe << " | grep -vi windows ";
#ifdef _WIN32

    FILE *fptr = _popen(stream.str().c_str(), "r");
#else

    FILE *fptr = popen(stream.str().c_str(), "r");
#endif

    if (!fptr) {
        std::cerr << "An Error has occoured..\n";
        std::cerr.flush();
        exit(EXIT_FAILURE);
    }
    std::string output;
    while (!feof(fptr)) {
        char buf[1024];
        std::size_t bytes = fread(buf, 1, 1024, fptr);
        buf[bytes] = 0;
        output += buf;
    }
#ifdef _WIN32

    _pclose(fptr);
#else

    pclose(fptr);
#endif

    std::istringstream istream(output);
    while (!istream.eof()) {
        std::string line;
        std::getline(istream, line);
        if (istream) {
            auto filename = extractFilename(line);
            if (filename.has_value()) {
                std::ostringstream stream;
                stream << "cp " << filename.value() << " " << output_dir;
                system(stream.str().c_str());
                std::cout << stream.str() << "\n";
            }
        }
    }
    return 0;
}