2016-07-31 10 views
1

У меня есть некоторые файлы, такие как:Можете ли вы создать независимые слои абстракции при связывании объектных файлов с GCC?

a.c a.h 
b.c b.h 
c.c c.h 
d.c d.h 

где используется б, б использует C, C использует д.

При компиляции существует ли способ, с помощью которого я могу связать непосредственно с b, а не включать все из них в свой компилятор?

каким-то образом использовать:

gcc a.o b.o 

вместо:

gcc a.o b.o c.o d.o 

Я хочу сделать это так, чтобы не беспокоиться о том, если б или в, или d осуществляется с использованием любого другого файлы, а вместо этого можно просто указывать непосредственно на bo

Боковой вопрос: есть ли способ сделать команду с таким же именем, как и в рекурсивном файле:

gcc *.o 

Я любопытен и только в случае, в лучшем случае выше не представляется возможным

+0

Объясните, что вы подразумеваете под «где использует b, b использует c, c использует d.», У вас есть три программы или библиотеки? Если вам нужно связать подмножество объектных файлов, тогда просто скажите так: someapp: a.o b.o'. – user657267

ответ

1

Вы, кажется, есть небольшое неправильное представление о том, как компиляции и компоновки работы.

Предположим, что файлы выглядеть следующим образом:

//a.h 
// nothing in particular 

//a.c 
#include "b.h" 
int main() 
{ 
    bravo(); 
    return 0; 
} 

//b.h 
void bravo(); 

//b.c 
#include "c.h" 
void bravo() 
{ 
    charlie(); 
} 

//c.h 
void charlie(); 

//c.c 
#include "d.h" 
void charlie() 
{ 
    delta(); 
} 

и так далее.

Как вы можете видеть, код в a.c относится к коду объявлен в b.h и определенной в b.c. Это не относится ни к чему в c или d.

Вы можете построить a.oпо составлению [1]:

gcc -c a.c  

«-c» означает «создать файл двоичный объект и остановить, не пытайтесь построить исполняемый». Компилятор замечает строку

#include "b.h" 

и тянет «b.h» в код. Он не смотрит на b.c, потому что никто не сказал об этом. Он видит, что этот код использует bravo(), который не был определен, и он надеется, что кто-то предоставит эту функцию, когда придет время для создания исполняемого файла. Компилятор не знает и не заботится о b.c, charlie(), delta() и ни в одном из c или d файлах.

Когда приходит время для создания исполняемого файла, то линкер вступает в игру [2]:

gcc a.o b.o c.o d.o 

Компоновщик может построить исполняемый файл из этих файлов, так как все функции, которые вызываются, определяются, поэтому он может связывать все свободные концы.Это:

gcc a.o b.o 

не будет работать. Компилятор говорит: «Держись, я не могу построить полную программу из этого, вы вызываете charlie(), но я не вижу определения charlie()

[1] Есть некоторые разногласия относительно того, следует ли это называть «компиляция a.c» или «компиляция a.o», но это не важно здесь.

[2] Обратите внимание, что gcc содержит как компилятор, так и компоновщик, а также другие вещи. Это как швейцарский армейский нож.

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

  • Нет связанных вопросов^_^