2016-10-03 97 views
0

我有一個C應用程序,我使用默認的gcc編譯器在Beaglebone Green Wireless開發系統上編譯。我的應用有以下標題,如何避免使用gcc編譯器的-l選項?

#include <stdio.h> 
#include <unistd.h> 
#include <malloc.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <netdb.h> 
#include <openssl/x509.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 
#include <assert.h> 
#include <json/json.h> 

當我編譯這個應用程序,我必須鍵入

gcc edgeclient.c -o edgeclient -l ssl -l crypto -l json 

有沒有辦法,我可以安裝SSL,加密和JSON庫,所以我不」的方式不得不輸入所有這些-l的?我不是一個懶惰的打字員。只是當我添加一個新的庫時,並不總是清楚我是否必須添加另一個-l libraryname選項。比猜測更清楚地瞭解到底發生了什麼。

+1

庫鏈接到您正在編寫的應用程序中,創建最終的應用程序。每個鏈接的庫只在您的應用程序使用庫中的代碼時才需要。如果你離開一個,你的應用無法鏈接,那麼這是必要的。如果它鏈接並運行,它從未被調用並且可以被排除。 –

+1

您是否考慮編寫Makefile並使用'make'來執行構建?那麼你不僅需要輸入所有的選項,而且在Makefile中你應該有什麼選項。 –

+2

似乎有很多人遇到了頭文件和庫之間的區別。如果你使用一個新的庫*,你需要鏈接到它(用'-l')。如果你添加一個頭文件,你只需要鏈接到一個新的庫,如果這個頭文件和一個你還沒有鏈接到的庫(並且在你的代碼中實際使用的)一起使用的話。 – Dmitri

回答

0

這些選項不會安裝這些庫,而是告訴編譯器將您的程序與這些庫鏈接。我建議你使用一個makefile來替代,你可以通過簡單的鍵入「make」來編譯一次和稍後編譯選項。 如果您嘗試使用尚未添加到makefile中的新庫,則可以隨時更新您的生成文件。 Cmake是提供可移植性選項的另一種選擇。

+0

我不認爲OP對'-l'選項的含義感到困惑,但使用'make'仍然是一個很好的建議。 –

+0

@JohnBollinger下面的聲明讓我覺得OP在鏈接和安裝之間有一些混淆。「有沒有一種方法可以安裝ssl,crypto和json庫,這樣我就不必輸入所有這些-l了? 「 –

+0

是的,這似乎表明他明白'-l'選項確實不安裝這些庫。 –

0

有沒有一種方法可以安裝ssl,crypto和json庫,因此我不必輸入所有這些-l的?

您已將它們安裝在您的機器上。否則,它不會編譯! 他們在那裏告訴鏈接器與這些庫鏈接。所以,如果您在應用程序中使用它們,則需要它們。沒有辦法避免它們。

只是,當我添加一個新的庫也並不總是很清楚,如果我得再添-l選項庫名稱

這很容易找出來。如果編譯失敗,那麼你缺少一個或多個庫! (但編譯也可能因其他原因而失敗)。

想要比猜測更清楚地瞭解到底發生了什麼。

如果你已經編寫了應用程序,那麼很可能你會知道需要哪些庫。看起來你正在編譯你不完全理解的代碼。 在這種情況下,上面提到的「嘗試使用-lblah並在失敗時添加它」可能是您更簡單的選擇(也是可靠的方法)。

0

這只是當我添加一個新庫時,並不總是清楚我是否需​​要添加另一個-l libraryname選項。比猜測更清楚地瞭解到底發生了什麼。

首先,你需要了解添加#include指令對於給定頭文件和鏈接到一個給定的之間的差異。庫是一個預先編譯的外部函數和/或變量的集合,它們打包在一起,以便您可以在程序中使用它們,而無需在每個程序的源代碼中構建它們。頭文件(通常)爲函數和變量提供聲明,並且可能爲相關數據類型和宏提供,例如給定庫提供的函數和變量。

任何包含對給定函數的調用或給定變量訪問的源文件都必須預先聲明函數/變量。使這種方便並儘量減少錯誤的範圍是頭文件的原因。程序使用的所有函數和變量的實現必須同時鏈接以產生可執行文件。因此,無論何時使用一個你自己不提供的實現的函數或變量,你都需要知道兩件事情:它的聲明在哪裏(或什麼),它的實現在哪裏。首先是關於要包含哪個頭文件;後者是關於什麼庫需要包含在鏈接中。

請注意,這甚至適用於C標準庫。您需要爲每個要使用的標準庫函數包含適當的頭文件。大多數現代編譯器會自動將大多數標準庫鏈接到任何程序,但是歷史上,有些需要您明確鏈接它,即使在今天,如果您要使用任何一種編譯器,許多編譯器都需要顯式地鏈接包含數學函數的庫他們。

,你提出了一個錯誤的問題,因爲這些庫,你需要鏈接是不是(通常)依賴於您包括頭文件。 這兩個取決於你使用哪些變量和函數,這兩個問題最好通過查閱這些函數和變量的文檔來回答。

如果失敗了,您可以依靠編譯器來告訴您關於未聲明的函數,並且您應該可以依靠它來告訴您關於未聲明的變量 - 這可以幫助您確定何時需要包含額外的頭文件。您還應該能夠依賴鏈接器來告訴您關於沒有提供實現的函數和變量 - 這可以幫助您確定何時需要鏈接其他庫。

有沒有一種方法可以安裝ssl,crypto和json庫,所以我不必輸入所有這些-l的?

技術上,是的。您可以下載它們的源代碼,與現有源一起構建它,並將所有必需的目標文件鏈接在一起以獲取最終的可執行文件。您可能需要遞歸執行這些源包含。通過這種方式,您可以在不使用任何-l選項的情況下構建您的程序,代價是需要您無法親自輸入的構建命令。

這讓我想到構建系統的主題,如make。使用一個。大概make本身,直接。這將爲您節省重複鍵入,確保您始終使用所有必需的選項進行構建(一旦您確定了這些選項),並記錄構建過程和需求。對於像你看起來是那麼簡單的一個項目,一個Makefile相似,這可能已經足夠了:

LDLIBS = -lssl -lcrypto -ljson 

all: edgeclient 

Makefile並把它放在同一個目錄中edgeclient.c。把它作爲你的工作目錄,運行make命令並觀察它。有許多方法可以修飾它,並且可以通過一些方法修改需要修飾的項目(例如添加更多源文件),但這應該足以讓您開始,至少在GNU make和GNU工具鏈。