A. 如何編譯OpenWrt
搭建編譯環境。編譯建議在linux下進行。我的系統是Linux mint 17,執行以下命令,構建編譯環境:
sudo apt-get update
sudo apt-get install git-core build-essential
獲取openwrt源碼。在當前用戶主目錄下執行
git clone git://git.openwrt.org/openwrt.git
等待代碼下載。結束後,目錄下會出現openwrt文件夾。
配置軟體源。進入openwrt目錄,執行
./scripts/feeds update -a
./scripts/feeds install -a
檢查編譯環境是否完整:
make defconfig
make prereq
根據提示信息安裝需要的軟體包。如果提示類似
「tmp/.config-package.in:22022:warning: multi-line strings not supported」
的信息,打開 openwrt/tmp/.config-package.in,定位到對應行,添上丟掉的一個引號就可以了。
編譯選項:
執行 make menuconfig,根據路由器情況,選擇 Target System 和 Subtarget。如意雲一代和極壹S的 Target System 均為 Ralink RT288x/RT3xxx 。對於Subtarget ,前者為 MT7620n based boards ,後者為 MT7620a based boards。
其他選項根據個人喜好選擇。一般來說要選中LuCI界面,選中中文語言包等等。
開始編譯:
執行 make -j2 V=s 進行編譯。-j後面的數字是電腦物理CPU數量加一。V=s可以顯示出編譯的詳細信息。首次編譯大概需要幾個小時的時間。
錯誤排查:
編譯失敗,一般有兩種情況:
1.代碼下載鏈接失效。首次編譯時,編譯程序會實時從網上下載一些軟體包的代碼。如果下載鏈接失效,編譯就會失敗。這時需要根據軟體包的名稱,從網上自行下載,然後放在 openwrt/dl/ 目錄下,執行 make -j2 V=s 繼續編譯即可。
2.軟體包自身有問題。這時重新執行 make menuconfig ,取消對應軟體包選中即可。這種情況比較少見,目前已知的有 tor 等。
編譯成功,但沒有生成固件。這種情況一般是因為選中的軟體包過多,導致固件大小超過16MB。重新執行 make menuconfig,去掉一些軟體包,重新執行編譯即可。
得到固件。在排除了所有錯誤後,現在終於得到了固件。對於如意雲RY-1,固件在 openwrt/bin/ramips 目錄下,形如
openwrt-ramips-mt7620n-rt-n14u-squashfs-sysupgrade.bin
openwrt-ramips-mt7620n-wrtnode-squashfs-sysupgrade.bin
openwrt-ramips-mt7620n-mlw221-squashfs-sysupgrade.bin
openwrt-ramips-mt7620n-wr8305rt-squashfs-sysupgrade.bin
等等。
B. 編譯openwrt時,更改某個軟體版本
更改方式如下:
1、在伺服器上山塌安裝一個較高版逗告圓本的gcc,例如gcc4.8,需當前系統正在使用的gcc不需要發生改變。
2、修改openwrt中rule.mk文件友鬧。
C. 如何為現有的openwrt編譯一個opkg上沒有的軟體
一、安裝編譯環境(以ubuntu10.10為例)
依次輸入以下命令:
1.ubuntu開發環境需要的軟體:
sudo
apt-get install gcc g++ binutils patch bzip2 flex bison make autoconf
gettext texinfo unzip sharutils subversion libncurses5-dev ncurses-term
zlib1g-dev gawk
sudo apt-get update
2.創建目錄
mkdir openwrt
3.獲取OpenWrt源代碼和安裝包,更新
svn checkout svn://svn.openwrt.org/openwrt/backfire
cd backfire
./scripts/feeds update -a
./scripts/feeds install -a
4.配置編譯選項
make menuconfig
在target system里選擇Broadcom BCM63xx,根據需要選擇其他的軟體,
*:表示該模塊直接編譯到核心中
M:該模塊以被核心支持,可以後再安裝
空白:不支持該模塊
具體模塊的起什麼作用需要多google;
5.編譯選項配置保存後,開始編譯
make V=99
V=99表示輸出詳細的debug信息;
二、編譯准備
1.下載源文件
下載地址:http://ftp.awk.cz/cntlm/ ,最新的版本是0.91rc6;
2.獲取md5sum碼
進入下載文件目錄,在終端里輸入
md5sum cntlm-0.91rc6.tar.gz
獲得md5驗證碼:
3.編寫makefile文件
在openwrt/backfire目錄中的package目錄下新建cntlm目錄,在cntlm目錄下新建文件,命名為makefile,編輯makefile文件,加入如下內容:
---------------------------------------------------------------------------------------------------------------------------
#
# Copyright (C) 2006-2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=cntlm
PKG_VERSION:=0.91rc6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://ftp.awk.cz/cntlm/
PKG_MD5SUM:=
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/cntlm
SUBMENU:=Proxy Servers
SECTION:=net
CATEGORY:=Network
TITLE:=Cntlm is a Fast NTLM Authentication Proxy
URL:=http://cntlm.sourceforge.net/
endef
define Package/cntlm/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/cntlm $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/share/man/man1
$(CP) $(PKG_INSTALL_DIR)/usr/share/man/man1/$(PKG_NAME).1 $(1)/usr/share/man/man1
$(INSTALL_DIR) $(1)/etc/
$(CP) $(PKG_INSTALL_DIR)/etc/cntlm.conf $(1)/etc/
endef
$(eval $(call BuildPackage,cntlm))
---------------------------------------------------------------------------------------------------------------------------
4.編寫patch文件
由於BCM63xx核心是big
endian,而我們常用的intel或AMD的cpu都是little
endian的,cntlm雖然能夠自己檢測編譯環境的endian,但我們是在交叉編譯環境中編譯,cntlm檢測出來的還是ubuntu系統的endian,因此需要設置手動endian為big
endian。具體就是將源碼文件中的config/endian.c文件的rc設定為0.
將源碼文件中的endian.c文件分別復制到a目錄下的config目錄和b目錄下的config目錄,打開b目錄下的config目錄中的endian.c文件,並將其修改為:
-------------------------------------------------------------------------------------------------------------------------
#include
#include
int main(int argc, char **argv) {
int rc;
rc = 0;
printf("%s\n", rc ? "little endian" : "big endian");
return rc;
}
---------------------------------------------------------------------------------------------------------------------------
然後保存。
運行:
diff -Naur a/config/endian.c b/config/endian.c >endian.patch
endian.patch文件內容如下:
---------------------------------------------------------------------------------------------------------------------------
--- a/config/endian.c 2007-08-20 07:23:17.000000000 +0800
+++ b/config/endian.c 2010-11-01 18:36:32.000000000 +0800
@@ -1,15 +1,11 @@
#include
#include
-uint8_t num[] = { 0xEF, 0xBE };
-/*
- * RC: 1 = LE, 0 = BE
- */
int main(int argc, char **argv) {
int rc;
- rc = (*((uint16_t *)num) == 0xBEEF);
+ rc = 0;
printf("%s\n", rc ? "little endian" : "big endian");
return rc;
---------------------------------------------------------------------------------------------------------------------------
將endian.patch文件復制到package/cntlm/patches/目錄下(沒有patches目錄就新建一個)。
三、編譯
1.選定安裝包
終端輸入:
make menuconfig
在Network——》Proxy Severs中選擇cntlm;
2.開始編譯
終端輸入:
make package/cntlm/compile V=99
中間可能會出現一些提示(Note),可以不用理會。編譯完成後在bin/packages目錄下可以看到cntlm_0.91rc6-1_brcm63xx.ipk文件啦。
四、補充
上面提到在編譯過程中出會現提示(Note),一般如下:
utils.c:1: note: someone does not honour COPTS correctly, passed 0 times
這是由於cntlm源碼文件中CFLAG的設置是覆蓋而不是續接,與openwrt要求不同,在openwrt一般寫成CFLAG += 的方式。可以通過如下修改去除note:
將源碼包中的Makefile文件復制到a目錄和b目錄,打開b目錄下的Makefile文件,作如下修改:
CFLAGS+=$(FLAGS)
即增加上面的「+」號,保存。
運行:
diff -Naur a/Makefile b/Makefile > makefile.patch
得到的makefile.patch文件如下:
---------------------------------------------------------------------------------------------------------------------------
--- a/Makefile 2010-04-29 19:18:58.000000000 +0800
+++ b/Makefile 2010-11-09 20:17:33.405177000 +0800
@@ -16,7 +16,7 @@
CC=gcc
VER=`cat VERSION`
OBJS=utils.o ntlm.o xcrypt.o config.o socket.o acl.o auth.o http.o forward.o direct.o scanner.o pages.o main.o
-CFLAGS=$(FLAGS)
-std=c99 -Wall -pedantic -O3 -D__BSD_VISIBLE -D_ALL_SOURCE
-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112 -D_ISOC99_SOURCE
-D_REENTRANT -DVERSION=\"`cat VERSION`\" -g
+CFLAGS+=$(FLAGS)
-std=c99 -Wall -pedantic -O3 -D__BSD_VISIBLE -D_ALL_SOURCE
-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112 -D_ISOC99_SOURCE
-D_REENTRANT -DVERSION=\"`cat VERSION`\" -g
OS=$(shell uname -s)
OSLDFLAGS=$(shell [ $(OS) = "SunOS" ] && echo "-lrt -lsocket -lnsl")
LDFLAGS:=-lpthread $(OSLDFLAGS)
---------------------------------------------------------------------------------------------------------------------------
將makefile.patch文件復制到package/cntlm/patches目錄下,重新編譯即可。
D. 如何安裝tar.gz,或者製作ipk安裝包
有兩種方式安裝:
登錄路由web界面(一般是192.168.1.1),在openwrt的軟體安裝界面上選擇上傳安裝。
登錄openwrt控制台,可用ssh登錄或通過路由的TTL介面在控制台用命令進行安裝:用winscp將下載的ipk安裝包上傳到路由器中,用命令opkg install xxx.ipk安裝即可。
很多新手對linux下的軟體安裝存在誤解,現在簡單解釋一下:
這類源代碼包需要解壓後(tar.gz的用tarzxvf解壓,tar.bz2的用tarjxvf解壓),進入解壓目錄,一般都有一個INSTALL的文本文件,裡面一般都是安裝的詳細說明,可以用vi、nano、pico或X下面的文本編輯器(如gedit,gvim,kedit等)打開查看,安裝一般就是三個步驟:
1、configure,這一步一般用來生成Makefile,為下一步的編譯做准備,你可以通過在configure後加上參數來對安裝進行控制,比如代碼:
./configure--prefix=/usr
上面的意思是將該軟體安裝在/usr下面,執行文件就會安裝在/usr/bin(而不是默認的/usr/local/bin),資源文件就會安裝在/usr/share(而不是默認的/usr/local/share)。同時一些軟體的配置文件你可以通過指定--sys-config=參數進行設定。有一些軟體還可以加上--with、--enable、--without、--disable等等參數對編譯加以控制,你可以通過允許./configure--help察看詳細的說明幫助。
2、make,這一步就是編譯,大多數的源代碼包都經過這一步進行編譯(當然有些perl或python編寫的軟體需要調用perl或python來進行編譯)。如果在make過程中出現error,你就要記下錯誤代碼(注意不僅僅是最後一行),然後你可以向開發者提交bugreport(一般在INSTALL里有提交地址),或者你的系統少了一些依賴庫等,這些需要自己仔細研究錯誤代碼。
3、makeinsatll,這條命令來進行安裝(當然有些軟體需要先運行makecheck或maketest來進行一些測試),這一步一般需要你有root許可權(因為要向系統寫入文件)。
安裝完畢後你就可以刪除解壓目錄了。採用源代碼編譯方式來安裝軟體是Linux系統下最常見的安裝軟體方法,而且這種方法使你可以更加自由地控制安裝細節,所以提倡大家多使用該方法安裝軟體。
PS:對於bin類型的安裝文件,一般給該文件加上可執行許可權,再運行之即可
E. 如何編譯OpenWrt
准備工作
在開始編譯Openwrt之前需要您做些准備工作;與其他編譯過程一樣,類似的編譯工具和編譯環境是必不可少的:
一個構建OpenWrt映像的系統平台,簡單說就是准備一個操作系統(比如Ubuntu、Debian等);
確保安裝了所需的依賴關系庫, (在debian系統中就是安裝各種需要的軟體包)
OpenWrt源代碼副本
首先, 開機登陸到支持編譯Openwrt的操作系統(廢話了)。實體機或者虛擬機(Vmware 或者 Qemu)里的操作系統都行,這里推薦使用Linux系統。 bsd和mac osx系統也可以編,但不推薦,且未驗證是否可編譯成功。下文假定您使用的是Debian操作系統,使用 apt-get 來管理包. 替代的選擇是 Ubuntu (分支 Kubuntu, Xubuntu 等即可)。
第二步, 就是安裝所需要的各種軟體包, 包括編譯器,解壓工具,特定的庫等. 這些工作可以簡單的通過鍵入以下命令 (通常需要root 或者是 sudo 許可權),以root許可權安裝下列軟體包(可能並不完整,會有提示,提示缺少即裝就可以了):
32位(x86)請執行下列命令:
# apt-get install build-essential asciidoc binutils bzip2 gawk gettext \
git libncurses5-dev libz-dev patch unzip zlib1g-dev
64位(x86_64)請執行下列命令(多裝了哪些庫或軟體包呢?請您仔細看一看哦):
# apt-get install build-essential asciidoc binutils bzip2 gawk gettext \
git libncurses5-dev libz-dev patch unzip zlib1g-dev ia32-libs \
lib32gcc1 libc6-dev-i386
參考 本列表中 所列的編譯環境所需要軟體包或庫。
某些依賴的為庫或軟體包也許操作系統中已經安裝過,此時apt-get會作出提示(提示您忽略或重新安裝的),別緊張,放輕鬆些,編譯Openwrt不會像編譯DD-WRT那樣難的(至少本人是體會到了編譯DD-WRT的難)。
最後下載一份完整的 Openwrt 源碼到編譯環境中。關於Openwrt的源代碼下載,途徑有二,一是通過 svn ,一是通過 git,建議使用 svn ,因為Openwrt主要以 svn 來維護Openwrt系統的版本。另外,請注意Openwrt中不同的分支版本,一個是用得較多的開發快照,俗稱 trunk,二是穩定版,俗稱 backfire。
F. 我想為openwrt編譯一個軟體包,應該怎麼辦
下面是Makefile中一些約定俗成的目標名稱及其含義:
all
編譯整個軟體包,但不重建任何文檔。一般此目標作為默認的終極目標。此目標一般對所有源程序的編譯和連接使用"-g"選項,以使最終的可執行程序中包含調試信息。可使用 strip 程序去掉這些調試符號。
clean
清除當前目錄下在 make 過程中產生的文件。它不能刪除軟體包的配置文件,也不能刪除 build 時創建的那些文件。
distclean
類似於"clean",但增加刪除當前目錄下的的配置文件、build 過程產生的文件。
info
產生必要的 Info 文檔。
check 或 test
完成所有的自檢功能。在執行檢查之前,應確保所有程序已經被創建(但可以尚未安裝)。為了進行測試,需要實現在程序沒有安裝的情況下被執行的測試命令。
install
完成程序的編譯並將最終的可執行程序、庫文件等拷貝到指定的目錄。此種安裝一般不對可執行程序進行 strip 操作。
install-strip
和"install"類似,但是會對復制到安裝目錄下的可執行文件進行 strip 操作。
uninstall
刪除所有由"install"安裝的文件。
installcheck
執行安裝檢查。在執行安裝檢查之前,需要確保所有程序已經被創建並且被安裝。
installdirs
創建安裝目錄及其子目錄。它不能更改軟體的編譯目錄,而僅僅是創建程序的安裝目錄。
下面是 Makefile 中一些約定俗成的變數名稱及其含義:
這些約定俗成的變數分為三類。第一類代表可執行程序的名字,例如 CC 代表編譯器這個可執行程序;第二類代表程序使用的參數(多個參數使用空格分開),例如 CFLAGS 代表編譯器執行時使用的參數(一種怪異的做法是直接在 CC 中包含參數);第三類代表安裝目錄,例如 prefix 等等,含義簡單,下面只列出它們的默認值。
AR 函數庫打包程序,可創建靜態庫.a文檔。默認是"ar"。
AS 匯編程序。默認是"as"。
CC C編譯程序。默認是"cc"。
CXX C++編譯程序。默認是"g++"。
CPP C/C++預處理器。默認是"$(CC) -E"。
FC Fortran編譯器。默認是"f77"。
PC Pascal語言編譯器。默認是"pc"。
YACC Yacc文法分析器。默認是"yacc"。
ARFLAGS 函數庫打包程序的命令行參數。默認值是"rv"。
ASFLAGS 匯編程序的命令行參數。
CFLAGS C編譯程序的命令行參數。
CXXFLAGS C++編譯程序的命令行參數。
CPPFLAGS C/C++預處理器的命令行參數。
FFLAGS Fortran編譯器的命令行參數。
PFLAGS Pascal編譯器的命令行參數。
YFLAGS Yacc文法分析器的命令行參數。
LDFLAGS 鏈接器的命令行參數。
prefix /usr/local
exec_prefix $(prefix)
bindir $(exec_prefix)/bin
sbindir $(exec_prefix)/sbin
libexecdir $(exec_prefix)/libexec
datadir $(prefix)/share
sysconfdir $(prefix)/etc
sharedstatedir $(prefix)/com
localstatedir $(prefix)/var
libdir $(exec_prefix)/lib
infodir $(prefix)/info
includedir $(prefix)/include
oldincludedir $(prefix)/include
mandir $(prefix)/man
srcdir 需要編譯的源文件所在的目錄,無默認值