2014-10-20 103 views
-1

我現在有兩個unix系統,一個用於服務,另一個用於構建(具有所有要構建的環境,但它是舊的)。我需要在服務機器中使用python中的lxml。以下命令我想:如何在Unix/Linux系統中創建lxml的靜態構建?

python setup.py build --static-deps 

CFLAGS="-g -O2 -fPIC" 
python setup.py build --static-deps 

但結果是:

ld: fatal: relocations remain against allocatable but non-writable sections 
collect2: ld returned 1 exit status 
error: command '/usr/lib/python2.6/pycc' failed with exit status 1 

我想知道我怎樣才能使一個靜電積聚,這樣我可以很容易地部署到我的服務箱?

另外,如果我

python setup.py build 

它沒有錯誤,但如果我:

Python 2.6.4 (r264:75706, Apr 17 2011, 11:24:50) [C] on sunos5 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from lxml import etree 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: ld.so.1: isapython2.6: fatal: relocation error: file /usr/lib/python2.6/site-packages/lxml/etree.so: symbol __xmlStructuredErrorContext: referenced symbol not found 

我搜索它:get errors when import lxml.etree to python 似乎並不有一個很好的答案。我認爲這是鏈接問題,所以我認爲它靜態鏈接應該是一個更好的解決方案。

但我的主要目標是減少在部署中花費的工作,所以我會接受任何簡單的方法。

請大家幫忙。提前致謝。

+0

首先,您是否擁有完全相同的Python版本並在兩臺機器上構建?其次,你是否有依賴關係的靜態庫('libxml2.a','libxslt.a','libz.a',或者它需要的東西)? – abarnert 2014-10-20 21:56:45

+0

我認爲是蟒蛇版本。第二個問題是什麼意思?我有這些庫的.so庫,否則,'python setup.py build'不會通過,對吧?根據doc,'python setup.py build --static-deps'將會下載最新的libxml2和libxslt,它就是這樣。 – HuStmpHrrr 2014-10-20 23:00:51

+0

如果你構建了一個與'.so'鏈接的東西,它將在運行時需要'.so'。這可能是你的問題。 – abarnert 2014-10-20 23:10:31

回答

3

這個問題似乎是你試圖建立一個沒有靜態依賴關係的靜態庫。

靜態庫,如libxml2.a,只是對象的存檔(.o文件)。鏈接時,鏈接器會將您從這些對象中調用的任何函數的代碼複製到鏈接目標中。所以,結果將是一個獨立的目標,不需要libxml2.a運行;當你從libxml2調用函數時,一切正常,因爲代碼在你的庫中。

共享庫,如libxml2.so,基本上是一個可執行文件。鏈接器鏈接時,鏈接器會創建重定位條目,以便當您的目標和libxml2.so同時加載到內存中時,由於代碼位於libxml2.so中,所以您調出的任何函數都可以工作。

你想在這裏做的是實際上建立一個混合:一個共享庫(因此它可以作爲一個模塊加載),可能動態鏈接到libpython.so(也可能是內置於操作系統的其他東西),但是從libxml2(和libxslt2)的代碼中靜態鏈接。

一個現代的鏈接器完全沒有問題 - 但它需要靜態庫libxml2來做到這一點。

所以,你需要得到libxml2.a(和libxslt2.a,甚至可能是libz.a)安裝之前,你可以建立你想要的。


我在這裏稍微簡化了一點。在某些平臺上,.so文件實際上只是真正的共享對象的前端,基本上是重定位表加上實際文件的鏈接。在其他平臺上,可以從.so文件中取出代碼,並在原地「重新定位」,.a文件可以只是類似的前端到共享對象。還有一些平臺與ELF截然不同,這個術語更具誤導性而非實用性。

如果您想了解更多信息,請從this question以及其他相關的問題開始。

如果你不這樣做,只要相信你需要.a文件就可以靜態鏈接任何東西。只要

在Linux(和大多數其他乖巧的操作系統),pip將設法構建源分佈:


如果你讀了installation文檔,你會發現, libxml2libxslt已正確安裝,包括開發包(即頭文件等)。如果構建失敗,請使用包管理工具查找類似libxml2-devlibxslt-devel的包,並確保它們已安裝。 或者,設置STATIC_DEPS=true將自動下載並構建兩個庫。

所以,如果你沒有這些庫都,建設lxml將下載的依賴性,構建了.a文件給你,並且對他們的鏈接。

但是,如果你做的他們,然後(一)pkg-config和/或xml2-config是要找到並使用它們,和(b),即使沒有,lxml最終可能-lxml2不是建立絕對路徑爲libxml2.a,並且無論如何都鏈接錯誤的路徑。

你怎麼能解決這個問題?那麼,你會認爲會有一個簡單的標誌,告訴它不要這樣做,但據我所知,沒有。因此,您的選項包括:

  • 使用不包含libxml2libxslt2的假根構建。這在Building Debian packages文檔中鬆散地暗示。
  • 手動構建靜態僅libxml2libxslt2並通過絕對路徑向所得xml2-configxslt2-configsetup.py,如在Building the sources說明。
  • 暫時砍了xml2-configxslt2-config(或者,如果你沒有這些,通過pkg-config使用的.pc文件)使用絕對路徑.a文件LDFLAGS,而不是-L-l標誌。
  • 在構建lxml時(通過重命名它們,設置不同的路徑或其他方式),暫時將.so文件從您的庫路徑中取出。
  • 假設版本號與您安裝的.so文件的版本號不同(或可能不同),您可以按照Mac build instructions指定明確的版本號來作弊。您可能必須手動下載tarball才能正常工作,但您不必構建它們。

如果這一切看起來像是一種痛苦,而且應該很容易......好的,請記住你在這裏要做的事情。 Linux是圍繞構建源代碼發佈的想法而設計的,它是您的特定系統可能的最佳方式。如果您的系統具有xml2和xslt2的共享庫,則設置所有內容以嘗試使用它們。如果你想構建代碼來部署到沒有這些系統的系統,那麼你的開發系統預計也沒有它們;如果確實如此,你應該知道如何解決這個問題。

+0

嗨。我建立了一個新的虛擬機來測試它。我在我的新vm中找到了Debian,'python setup.py build --static-deps'很完美。而我在構建之前只有1個命令:'sudo apt-get install gcc build-essential binutils python-dev'。看起來並非如此,因爲你說我缺乏靜態庫。 – HuStmpHrrr 2014-10-21 00:03:41

+0

@HuStmpHrrr:我猜你的新VM沒有'libxml2.so'嗎? (或者也許它,但也有'libxml2.a',但這似乎不太可能。) – abarnert 2014-10-21 00:17:17

+0

不,我沒有。一切都很乾淨。我在開始時甚至沒有gcc。 – HuStmpHrrr 2014-10-21 00:53:46