[{"data":1,"prerenderedAt":825},["ShallowReactive",2],{"wiki-page-/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch3-cha-jian-kai-fa":3,"wiki-doc-items-/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch3-cha-jian-kai-fa":797},{"id":4,"title":5,"body":6,"chapter":783,"chapterSort":784,"date":785,"description":35,"docKey":786,"docRoot":787,"docTitle":788,"extension":789,"isWikiDoc":80,"isWikiIndex":790,"layout":791,"meta":792,"navigation":80,"path":793,"seo":794,"stem":795,"wikiDepth":60,"__hash__":796},"content/wiki/2021-09-16-OpenWrt编译教学/ch3-插件开发.md","插件开发",{"type":7,"value":8,"toc":780},"minimark",[9,14,26,36,40,49,416,425,542,547,550,565,776],[10,11,13],"h3",{"id":12},"插件源码的文件组成openwrt插件一般使用mvc结构","插件源码的文件组成Openwrt插件一般使用\"MVC\"结构：",[15,16,17],"ol",{},[18,19,20,21,25],"li",{},"配置文件\n位于 ",[22,23,24],"code",{},"/etc/config/*","：",[27,28,33],"pre",{"className":29,"code":31,"language":32},[30],"language-text","config server\noption username ''\noption password ''\n","text",[22,34,31],{"__ignoreMap":35},"",[37,38,39],"p",{},"例示文件中生成了两个待输入的配置。现在需要一个表单页面来管理它。",[15,41,43],{"start":42},2,[18,44,45,46,25],{},"CBI文件\n一般位于目录 ",[22,47,48],{},"/usr/lib/lua/luci/model/cbi/*.lua",[27,50,54],{"className":51,"code":52,"language":53,"meta":35,"style":35},"language-lua shiki shiki-themes github-light github-dark","require(\"luci.sys\")\n\n-- 页面标题和描述\nm = Map(\"bargo\", translate(\"Bargo Client\"), translate(\"Configure Bargo client, Powered By Sinchie.\"))\n\n-- 读取配置文件\ns = m:section(TypedSection, \"server\", \"\")\ns.addremove = false\ns.anonymous = true\n\n-- 是否启用的选择框\nenable = s:option(Flag, \"enable\", translate(\"Enable\"))\n-- 映射我们的配置到输入框\nusername = s:option(Value, \"username\", translate(\"Username\"))\npass = s:option(Value, \"password\", translate(\"Password\"))\npass.password = true\n\n-- 如果点击了保存按钮\nlocal apply = luci.http.formvalue(\"cbi.apply\")\nif apply then\n    -- 这里是调用我们自己的程序脚本，后面会讲怎么来写这个脚本\n    io.popen(\"/etc/init.d/bargo restart > /dev/null &\")\nend\n\nreturn m\n","lua",[22,55,56,76,82,89,131,136,142,173,188,201,206,212,245,251,282,312,325,330,336,366,377,383,396,402,407],{"__ignoreMap":35},[57,58,61,65,69,73],"span",{"class":59,"line":60},"line",1,[57,62,64],{"class":63},"sj4cs","require",[57,66,68],{"class":67},"sVt8B","(",[57,70,72],{"class":71},"sZZnC","\"luci.sys\"",[57,74,75],{"class":67},")\n",[57,77,78],{"class":59,"line":42},[57,79,81],{"emptyLinePlaceholder":80},true,"\n",[57,83,85],{"class":59,"line":84},3,[57,86,88],{"class":87},"sJ8bj","-- 页面标题和描述\n",[57,90,92,95,99,102,104,107,110,113,115,118,121,123,125,128],{"class":59,"line":91},4,[57,93,94],{"class":67},"m ",[57,96,98],{"class":97},"szBVR","=",[57,100,101],{"class":63}," Map",[57,103,68],{"class":67},[57,105,106],{"class":71},"\"bargo\"",[57,108,109],{"class":67},", ",[57,111,112],{"class":63},"translate",[57,114,68],{"class":67},[57,116,117],{"class":71},"\"Bargo Client\"",[57,119,120],{"class":67},"), ",[57,122,112],{"class":63},[57,124,68],{"class":67},[57,126,127],{"class":71},"\"Configure Bargo client, Powered By Sinchie.\"",[57,129,130],{"class":67},"))\n",[57,132,134],{"class":59,"line":133},5,[57,135,81],{"emptyLinePlaceholder":80},[57,137,139],{"class":59,"line":138},6,[57,140,141],{"class":87},"-- 读取配置文件\n",[57,143,145,148,150,154,157,160,163,166,168,171],{"class":59,"line":144},7,[57,146,147],{"class":67},"s ",[57,149,98],{"class":97},[57,151,153],{"class":152},"sScJk"," m",[57,155,156],{"class":67},":",[57,158,159],{"class":63},"section",[57,161,162],{"class":67},"(TypedSection, ",[57,164,165],{"class":71},"\"server\"",[57,167,109],{"class":67},[57,169,170],{"class":71},"\"\"",[57,172,75],{"class":67},[57,174,176,179,182,185],{"class":59,"line":175},8,[57,177,178],{"class":67},"s.",[57,180,181],{"class":152},"addremove",[57,183,184],{"class":97}," =",[57,186,187],{"class":63}," false\n",[57,189,191,193,196,198],{"class":59,"line":190},9,[57,192,178],{"class":67},[57,194,195],{"class":152},"anonymous",[57,197,184],{"class":97},[57,199,200],{"class":63}," true\n",[57,202,204],{"class":59,"line":203},10,[57,205,81],{"emptyLinePlaceholder":80},[57,207,209],{"class":59,"line":208},11,[57,210,211],{"class":87},"-- 是否启用的选择框\n",[57,213,215,218,220,223,225,228,231,234,236,238,240,243],{"class":59,"line":214},12,[57,216,217],{"class":67},"enable ",[57,219,98],{"class":97},[57,221,222],{"class":152}," s",[57,224,156],{"class":67},[57,226,227],{"class":63},"option",[57,229,230],{"class":67},"(Flag, ",[57,232,233],{"class":71},"\"enable\"",[57,235,109],{"class":67},[57,237,112],{"class":63},[57,239,68],{"class":67},[57,241,242],{"class":71},"\"Enable\"",[57,244,130],{"class":67},[57,246,248],{"class":59,"line":247},13,[57,249,250],{"class":87},"-- 映射我们的配置到输入框\n",[57,252,254,257,259,261,263,265,268,271,273,275,277,280],{"class":59,"line":253},14,[57,255,256],{"class":67},"username ",[57,258,98],{"class":97},[57,260,222],{"class":152},[57,262,156],{"class":67},[57,264,227],{"class":63},[57,266,267],{"class":67},"(Value, ",[57,269,270],{"class":71},"\"username\"",[57,272,109],{"class":67},[57,274,112],{"class":63},[57,276,68],{"class":67},[57,278,279],{"class":71},"\"Username\"",[57,281,130],{"class":67},[57,283,285,288,290,292,294,296,298,301,303,305,307,310],{"class":59,"line":284},15,[57,286,287],{"class":67},"pass ",[57,289,98],{"class":97},[57,291,222],{"class":152},[57,293,156],{"class":67},[57,295,227],{"class":63},[57,297,267],{"class":67},[57,299,300],{"class":71},"\"password\"",[57,302,109],{"class":67},[57,304,112],{"class":63},[57,306,68],{"class":67},[57,308,309],{"class":71},"\"Password\"",[57,311,130],{"class":67},[57,313,315,318,321,323],{"class":59,"line":314},16,[57,316,317],{"class":67},"pass.",[57,319,320],{"class":152},"password",[57,322,184],{"class":97},[57,324,200],{"class":63},[57,326,328],{"class":59,"line":327},17,[57,329,81],{"emptyLinePlaceholder":80},[57,331,333],{"class":59,"line":332},18,[57,334,335],{"class":87},"-- 如果点击了保存按钮\n",[57,337,339,342,345,347,350,353,356,359,361,364],{"class":59,"line":338},19,[57,340,341],{"class":97},"local",[57,343,344],{"class":67}," apply ",[57,346,98],{"class":97},[57,348,349],{"class":67}," luci.",[57,351,352],{"class":152},"http",[57,354,355],{"class":67},".",[57,357,358],{"class":63},"formvalue",[57,360,68],{"class":67},[57,362,363],{"class":71},"\"cbi.apply\"",[57,365,75],{"class":67},[57,367,369,372,374],{"class":59,"line":368},20,[57,370,371],{"class":97},"if",[57,373,344],{"class":67},[57,375,376],{"class":97},"then\n",[57,378,380],{"class":59,"line":379},21,[57,381,382],{"class":87},"    -- 这里是调用我们自己的程序脚本，后面会讲怎么来写这个脚本\n",[57,384,386,389,391,394],{"class":59,"line":385},22,[57,387,388],{"class":63},"    io.popen",[57,390,68],{"class":67},[57,392,393],{"class":71},"\"/etc/init.d/bargo restart > /dev/null &\"",[57,395,75],{"class":67},[57,397,399],{"class":59,"line":398},23,[57,400,401],{"class":97},"end\n",[57,403,405],{"class":59,"line":404},24,[57,406,81],{"emptyLinePlaceholder":80},[57,408,410,413],{"class":59,"line":409},25,[57,411,412],{"class":97},"return",[57,414,415],{"class":67}," m\n",[15,417,418],{"start":84},[18,419,420,421,424],{},"控制器文件\n一般位于系统的",[22,422,423],{},"/usr/lib/lua/luci/controller/*.lua","，创建控制器文件后可以在web界面创建一个界面入口（菜单）。脚本结构如下：",[27,426,428],{"className":51,"code":427,"language":53,"meta":35,"style":35},"-- module 名称\nmodule(\"luci.controller.bargo\", package.seeall)\n\nfunction index()\n    -- 4 个参数介绍\n    -- 1.后台访问路径 admin/services/bargo \n    -- 2.target 动作（call, template, cbi）call 是调用自定义函数，template 调用 html 模板，cbi 调用 openwrt 的公共表单页面\n    -- 3.菜单名称 \n    -- 4.排序\n    entry({\"admin\", \"services\", \"bargo\"}, cbi(\"bargo\"), _(\"Bargo Client\"), 1)\nend\n",[22,429,430,435,452,456,467,472,477,482,487,492,538],{"__ignoreMap":35},[57,431,432],{"class":59,"line":60},[57,433,434],{"class":87},"-- module 名称\n",[57,436,437,440,442,445,447,450],{"class":59,"line":42},[57,438,439],{"class":63},"module",[57,441,68],{"class":67},[57,443,444],{"class":71},"\"luci.controller.bargo\"",[57,446,109],{"class":67},[57,448,449],{"class":63},"package.seeall",[57,451,75],{"class":67},[57,453,454],{"class":59,"line":84},[57,455,81],{"emptyLinePlaceholder":80},[57,457,458,461,464],{"class":59,"line":91},[57,459,460],{"class":97},"function",[57,462,463],{"class":152}," index",[57,465,466],{"class":67},"()\n",[57,468,469],{"class":59,"line":133},[57,470,471],{"class":87},"    -- 4 个参数介绍\n",[57,473,474],{"class":59,"line":138},[57,475,476],{"class":87},"    -- 1.后台访问路径 admin/services/bargo \n",[57,478,479],{"class":59,"line":144},[57,480,481],{"class":87},"    -- 2.target 动作（call, template, cbi）call 是调用自定义函数，template 调用 html 模板，cbi 调用 openwrt 的公共表单页面\n",[57,483,484],{"class":59,"line":175},[57,485,486],{"class":87},"    -- 3.菜单名称 \n",[57,488,489],{"class":59,"line":190},[57,490,491],{"class":87},"    -- 4.排序\n",[57,493,494,497,500,503,505,508,510,512,515,518,520,522,524,527,529,531,533,536],{"class":59,"line":203},[57,495,496],{"class":63},"    entry",[57,498,499],{"class":67},"({",[57,501,502],{"class":71},"\"admin\"",[57,504,109],{"class":67},[57,506,507],{"class":71},"\"services\"",[57,509,109],{"class":67},[57,511,106],{"class":71},[57,513,514],{"class":67},"}, ",[57,516,517],{"class":63},"cbi",[57,519,68],{"class":67},[57,521,106],{"class":71},[57,523,120],{"class":67},[57,525,526],{"class":63},"_",[57,528,68],{"class":67},[57,530,117],{"class":71},[57,532,120],{"class":67},[57,534,535],{"class":63},"1",[57,537,75],{"class":67},[57,539,540],{"class":59,"line":208},[57,541,401],{"class":97},[543,544,546],"h5",{"id":545},"创建构建文件makefile","创建构建文件Makefile",[37,548,549],{},"制作 OpenWRT 编译 Makefile 文件需要以下步骤：",[15,551,552,555,558],{},[18,553,554],{},"安装 OpenWRT SDK，并设置环境变量",[18,556,557],{},"在任意目录下，创建一个新的文件夹，用于存放你的应用程序代码",[18,559,560,561,564],{},"在该目录下，创建 ",[22,562,563],{},"Makefile"," 文件，并按照以下结构填写相应内容：",[27,566,570],{"className":567,"code":568,"language":569,"meta":35,"style":35},"language-makefile shiki shiki-themes github-light github-dark","\n# 这是注释，可以忽略或者修改\n\ninclude $(TOPDIR)/rules.mk # 引入OpenWRT编译规则\nPKG_NAME:=myapp # 应用程序的名称，建议使用小写字母和数字组合\nPKG_VERSION:=1.0 # 应用程序的版本号\nPKG_RELEASE:=1 # 应用程序的发行版本号\n\ninclude $(INCLUDE_DIR)/package.mk # 引入OpenWRT中提供的软件包模板\ndefine Package/myapp # 描述应用程序的信息\n  SECTION:=net\n  CATEGORY:=Network\n  TITLE:=My Application\n  DEPENDS:=+libopenssl +libcurl +libjson-c \nendef\n\ndefine Package/myapp/description # 描述应用程序功能和用途\n My Application is a simple program that does something useful.\nendef\n\ndefine Build/Prepare # 准备构建应用程序所需的源码和资源\n\n# 此处可以添加自定义命令，用于准备应用程序的源码和资源\nendef\n\ndefine Build/Configure # 配置应用程序的编译选项\n\n# 此处可以添加自定义命令，用于配置应用程序的编译选项\nendef\n\ndefine Build/Compile # 编译应用程序的源码\n\n# 此处可以添加自定义命令，用于编译应用程序的源码\nendef\n\ndefine Package/myapp/install # 安装应用程序所需的文件和目录\n$(INSTALL_DIR) $(1)/usr/bin # 创建安装目录\n$(INSTALL_BIN) $(PKG_BUILD_DIR)/myapp $(1)/usr/bin/ # 安装二进制文件\nendef\n\n$(eval $(call BuildPackage,myapp)) # 构建软件包并注册到OpenWRT中\n","makefile",[22,571,572,576,581,585,590,595,600,605,609,614,619,624,629,634,639,644,648,653,658,662,666,671,675,680,684,688,694,699,705,710,715,721,726,732,737,742,748,754,760,765,770],{"__ignoreMap":35},[57,573,574],{"class":59,"line":60},[57,575,81],{"emptyLinePlaceholder":80},[57,577,578],{"class":59,"line":42},[57,579,580],{},"# 这是注释，可以忽略或者修改\n",[57,582,583],{"class":59,"line":84},[57,584,81],{"emptyLinePlaceholder":80},[57,586,587],{"class":59,"line":91},[57,588,589],{},"include $(TOPDIR)/rules.mk # 引入OpenWRT编译规则\n",[57,591,592],{"class":59,"line":133},[57,593,594],{},"PKG_NAME:=myapp # 应用程序的名称，建议使用小写字母和数字组合\n",[57,596,597],{"class":59,"line":138},[57,598,599],{},"PKG_VERSION:=1.0 # 应用程序的版本号\n",[57,601,602],{"class":59,"line":144},[57,603,604],{},"PKG_RELEASE:=1 # 应用程序的发行版本号\n",[57,606,607],{"class":59,"line":175},[57,608,81],{"emptyLinePlaceholder":80},[57,610,611],{"class":59,"line":190},[57,612,613],{},"include $(INCLUDE_DIR)/package.mk # 引入OpenWRT中提供的软件包模板\n",[57,615,616],{"class":59,"line":203},[57,617,618],{},"define Package/myapp # 描述应用程序的信息\n",[57,620,621],{"class":59,"line":208},[57,622,623],{},"  SECTION:=net\n",[57,625,626],{"class":59,"line":214},[57,627,628],{},"  CATEGORY:=Network\n",[57,630,631],{"class":59,"line":247},[57,632,633],{},"  TITLE:=My Application\n",[57,635,636],{"class":59,"line":253},[57,637,638],{},"  DEPENDS:=+libopenssl +libcurl +libjson-c \n",[57,640,641],{"class":59,"line":284},[57,642,643],{},"endef\n",[57,645,646],{"class":59,"line":314},[57,647,81],{"emptyLinePlaceholder":80},[57,649,650],{"class":59,"line":327},[57,651,652],{},"define Package/myapp/description # 描述应用程序功能和用途\n",[57,654,655],{"class":59,"line":332},[57,656,657],{}," My Application is a simple program that does something useful.\n",[57,659,660],{"class":59,"line":338},[57,661,643],{},[57,663,664],{"class":59,"line":368},[57,665,81],{"emptyLinePlaceholder":80},[57,667,668],{"class":59,"line":379},[57,669,670],{},"define Build/Prepare # 准备构建应用程序所需的源码和资源\n",[57,672,673],{"class":59,"line":385},[57,674,81],{"emptyLinePlaceholder":80},[57,676,677],{"class":59,"line":398},[57,678,679],{},"# 此处可以添加自定义命令，用于准备应用程序的源码和资源\n",[57,681,682],{"class":59,"line":404},[57,683,643],{},[57,685,686],{"class":59,"line":409},[57,687,81],{"emptyLinePlaceholder":80},[57,689,691],{"class":59,"line":690},26,[57,692,693],{},"define Build/Configure # 配置应用程序的编译选项\n",[57,695,697],{"class":59,"line":696},27,[57,698,81],{"emptyLinePlaceholder":80},[57,700,702],{"class":59,"line":701},28,[57,703,704],{},"# 此处可以添加自定义命令，用于配置应用程序的编译选项\n",[57,706,708],{"class":59,"line":707},29,[57,709,643],{},[57,711,713],{"class":59,"line":712},30,[57,714,81],{"emptyLinePlaceholder":80},[57,716,718],{"class":59,"line":717},31,[57,719,720],{},"define Build/Compile # 编译应用程序的源码\n",[57,722,724],{"class":59,"line":723},32,[57,725,81],{"emptyLinePlaceholder":80},[57,727,729],{"class":59,"line":728},33,[57,730,731],{},"# 此处可以添加自定义命令，用于编译应用程序的源码\n",[57,733,735],{"class":59,"line":734},34,[57,736,643],{},[57,738,740],{"class":59,"line":739},35,[57,741,81],{"emptyLinePlaceholder":80},[57,743,745],{"class":59,"line":744},36,[57,746,747],{},"define Package/myapp/install # 安装应用程序所需的文件和目录\n",[57,749,751],{"class":59,"line":750},37,[57,752,753],{},"$(INSTALL_DIR) $(1)/usr/bin # 创建安装目录\n",[57,755,757],{"class":59,"line":756},38,[57,758,759],{},"$(INSTALL_BIN) $(PKG_BUILD_DIR)/myapp $(1)/usr/bin/ # 安装二进制文件\n",[57,761,763],{"class":59,"line":762},39,[57,764,643],{},[57,766,768],{"class":59,"line":767},40,[57,769,81],{"emptyLinePlaceholder":80},[57,771,773],{"class":59,"line":772},41,[57,774,775],{},"$(eval $(call BuildPackage,myapp)) # 构建软件包并注册到OpenWRT中\n",[777,778,779],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":35,"searchDepth":42,"depth":42,"links":781},[782],{"id":12,"depth":84,"text":13},"3",3000000,"2021-09-16","2021-09-16-openwrt-bian-yi-jiao-xue","/wiki/2021-09-16-openwrt-bian-yi-jiao-xue","OpenWrt编译教学","md",false,null,{},"/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch3-cha-jian-kai-fa",{"title":5,"description":35},"wiki/2021-09-16-OpenWrt编译教学/ch3-插件开发","u-8IL1cxIuH5WtO8F6lXSXP45bYPjKo1wN_pPuCr9PI",[798,803,809,810,816,822],{"path":799,"stem":800,"title":801,"date":785,"chapter":535,"chapterSort":802,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":790},"/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch1-bian-yi-huan-jing-zhun-bei","wiki/2021-09-16-OpenWrt编译教学/ch1-编译环境准备","编译环境准备",1000000,{"path":804,"stem":805,"title":806,"date":785,"chapter":807,"chapterSort":808,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":790},"/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch2-ge-xing-hua-pei-zhi","wiki/2021-09-16-OpenWrt编译教学/ch2-个性化配置","个性化配置","2",2000000,{"path":793,"stem":795,"title":5,"date":785,"chapter":783,"chapterSort":784,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":790},{"path":811,"stem":812,"title":813,"date":785,"chapter":814,"chapterSort":815,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":790},"/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch4-bu-chong-gong-ju","wiki/2021-09-16-OpenWrt编译教学/ch4-补充工具","补充工具","4",4000000,{"path":817,"stem":818,"title":819,"date":785,"chapter":820,"chapterSort":821,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":790},"/wiki/2021-09-16-openwrt-bian-yi-jiao-xue/ch5-qi-ta-can-kao-zi-liao-tian-jia-usb-he-ying-pan-ge-shi-hai-you-wang-ka-jiao-cheng","wiki/2021-09-16-OpenWrt编译教学/ch5-其他参考资料添加USB和硬盘格式还有网卡教程：","其他参考资料添加USB和硬盘格式还有网卡教程：","5",5000000,{"path":787,"stem":823,"title":788,"date":785,"chapter":791,"chapterSort":824,"docKey":786,"docRoot":787,"docTitle":788,"isWikiDoc":80,"isWikiIndex":80},"wiki/2021-09-16-OpenWrt编译教学/index",0,1778560331485]