เทอร์มินัลรายงานเวอร์ชัน OpenSSL ได้อย่างง่ายดาย แต่ทรีซอร์สโค้ดยังคงล้มเหลวพร้อมข้อความเกี่ยวกับเฮดเดอร์การเข้ารหัสที่หายไป ทั้งสองข้อความเป็นจริงในเวลาเดียวกัน เพราะเครื่องมือรันไทม์และชุดอินพุตสำหรับบิลด์ถูกจัดส่งแยกกัน ให้ทำการตรวจสอบสี่ข้อนี้ตามลำดับ ได้แก่ แพ็กเกจที่ติดตั้ง เอาต์พุตการค้นหา พาธการค้นหา และสุดท้ายคือซอร์สโค้ดเองเข้ากันได้หรือไม่ หยุดที่ข้อแรกที่อธิบายความล้มเหลวแทนที่จะวางรายการดีเพนเดนซีเก่า

รันไทม์และอินพุตสำหรับบิลด์เป็นแพ็กเกจที่ต่างกัน

ดิสทริบิวชันแบ่ง OpenSSL ออกเป็นแพ็กเกจรันไทม์ที่ให้ไลบรารีแบบใช้ร่วมและเครื่องมือบรรทัดคำสั่ง และแพ็กเกจสำหรับพัฒนาที่ให้เฮดเดอร์ ชื่อลิงก์ที่ไม่มีเวอร์ชัน และเมทาดาทาของ pkg-config การติดตั้งตัวแรกไม่ได้ติดตั้งตัวที่สอง และคอมไพเลอร์ต้องการเพียงตัวที่สอง

ตรวจสอบว่ามีอะไรอยู่จริง ไม่ใช่สิ่งที่คุณจำได้ว่าติดตั้งไว้ ในระบบที่อิง Debian แพ็กเกจสำหรับพัฒนามักเป็น libssl-dev ส่วนรันไทม์คือแพ็กเกจไลบรารีที่มีเวอร์ชันบวกไบนารี openssl

dpkg -l | grep -E 'libssl-dev|libssl3|openssl'
pkg-config --modversion openssl
openssl version

คำสั่งแรกแสดงว่าตัวใดในสามตัวถูกติดตั้ง คำสั่งที่สองรายงานเวอร์ชันที่ระบบบิลด์จะค้นพบผ่าน pkg-config และคำสั่งที่สามรายงานเวอร์ชันรันไทม์ บรรทัดที่หายไปในเอาต์พุตแรกอธิบายข้อผิดพลาดได้ทันที ความไม่ตรงกันของเวอร์ชันระหว่างคำสั่งที่สองและที่สามเป็นปัญหาอีกอย่าง และมักหมายถึงมีการติดตั้งสองชุดที่แข่งขันกัน

อ่านเอาต์พุตการค้นหาของการบิลด์เอง

ความล้มเหลวส่วนใหญ่มองเห็นได้ในบันทึกการกำหนดค่าหากอ่านก่อนสรุป โมดูล FindOpenSSL ของ CMake รายงานว่าไดเรกทอรี include และไลบรารีใดที่พบ และล้มเหลวพร้อมข้อความเฉพาะเมื่อส่วนประกอบที่จำเป็นหายไป

ยืนยันว่าโปรเจกต์ใช้โมดูลเวอร์ชันใด เพราะสำเนาที่รวมอยู่ในทรีซอร์สโค้ดอาจทำงานต่างจากสำเนาที่จัดส่งมาพร้อม CMake ที่ติดตั้งไว้ จากนั้นอ่านรายการส่วนประกอบ โปรเจกต์ที่ขอเฉพาะ Crypto ไม่ต้องใช้ไลบรารี SSL และโปรเจกต์ที่ขอ SSL จะล้มเหลวหากมีเพียงบางส่วนของแพ็กเกจสำหรับพัฒนา

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
grep -i -E 'openssl|ssl' build/CMakeCache.txt

คำสั่งแรกกำหนดค่าใหม่ตั้งแต่ต้น และคำสั่งที่สองแสดงผลลัพธ์ที่แคชไว้ รวมถึงไดเรกทอรีรากหรือพาธไลบรารีที่โมดูลเลือก หากแคชชี้ไปที่คำนำหน้าเก่าจากความพยายามครั้งก่อน ให้ลบไดเรกทอรีบิลด์และกำหนดค่าใหม่แทนการแก้ไขค่าด้วยมือ รายการแคชที่ล้าสมัยเป็นสาเหตุทั่วไปของความล้มเหลวที่อยู่รอดแม้แก้ไขอย่างถูกต้อง

