2015-07-14 2 views
0

Может ли GCC компилировать и запускать исходный код без генерации какого-либо выходного файла (ни объекта, ни исполняемого файла), поддерживая кросс-платформу? В частности, решение, поддерживаемое GCC напрямую.Может ли GCC компилировать и запускать исходный код без создания объекта или исполняемых файлов?

Я хочу избежать генерации любого файла трассировки, поскольку это небольшой код в большом проекте. Это просто испортит каталог bin.

Существующий вопрос here, предоставляет решение для компиляции исходного кода не генерируя выходной файл, например:

gcc somefile.c -o /dev/null 

Однако это только компилируется и не запускается.

Другой подобный вопрос here предлагает решение, специфичное для ОС Windows, а не межплатформенное.

+0

вы имеете в виду объектный файл? – Jagannath

+0

@Jagannath Я хочу избежать любого двоичного или объектного файла. Просто хочу запустить то, что должно быть построено. – ar2015

+0

lol. Binary - это то, что нужно поддерживать и запускать. – Jagannath

ответ

2

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

Вот ссылка на пример программы, которая удаляет себя. Click Here

+0

OP говорил о переносимости. Является ли это переносной? В Windows мы можем удалить что-то, что используется? – Jagannath

+0

Да, это работает в Windows, я обновил пример. – wuno

+1

Пожалуйста, не плагируйте - дайте кредит, где должен быть кредит! –

1

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

Например, вы можете решить, что каждый промежуточный исполняемый файл или файл с именем *.tmp или _* или *.tmpbin (для временных бинарных файлов) и имеют некоторые Makefile правил, которые удаляют их. Или вы можете использовать mktemp(1) в своем Makefile, чтобы получить временное имя файла. Не забудьте удалить его позже.

Кроме того, в большинстве крупных проектов есть шаг компиляции и шаг установки (часто make install); и если у вас этого нет, вы, вероятно, должны. Вы хотите, чтобы ваш шаг установки избегал установки временных двоичных файлов или файлов; с некоторыми соглашениями об именах это довольно просто: первая команда для install фальшивой цели в вашем Makefile удалит эти временные файлы или файлы.

Кроме того, вы обычно строите дерево файлов, отличное от конечного каталога bin/, поэтому вы можете оставить временные исполняемые файлы в дереве сборки.

Как несколько человек заметили, убрав свой собственный исполняемый легко на Linux (сделать readlink(2) на "/proc/self/exe" (см proc(5) подробности), то unlink(2) результат readlink ....), но трудно на Windows.

Так что практически ваш вопрос не является очень важным вопросом ... (если вы используете подходящие соглашения о строительстве). И GCC работают над файлами (потому что он будет запускать ld для создания этого исполняемого файла); однако GCCJIT скрывает их. AFAIK, вы даже не сможете использовать /dev/stdout в качестве исполняемого вывода gcc (но вы можете запустить gcc -x c /dev/stdin, чтобы скомпилировать код C от stdin).Таким образом, GCC не может избежать возможности сделать исполняемый файл file (но вы могли бы использовать его временно или в файловой системе tmpfs или FUSE). Поэтому вам нужно что-то внешнее для вашей команды gcc (возможно, просто rm в следующей строке вашего Makefile), чтобы удалить созданный исполняемый файл.

Вы также можете решить (dynamically loaded) plugins (например, использовать dlopen(3) на Linux). Ваша основная программа может загрузить плагин (с dlopen на Linux) - возможно, даже после того, как он динамически сгенерировал свой код на C++ и скомпилировал этот сгенерированный код, например. некоторые shared object.so на Linux (или DLL на Windows), как я do в MELT - запустите функции в нем получены с dlsym и выгрузить плагин (с dlclose на Linux) и, наконец, remove его. Вы можете использовать кросс-платформенные фреймворки, такие как Qt или POCO, чтобы избежать использования кода плагина, специфичного для ОС.

+0

Спасибо, Василий за ваш ответ. Однако для меня очень важно услышать, возможно ли GCC напрямую или нет. Я не знаю, почему люди избегают говорить об этом. Даже «Нет» не раздражает меня. Но, по крайней мере, я знаю, что я не должен продолжать его искать. – ar2015

+0

Я думаю, что проблема заключается не в компиляции на ветру, а в запуске сгенерированного исполняемого файла на ветру. – ar2015

+0

и +1, ссылаясь на основную точку. – ar2015

0

Простой Баш скрипт может помочь:

#!/bin/bash 

echo 'compile... ' $1 
gcc $1 && ./a.out && rm a.out 

предположил, что это назвало once, то вы можете сделать

$ sh once any.c 

скомпилировать any.c и просто запустить его раз.
Вы также можете сделать once исполняемый с chmod +x once, так что вы можете просто ввести

$ once any.c 

Надеются, что это помогает;)

Смежные вопросы