ไลบรารีแบบคงที่ซึ่งขึ้นอยู่กับไลบรารีแบบคงที่อื่น ๆ

ฉันมีคำถามเกี่ยวกับการสร้างไลบรารีแบบคงที่ที่ใช้ไลบรารีแบบคงที่อื่น ๆ

ฉันตั้งค่าตัวอย่างด้วย 3 ไฟล์ - main.cpp, slib1.cpp และ slib2.cpp slib1.cpp และ slib2.cpp ได้รับการคอมไพล์เป็นไลบรารีสแตติกแต่ละไลบรารี (เช่น ฉันลงเอยด้วย slib1.a และ slib2.a) main.cpp จะถูกคอมไพล์เป็นไฟล์ปฏิบัติการ ELF มาตรฐานที่เชื่อมโยงกับไลบรารีทั้งสอง
นอกจากนี้ยังมี ไฟล์ส่วนหัวชื่อ main.h ซึ่งสร้างต้นแบบฟังก์ชันใน slib1 และ slib2

main.cpp เรียกใช้ฟังก์ชันที่เรียกว่า lib2func() จาก slib2 ฟังก์ชั่นนี้จะเรียก lib1func() จาก slib1

หากฉันคอมไพล์โค้ดตามที่เป็นอยู่ g++ จะกลับมาพร้อมกับข้อผิดพลาดของลิงก์เกอร์ที่ระบุว่าไม่พบ lib1func() ใน slib1 อย่างไรก็ตาม หากฉันทำการเรียก lib1func() ก่อนการเรียกฟังก์ชันใดๆ ใน slib2 โค้ดจะคอมไพล์และทำงานได้อย่างถูกต้อง

คำถามของฉันมีดังต่อไปนี้: เป็นไปได้ไหมที่จะสร้างไลบรารีแบบคงที่ซึ่งขึ้นอยู่กับไลบรารีแบบคงที่อื่น ดูเหมือนเป็นข้อจำกัดที่รุนแรงมากหากเป็นไปไม่ได้

ซอร์สโค้ดสำหรับปัญหานี้แนบมาด้านล่าง:

main.h:

#ifndef MAIN_H
#define MAIN_H

int lib1func();
int lib2func();

#endif

slib1.cpp:

#include "main.h"

int lib1func() {
  return 1;
}

slib2.cpp:

#include "main.h"

int lib2func() {
  return lib1func();
}

main.cpp:

#include <iostream>
#include "main.h"

int main(int argc, char **argv) {
  //lib1func();  // Uncomment and compile will succeed.  WHY??

  cout << "Ans: " << lib2func() << endl;
  return 0;
}

เอาต์พุต gcc (โดยมีบรรทัดใส่ความคิดเห็น):

g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
./libslib2.a(slib2.o): In function `lib2func()':
slib2.cpp:(.text+0x5): undefined reference to `lib1func()'
collect2: ld returned 1 exit status

เอาต์พุต gcc (ไม่มีบรรทัดแสดงข้อคิดเห็น)

g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2

$ ./main 
Ans: 1

person knelson    schedule 19.06.2012    source แหล่งที่มา


คำตอบ (2)


โปรดลอง g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group

กลุ่มที่กำหนดด้วย --start-group, --end-group ช่วยในการแก้ไขการขึ้นต่อกันแบบวงกลมระหว่างไลบรารี

ดูเพิ่มเติมที่: GCC: อะไรคือ --start-group และ --end-group ตัวเลือกบรรทัดคำสั่ง?

person Ruben    schedule 19.06.2012

คำสั่งซื้อสร้างความแตกต่าง นี่คือจากหน้าคู่มือ gcc(1):

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
person Nikolai Fetissov    schedule 19.06.2012
comment
มันเป็นไปได้ที่จะมีการพึ่งพาแบบวงกลมระหว่างไลบรารีด้วยซ้ำ ในกรณีเช่นนี้ คุณต้องระบุไลบรารีใดไลบรารีหนึ่งสองครั้งบนบรรทัดคำสั่ง - person Tamás Szelei; 20.06.2012
comment
หรือใช้ตัวเลือกตัวเชื่อมโยงตามที่ @Ruben แนะนำ - person Nikolai Fetissov; 20.06.2012