กำหนดทิศทางการบิลด์ไปยังการติดตั้งที่ถูกต้องอย่างแคบ

เมื่อ OpenSSL ที่ได้รับอนุมัติอยู่นอกพาธการค้นหาเริ่มต้น FindOpenSSL ระบุ OPENSSL_ROOT_DIR เป็นคำใบ้สำหรับการบิลด์นั้นโดยเฉพาะ บนระบบแบบ Unix ยังสอบถาม pkg-config ด้วย ดังนั้น PKG_CONFIG_PATH ที่เหมาะสมช่วยได้โดยไม่ต้องเปลี่ยนสิ่งใดในระดับโลก

cmake -S . -B build -DOPENSSL_ROOT_DIR=/opt/openssl-3.2 -DCMAKE_BUILD_TYPE=Release
ldd build/vpn_client | grep -i ssl

คำสั่งแรกจำกัดคำใบ้ไว้ที่ไดเรกทอรีบิลด์เดียว และคำสั่งที่สองแสดงว่าไบนารีที่ได้จะโหลดไลบรารีร่วมใดเมื่อรัน การบิลด์ที่ลิงก์กับคำนำหน้าที่ตั้งใจไว้และไบนารีที่โหลดอีกตัวเป็นปัญหาพาธรันไทม์ ไม่ใช่ปัญหาการค้นหา และต้องตัดสินใจเรื่อง rpath หรือการกำหนดค่าตัวโหลดแทนการใช้แฟล็กกำหนดค่าเพิ่ม

เก็บตัวเลือกเหล่านี้ไว้ในบิลด์เท่านั้น การแทนที่ไลบรารีของระบบหรือแก้ไขไฟล์ pkg-config ส่วนกลางเพื่อเอาใจโปรเจกต์เดียวคือทางที่เดสก์ท็อปที่ใช้งานได้กลายเป็นพัง ไดเรกทอรีบิลด์ที่บันทึกคำนำหน้าสามารถทำซ้ำได้ ส่วนการเปลี่ยนแปลงทั้งเครื่องเป็นเหตุการณ์สนับสนุนที่รอโปรเจกต์ถัดไป ลบไดเรกทอรีบิลด์เมื่อเปลี่ยนคำใบ้ เพื่อให้แคชไม่สามารถเก็บคำตอบเก่าไว้ได้

รู้ว่าเมื่อใดตัวซอร์สเองคือปัญหา

ขั้นตอนกำหนดค่าที่สำเร็จพิสูจน์เพียงว่าการตรวจสอบเสร็จสิ้น การคอมไพล์ยังอาจปฏิเสธ API ที่ซอร์สคาดหวัง และการลิงก์ยังอาจล้มเหลวเพราะสัญลักษณ์ที่หายไป เก็บข้อผิดพลาดเฉพาะเจาะจงข้อแรกของแต่ละขั้นตอน เพราะข้อถัดมามักเป็นผลสืบเนื่อง

OpenSSL 3 ประกาศเลิกใช้และลบอินเทอร์เฟซหลายตัวที่ไคลเอนต์ VPN รุ่นเก่าใช้โดยตรง ดังนั้นทรีซอร์สโค้ดจากยุคนั้นอาจต้องมีการเปลี่ยนแปลงจริงแทนพาธ include ใหม่ หากผู้ดูแลรองรับรุ่นปัจจุบันให้ใช้รุ่นนั้น หากไม่ การตัดสินใจเป็นของผู้ที่เป็นเจ้าของบริการ ไม่ใช่การค้นหาชื่อไฟล์ไลบรารีที่เก่ากว่า

ส่วนประกอบเดสก์ท็อปที่เป็นทางเลือกก็มีข้อกำหนดของตนเอง เป้าหมายบรรทัดคำสั่งที่กำหนดค่าได้สะอาดไม่ได้บอกอะไรว่าชุดเครื่องมือ GUI และเอดิเตอร์จะบิลด์ได้หรือไม่ จึงควรมองรายการแพ็กเกจ Qt เก่าเป็นประวัติศาสตร์ไม่ใช่ข้อกำหนด ตรวจสอบตัวเลือกของรีวิชันซอร์สเองว่าอินเทอร์เฟซใดเปิดใช้โดยปริยาย จากนั้นบิลด์เฉพาะสิ่งที่ต้องการ เพราะทุกดีเพนเดนซีที่เป็นทางเลือกคือปัญหาการค้นหาอีกข้อที่รอเกิดขึ้น

บทความที่เกี่ยวข้อง