รวบรวมรหัสจาก apue


12

เพียงแค่ตอนนี้ฉันได้เริ่มอ่านหนังสือ: การเขียนโปรแกรมในUNIX®สิ่งแวดล้อมขั้นสูง ฉันต้องการลองใช้ตัวอย่างรหัสแรก ฉันใช้ Scientific Linux 6.4

ฉันดาวน์โหลดซอร์สโค้ดและตามที่ระบุใน README ของมันฉันรันmakeในไฟล์ที่ไม่มีการบีบอัด

ฉันเขียนโปรแกรมแรก ( lsคำสั่งจำลอง)

#include "./include/apue.h"
#include <dirent.h>

int
main(int argc, char *argv[])
{
    DIR           *dp;
    struct dirent *dirp;

    if(argc!=2)
        err_quit("usage: test directory_name");

    if((dp=opendir(argv[1]))==NULL)
        err_sys("Can't open %s", argv[1]);

    while((dirp=readdir(dp))!=NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);
    return 0;
}

และวางไว้ในไฟล์ที่ไม่มีการบีบอัด ตามที่หนังสือแนะนำฉันก็วิ่งไป: gcc myls.c. แต่ฉันได้รับข้อผิดพลาดนี้:

# gcc myls.c
/tmp/ccWTWS2I.o: In function `main':
test.c:(.text+0x20): undefined reference to `err_quit'
test.c:(.text+0x5b): undefined reference to `err_sys'
collect2: ld returned 1 exit status

ฉันอยากรู้ว่าฉันสามารถแก้ไขปัญหานี้ได้อย่างไร ฉันต้องการที่จะเรียกใช้รหัสที่ฉันเขียนในไดเรกทอรีใด ๆ


คุณคาดหวังว่าerr_{quit,sys}จะมาจากไหน
Chris Down

ในซอร์สโค้ดไม่มีการบีบอัดมีไดเรกทอรี: ที่มีไฟล์ส่วนหัวinclude apue.hแต่นี่เป็นไฟล์เดียวในไดเรกทอรีนั้น ฉันไม่เข้าใจว่าคำจำกัดความของฟังก์ชั่นที่แท้จริงเป็นอย่างไร! ฉันคิดว่าบางคนอาจคุ้นเคยกับโครงสร้างไฟล์ซอร์สโค้ดของหนังสือเล่มนี้ที่นี่
makhlaghi

.hไฟล์รวมถึง protypes สำหรับฟังก์ชั่น การใช้งานของพวกเขาอยู่ใน.soหรือ.aไฟล์ที่จะต้องมีอยู่ในกล่อง เหล่านี้เป็นห้องสมุดแบบไดนามิกและคงที่ซึ่งมีฟังก์ชั่น
slm

อะไรกันนะapue.h?
เสียง

คำตอบ:


13

ทบทวนสั้น ๆ เกี่ยวกับวิธีการเขียนและคอมไพล์โปรแกรมในAdvanced Programming ในUNIX® Environmentขอบคุณslm ที่ช่วยให้ฉันเข้าใจขั้นตอน คุณสามารถดาวน์โหลดรหัสแหล่งที่มาจากที่นี่ ฉันหวังว่าข้อมูลนี้จะถูกรวมเป็นส่วนหนึ่งของภาคผนวกขของหนังสือที่อธิบายไฟล์ส่วนหัว

ไฟล์บีบอัดมีไดเรกทอรีที่มีชื่อของบทและอีกสองคนชื่อและinclude libคนที่มีชื่อของบทมีโปรแกรมทั้งหมดของบทนั้นในพวกเขา

ไดเรกทอรีมีไฟล์ส่วนหัวที่ถูกนำมาใช้ในส่วนของโปรแกรมในหนังสือเล่มนี้:include ไดเรกทอรีมีรหัสที่มาของการใช้งานสำหรับส่วนหัวที่apue.hlib

ให้ถือว่าไฟล์ที่ไม่มีการบีบอัดตั้งอยู่ที่: SCADDRESS/เช่นอาจเป็น: /home/yourid/Downloads/apue.3e/

เมื่อคุณคลายการบีบอัดซอร์สโค้ดให้ไปที่ไดเรกทอรีและเรียกใช้make:

$ cd SCADDRESS
$ make

makeจะรวบรวมโปรแกรมทั้งหมดในทุกบท แต่สิ่งที่สำคัญคือก่อนหน้านั้นมันจะทำให้ห้องสมุดที่จะมีการใช้งานของฟังก์ชั่นapue.hมา

ในการรวบรวมโปรแกรมตัวอย่างที่คุณเขียนจากหนังสือให้เรียกใช้คำสั่ง GCC นี้ (สมมติว่าชื่อโปรแกรมของคุณเป็นชื่อmyls.cแรกในหนังสือ):

gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue

-Iบอกgccไดเรกทอรีที่จะมองหาไฟล์รวม -Lบอกตำแหน่งของไดเร็กทอรีไลบรารีและ -lapueบอกชื่อของไฟล์ไลบรารีเพื่อค้นหาในไดเร็กทอรีนั้น เช่นนั้น -LXXX หมายถึงการค้นหาไฟล์ในไดเรกทอรีไลบรารีที่มีชื่อ: libXXX.a หรือ libXXX.so


บางครั้งอาจเพิ่มความสว่างให้-Wallกับgccคำสั่งเพื่อเตือนให้บ่อยขึ้น
MattBianco

3

ฉันคิดว่าคำถามและคำตอบ stackoverflow นี้มีการกำหนดฟังก์ชัน err_sys () ไว้ที่ไหน มีสิ่งที่คุณต้องการ 2 จากคำตอบในหัวข้อนั้นต้องบอกว่า:

A1

err_sys () เป็นฟังก์ชันที่ใช้ในหนังสือหลายเล่มที่เขียนโดย W. Richard Stevens ฟังก์ชั่นนี้ใช้พิมพ์ประเภทของข้อผิดพลาดที่เกิดขึ้น

ฟังก์ชั่นนี้ใช้ในโปรแกรมในข้อความที่มีไฟล์ส่วนหัวที่กำหนดเอง "ourhdr.h" (หรืออย่างอื่น) ตรวจสอบภาคผนวกสำหรับรายการส่วนหัวหรือนิยามฟังก์ชัน

A2

แหล่งสำหรับฟังก์ชั่นนี้ (จากการเขียนโปรแกรมขั้นสูงในUNIX®สิ่งแวดล้อมโดยริชาร์ดสตีเว่นดับบลิว) ที่สามารถพบได้บนเว็บไซต์ของหนังสือเล่มนี้: http://www.apuebook.com/

อ้างอิง


ขอบคุณ แต่ปัญหาของฉันคือการรวบรวมมันดังนั้นข้อผิดพลาดเหล่านี้จึงไม่เกิดขึ้น นี่err_sysเป็นเพียงตัวอย่างมีฟังก์ชั่นอื่น ๆ ในไฟล์ส่วนหัวนั้น ดังนั้นฉันกำลังมองหาคำตอบทั่วไปสำหรับปัญหานี้ (วิธีการรวมไฟล์ส่วนหัวและรวบรวมสำเร็จ) ไม่เขียนฟังก์ชันนี้โดยเฉพาะ
makhlaghi

1
@makhlaghi - ข้อผิดพลาดคือ b / c คุณไม่มีการใช้งานพื้นฐาน คุณมักจะรวมถึงการgccใช้-Lอาร์กิวเมนต์ที่อ้างอิงถึงไลบรารีที่จะใช้ ไลบรารีคือ.soหรือ.aไฟล์ กวดวิชานี้อาจจะมีประโยชน์ในการทำความคุ้นเคย w / gcc, ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html โดยเฉพาะในส่วนนี้: "การค้นหาไฟล์และไลบรารีส่วนหัว (-I, -L และ -l)"
slm

ขอบคุณมากสำหรับความอดทนของคุณในการจัดการกับฉัน (เป็นมือใหม่!) ฉันเข้าใจวิธีการรวบรวม ฉันต้องใช้คำสั่งนี้: gcc -o myls myls.c -L LIBPOSITION -lapue. ตำแหน่ง LIBPOSITION อยู่ในlibไดเร็กทอรีของไดเร็กทอรีที่ไม่ถูกบีบอัด ขอบคุณอีกครั้ง.
makhlaghi

@makhlaghi - อย่าพูดถึงมัน ฉันชอบช่วยให้ผู้อื่นเข้าใจว่าสิ่งต่าง ๆ ทำงานอย่างไร เชื่อหรือไม่โดยการอธิบายสิ่งต่าง ๆ มันช่วยให้ฉันเข้าใจสิ่งต่าง ๆ ได้ดีขึ้นเช่นกัน ขอบคุณสำหรับคำถามและโชคดีที่มีการเดินทาง gcc!
slm

2

ขั้นตอนต่อไปนี้ใช้งานได้สำหรับฉัน (Ubuntu 14.04 64 บิต):

  1. wget http://www.apuebook.com/src.3e.tar.gzดาวน์โหลดไฟล์เก็บถาวร gzipped tar จากเว็บไซต์หนังสืออย่างเป็นทางการ
  2. tar xzf src.3e.tar.gzสิ่งนี้จะสร้างโฟลเดอร์ที่คลายซิปซึ่งเรียกว่าapue.3eอยู่ภายใต้ไดเรกทอรีปัจจุบัน
  3. cd apue.3e
  4. sudo apt-get install libbsd-dev. นี่สำหรับลิงก์ -lbsd in / threads
  5. make นี่จะรวบรวมซอร์สโค้ดทั้งหมดในโฟลเดอร์ทั้งหมดโดยอัตโนมัติ
  6. cd introจากนั้น./ls1 ..ทำงานตามที่คาดไว้ (แสดงรายการไฟล์จากไดเรกทอรีหลัก)

คุณอาจต้องไปรอบ ๆ เพื่อค้นหาตัวอย่างโค้ดอื่น ๆ จากหนังสือ แต่ควรตรงไปตรงมา


1

สิ่งที่ makhlighi ได้อธิบายไว้ในความคิดเห็นล่าสุดของเขาทำงานให้ฉัน แต่ฉันต้องใช้ซอร์สโค้ดที่แตกต่างไม่ใช่จากเว็บไซต์ทางการ www.apuebook.com

ผมคนหนึ่งที่ใช้สามารถพบได้ในhttps://github.com/roktas/apue2e ดังที่มีคนอธิบายว่าสิ่งนี้ได้ถูกนำไปใช้เพื่อทำงานกับระบบ Linux ที่ทันสมัย


บางทีคุณอาจอธิบายรายละเอียดเล็กน้อยได้ไหม?
slm

0

ฉันสร้างไลบรารีสำเร็จโดยใช้คำสั่งบรรทัดคำสั่งที่ให้ไว้ที่นี่ ฉันมีปัญหาในการสร้างตัวอย่างใน Xcode เพื่อให้เสร็จฉันได้กำหนดพา ธ การค้นหาสำหรับไฟล์ส่วนหัวและไลบรารี (บานหน้าต่าง "สร้างการตั้งค่า") กว่าที่ฉันจะกำหนดห้องสมุดเองในบานหน้าต่าง "Build Phases" มากกว่า "Link Binary With Libraries" หลังจากนั้นมันเป็นเรื่องง่าย


0

หากติดตั้งapue.3eคุณสามารถลองใส่ apue ลงในไดเรกทอรีเริ่มต้นของระบบปฏิบัติการเช่น:

code@lab:~/src/code$ sudo cp ../apue.3e/include/apue.h /usr/include/
code@lab:~/src/code$ sudo cp ../apue.3e/lib/libapue.a /usr/lib/

เมื่อรวบรวมรหัสแล้วกรุณาเพิ่มอาร์กิวเมนต์: -lapue

code@lab:~/src/code$ gcc -o myls myls.c -lapue
code@lab:~/src/code$ ./myls
Usage: ls <dir>

0

'err_sys' และ 'err_quit' มีอยู่ในไฟล์ชื่อ 'errno.c' ซึ่งไม่ได้อยู่ในไดเรกทอรีการทำงานปัจจุบันของคุณ ก่อนอื่นให้เปิดโฟลเดอร์ 'apue' ที่คุณดาวน์โหลดและไม่บีบอัดและคัดลอกรายการทั้งหมดในโฟลเดอร์นั้นเช่น advio, daemons ฯลฯ ทุกอย่างไปยังไดเรกทอรีการทำงานปัจจุบันของคุณคุณสามารถทราบไดเรกทอรีการทำงานปัจจุบันของคุณได้โดย ใช้คำสั่ง 'pwd'. ตอนนี้ในโฟลเดอร์' รวม 'คุณจะพบไฟล์ส่วนหัว apue.Copy ที่เกินไปไปยังไดเรกทอรีการทำงานปัจจุบันของคุณในสั้นไฟล์ใด ๆ . c ที่คุณจะใช้ในโปรแกรมของคุณจะต้อง อยู่ในไดเรกทอรีการทำงานปัจจุบันของคุณดังนั้นคัดลอกไฟล์เหล่านั้นไปยังไดเรกทอรีการทำงานปัจจุบันของคุณ

ตอนนี้สำหรับการแก้ปัญหาของคุณไฟล์ errno.c อยู่ในโฟลเดอร์ lib ในโฟลเดอร์ apue คัดลอกไปยังไดเรกทอรีการทำงานปัจจุบันของคุณซึ่งจะช่วยแก้ปัญหาของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.