Nano Hash - криптовалюты, майнинг, программирование

Замените вызов системы в моей программе на C++

Я пытаюсь найти замену вызову "system" (из stdlib.h) в моей программе на C++. До сих пор я использовал его для вызова g++ в моей программе для компиляции и последующего связывания переменного количества исходных файлов в каталоге, выбранном пользователем.

Вот пример того, как примерно может выглядеть команда: "C:/mingw32/bin/g++.exe -L"C:\mingw32\lib" [...]"

Однако у меня возникла проблема (по крайней мере, с компилятором MinGW, который я использую) я получаю сообщение об ошибке "Командная строка слишком длинная", когда командная строка становится слишком длинной. длинный. В моем случае это было около 12000 символов. Поэтому мне, вероятно, нужен другой способ вызова g++. Кроме того, я читал, что обычно не следует использовать слово «система»: http://www.cplusplus.com/forum/articles/11153/

Поэтому мне нужна какая-то замена (которая также должна быть максимально независимой от платформы, потому что я хочу, чтобы программа работала в Windows и Linux). Я нашел одного кандидата, который в целом выглядит вполне подходящим:

  • _execv / execv:

    Независимость от платформы, но:

    а) http://linux.die.net/man/3/exec говорит: " Семейство функций exec() заменяет текущий образ процесса новым образом процесса". Итак, мне нужно сначала вызвать "fork", чтобы программа C++ не была завершена? Доступен ли форк для Windows/MSVC?

    б) Используя «систему», я проверил, равно ли возвращаемое значение 0, чтобы увидеть, можно ли скомпилировать исходный файл. Как это будет работать с exec? Если я правильно понимаю man-страницу, будет ли она возвращать только успех создания нового процесса, а не статус g++? И с помощью какой функции я могу приостановить свою программу, чтобы дождаться завершения g++ и получить возвращаемое значение?

В общем, я не совсем уверен, как мне с этим справиться. Каковы ваши предложения? Как межплатформенные программы, такие как Java (Runtime.getRuntime().exec(command)) или Eclipse C++ IDE, решают эту проблему? Что бы вы посоветовали мне сделать, чтобы вызвать g++ независимым от системы способом - с таким количеством аргументов, как я хочу?

РЕДАКТИРОВАТЬ: Теперь я использую следующий код - я еще тестировал его только в Windows, но, по крайней мере, там он работает так, как ожидалось. Спасибо за идею, jxh! Возможно, в будущем я рассмотрю возможность сокращения команд с помощью относительных путей. Тогда мне пришлось бы найти независимый от платформы способ изменения рабочего каталога нового процесса.

#ifdef WIN32
int success = spawnv(P_WAIT, sCompiler.c_str(), argv);
#else
pid_t pid;
switch (pid = fork()) {
case -1:
    cerr << "Error using fork()" << endl;
    return -1;
    break;
case 0:
    execv(sCompiler.c_str(), argv);
    break;
default:
    int status;
    if (wait(&status) != pid) {
        cerr << "Error using wait()" << endl;
        return -1;
    }
    int success = WEXITSTATUS(status);
}
#endif

  • fork() предназначен для систем POSIX, которые поддерживают вызов, а MINGW не реализует его для Windows. Должен быть заголовочный файл <process.h>, который предоставляет spawn*(), который MINGW заменяет вызовы fork()/exec(). 12.04.2014
  • Боюсь спросить, зачем вам более 12 000 символов командной строки. Я читал короткие рассказы, которые занимали меньше места. 12.04.2014
  • Проблема с командой заключается в том, что она включает путь к исходному каталогу для каждого отдельного файла (например, C:/Users/Christoph/C++-Projekte/GameProgramming/LandsOfShadow/leveleditor_interface/Audio/Audio.o). С сотнями исходных файлов это становится очень долго... 12.04.2014
  • Можете ли вы разобрать повторения или, по крайней мере, установить гораздо более короткие символические ссылки на каталоги? 12.04.2014
  • Поскольку все исходные файлы имеют одну и ту же родительскую папку, я мог бы сократить их, изменив рабочий каталог g++ на исходный каталог, а затем просто использовать относительные пути к файлам, такие как main.o, вместо абсолютных путей, таких как C:/Users/Christoph/ C++-Projekte/GameProgramming/LandsOfShadow/leveleditor_interface/main.cpp. Однако я не уверен, как установить рабочий каталог процесса g++. 12.04.2014

Ответы:


1

Вы можете получить некоторую поддержку с некоторыми из этих параметров командной строки, если все ваши файлы находятся (или могут быть перемещены) в один (или небольшое количество) каталогов. Учитывая ваш образец пути к audio.o, это сократит вашу командную строку примерно на 90%.

-Ldir
Add directory dir to the list of directories to be searched for `-l'.

Из: https://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_3.html#SEC17

-llibrary
Search the library named library when linking.

Имеет значение, где в команде вы пишете эту опцию; компоновщик ищет библиотеки процессов и объектные файлы в том порядке, в котором они указаны. Таким образом, foo.o -lz bar.o' searches libraryz' после файла foo.o' but beforebar.o'. Если bar.o' refers to functions inz', эти функции могут быть не загружены.

Компоновщик ищет библиотеку в стандартном списке каталогов, который на самом деле является файлом с именем `liblibrary.a'. Затем компоновщик использует этот файл, как если бы он был указан точно по имени.

Поисковые каталоги включают в себя несколько стандартных системных каталогов, а также все, что вы укажете с помощью `-L'.

Обычно найденные таким образом файлы являются библиотечными файлами — архивными файлами, членами которых являются объектные файлы. Компоновщик обрабатывает архивный файл, просматривая его в поисках элементов, определяющих символы, на которые до сих пор ссылались, но которые не были определены. Но если найденный файл является обычным объектным файлом, он связывается обычным образом. Единственная разница между использованием -l' option and specifying a file name is that-l' окружает библиотеку с lib' and.a' и выполняет поиск в нескольких каталогах.

Из: http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_3.html

22.01.2015
  • Это кажется лучшим решением, так как оно переносимо и вам не нужно добавлять код, специфичный для ОС. Спасибо за ваш ответ! 23.01.2015
  • Я отметил ваш ответ как наиболее полезное решение, однако я не могу проголосовать за него, так как у меня еще нет «15 репутации». 24.01.2015

  • 2

    Вот еще вариант, возможно, ближе к тому, что вам нужно. Попробуйте изменить каталог перед вызовом system(). Например, вот что происходит в Ruby... Я предполагаю, что это будет действовать так же и в C++.

    > system('pwd')
    /Users/dhempy/cm/acts_rateable
    => true
    > Dir.chdir('..')
    => 0
    > system('pwd')
    /Users/dhempy/cm
    => true
    
    22.01.2015

    3

    Если ни один из других ответов не подходит, вот еще один. Вы можете установить переменную среды как путь к каталогу, а затем использовать эту переменную перед каждым файлом, на который вы ссылаетесь.

    Мне не очень нравится такой подход, так как приходится возиться с окружением, и я не знаю, повлияет ли это на лимит командной строки. Возможно, ограничение применяется после интерполяции команды. Но есть о чем поговорить, несмотря ни на что.

    23.01.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..