2016-09-19 2 views
1

Когда я хочу запустить исходный код, почему это работает:Почему я не могу запустить объектный файл?

gcc test.c -o test.o 

затем

./test.o 

, но это не работает:

gcc -c test.c 

затем

./test.o 

и получить это сообщение

bash: ./test.o: Permission denied 
+0

Объектный файл не является машинным руководством. Он не предназначен для запуска. Он предназначен для связи. Вы должны использовать 'gcc test.c -o test'. Затем у вас есть исполняемый файл с именем 'test'. –

+0

Взгляните на «man ld» и посмотрите, какую цель он выполняет при создании окончательного эльфа-исполняемого файла, и см. Ответы (а также удаленный файл Joachim) ниже. –

+4

после 'gcc test.c -o test.o', вы создали исполняемый файл с именем' test.o'. Это не объектный файл. –

ответ

5

Прежде всего, вы не создаете файл объекта но исполняемый файл. Объектные файлы представляют собой промежуточный файл, используемый в качестве входного файла для компоновщика для создания исполняемого файла. То, что вы называете его суффиксом .o, не имеет значения.

Во-вторых, по традиции, если вы не укажете имя выходного файла с параметром -o, программа и компоновщик компилятора создадут исполняемый файл с именем a.out.

Но это еще не все, потому что со вторым примером вы фактически создаете реальный объектный файл, и они не исполняются. Как упомянуто выше, эти требования должны быть переданы на отдельный шаг привязки для создания исполняемого файла.

Вам необходимо либо создать исполняемый файл:

gcc test.c 
./a.out 

Или вы должны связать объектный файл в исполняемый файл:

gcc -c test.c   # Create object file 
gcc test.o -o test  # Use object file to create executable file 
./test     # Run the executable file 
1

В первом случае вы просто имя полученный файл test.o с помощью -o, он был собран собран и связаны между собой.

Во втором случае вы просто скомпилированы и собраны, он не может работать без связи. См gcc --h или Overall options for gcc для -c:

-c

Compile или собрать исходные файлы, но не связывают. Стадия связывания просто не делается. Конечный результат представлен в виде объектного файла для каждого исходного файла. По умолчанию имя файла объекта для исходного файла создается путем замены суффикса «.c», «.i», «.s» и т. Д. На «.o».

Unrecognized input files, not requiring compilation or assembly, are ignored. 

(выделено мной)

Вы должны связать его, а затем выполнить его:

gcc -o a.out test.o 
3

Вы получаете это сообщение, потому что компилятор Безразлично» t установить исполняемый бит в объектных файлах, потому что - ну, потому что они не исполняются. Если вы установите исполняемый бит вручную и попытаетесь запустить его, вы получите что-то вроде «неизвестного исполняемого формата».

Теперь это не просто проблема с форматом - дело в том, что объектный файл - это всего лишь половина работы, чтобы получить что-то, что действительно может быть выполнено. В частности, отсутствует , связанный с шагом, где компоновщик находит нерешенные ссылки и исправляет их адресами из других объектных файлов - в том числе те, которые вы не указываете явно, как стандартная библиотека, - и генерирует надлежащий исполняемый файл, что ядро ​​знает, как загружать и выполнять.

0

Вы не можете запустить объектный файл. Это не выполнимо и необходимо связать, чтобы стать исполняемым.

Попробуйте

gcc -o test test.c и запустить с помощью ./test.out

0

Это фундаментальный вопрос в НКУ. Обратите внимание, что никогда не с помощью параметра -c, если вы хотите, чтобы получить исполняемый файл в одной команде, такие как

gcc -c xx.c yy.c -o new 

.Но вы можете получить исполняемый файл -c в следующих командах

gcc -c xx.c yy.c 
gcc xx.o yy.o -o new 

Это эквивалентно до

gcc xx.c yy.c -o new 
Смежные вопросы