文档章节

OpenWRT开发之——对C++的支持(解决库依赖问题)

临峰不畏
 临峰不畏
发布于 2015/05/07 17:53
字数 3569
阅读 13178
收藏 8

C++是本人的强项。如果在OpenWrt中不能用C++进行开发,那就有点大失所望了。

接下来将与大家一起来尝试写一个C++程序,并把它做成 ipk 包,并试运行。


各文件内容

在 SDK/package/ 路径下创建 cpp-demo 目录,并生成一个非常简单的 cpp 程序

$ cd SDK
$ mkdir -p package/cpp-demo
$ cd package/cpp-demo
$ touch Makefile
$ mkdir src
$ cd src
$ touch Makefile main.cpp

形成如下目录结构:

$ tree package/demo-cpp
package/cpp-demo/
|-- Makefile
`-- src
    |-- main.cpp
    `-- Makefile


package/cpp-demo/src/main.cpp内容:

#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
    cout << "This is C++ Demo" << endl;
    return 0;
}


package/cpp-demo/src/Makefile内容:

target=cpp-demo

ALL:$(target)

objects=main.o

cpp-demo: $(objects)
    $(CXX) -o $(target) $(objects)

clean:
    @rm -rf $(objects)

注意:上面用的是CXX,而不是CC,就这点区别。


package/Makefile内容:

include $(TOPDIR)/rules.mk

PKG_NAME:=cpp-demo
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

define Package/cpp-demo
    SECTION:=utils
    CATEGORY:=Utilties
    TITLE:=cpp-demo
endef

define Build/Prepare
    $(MKDIR) -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)
endef

define Package/cpp-demo/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/cpp-demo $(1)/bin
endef

$(eval $(call BuildPackage,cpp-demo))


解决链接错误

在SDK目录下 make V=s,结果报错:

Package cpp-demo is missing dependencies for the following libraries:
libstdc++.so.6


对错误的初步认识

说是要依赖 libstdc++.so.6 这个库文件?

那好吧,在本地机上安装一个便是了。

$ sudo yum install libstdc++
...省略...
Package libstdc++-4.4.7-11.el6.i686 already installed and latest version
Nothing to do

说明本地已安排了libstdc++了的。难不成是版本对不上号?

我用 locate命令找了一下 libstdc++这个文件,发现存在 /usr/lib/libstdc++.so.6 文件。这应该就是上面需要的库吧。

应该在LD_LIBRARY_PATH环境变量中没有将 /usr/lib 加入到其中。如下:

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib make V=s

这次,报:

Package cpp-demo is missing dependencies for the following libraries:
libc.so.6
libm.so.6
libstdc++.so.6

不凑效?!


发现依赖的是目标机的动态库

不过静下心来想想,我编译cpp-demo需要的是开发机的动态库呢,还是目标机的动态库?

动态库是程序在运行起来后加载的库,那么cpp-demo在目标机上运行起来后,加载的动态库应该是目标机的,不应该是开发机的。所以,刚刚我在整开发机上的动态库,与这个应该是两码事儿。


在SDK路径下搜所有的动态库文件:

$ find -name lib*.so.*
./staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libzmq.so.4
./staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libevent_openssl-2.0.so.5
./staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libpopt.so.0.0.0
...<略>
./staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/mysql/libmysqlclient.so.16
./staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/mysql/libmysqlclient_r.so.16.0.0
...<略>
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib/libc.so.0
./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib/libstdc++.so.6
...<略>
./staging_dir/host/lib/libltdl.so.7
./staging_dir/host/lib/liblzma.so.5

有很多,也看到了 libstdc++.so.6

应该是在链接时将 libstdc++.so.6 所在的路径加进来吧。就像:

g++ -L./staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib/ -lstdc++

这样。


排除编译错误

我们检查编译调试信息打印出来的LDFLAGS的值:

LDFLAGS="-L/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib\
         -L/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/lib\
         -L/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/usr/lib\
         -L/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/lib "

这说明,libstdc++.so.6已在LDFLAGS的路径范围之下,编译不应该出错。

还是好好研究一下错误提示:

make[4]: Entering directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
make[4]: Nothing to be done for `ALL'.
make[4]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
touch /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/.built
mkdir -p /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/bin/ar71xx/packages /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/ipkg-ar71xx/cpp-demo/CONTROL /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/pkginfo
install -d -m0755 /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/ipkg-ar71xx/cpp-demo/bin
install -m0755 /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/cpp-demo /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/ipkg-ar71xx/cpp-demo/bin
find /home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/ipkg-ar71xx/cpp-demo -name 'CVS' -o -name '.svn' -o -name '.#*' -o -name '*~'| xargs -r rm -rf
Package cpp-demo is missing dependencies for the following libraries:
libc.so.6
libm.so.6
libstdc++.so.6
make[3]: *** [/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/bin/ar71xx/packages/base/cpp-demo_1_ar71xx.ipk] Error 1

从前3行看来,cpp-demo的编译好像是正常通过了的。

查看 build_dir/target-mips

tree build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/
build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/
|-- cpp-demo
|-- ipkg-ar71xx
|   `-- cpp-demo
|       |-- bin
|       |   `-- cpp-demo
|       `-- CONTROL
|-- main.cpp
|-- main.o
`-- Makefile

4 directories, 5 files

在这个路径下已经成功生成了cpp-demo可执行程序。证明,编译是通过了的。

为什么 find 执行完就报错?


深入研究错误根源

怎么入手?从错误提示入手吧,看看是在哪里提示"Package cpp-demo is missing dependencies for the following libraries"的。

在SDK目录下执行 grep 命令进行查找。

$ grep "is missing dependencies for the following libraries" ./* -R
./include/package-ipkg.mk:            echo "Package $(1) is missing dependencies for the following libraries:" >&2; \


package-ipkg.mk

打开 include/package-ipkg.mk 文件看个究竟。


在74行输入错误提示信息,条件是存在文件 $(PKG_INFO_DIR)/$(1).missing 这个文件。那问题来了,这个文件是怎么产生的呢?

行70~71行的意思是:如果在 $(PKG_INFO_DIR)/$(1).provides 中没有找到$FILE的,就把$FILE写入到 $(PKG_INFO_DIR)/$(1).missing
其中 $(1)值为cpp-demo,相应的 cpp-demo.provides 与 cpp-demo.missing 都是在 SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/pkginfo/ 路径下的。

那么 xxx.provides 文件里的内容代码什么呢?


63~68行为一个执行进程,它用管道与while语句连接起来。也就是说while里面的FILE变量就是63~68行标准输出的结果。
65,66,67是在根据平台设置环境变量的值,然后在68行执行 SDK/scripts/gen-dependencies.sh。

我猜gen-dependencise.sh执行输出的一定是cpp-demo所依赖的库名称。


研究gen-dependencise.sh

我们打开 SDK/scripts/gen-dependencise.sh 文件,其中最核心的一段:

#!/usr/bin/env bash

TARGETS=$*
XARGS="${XARGS:-xargs -r}"

find $TARGETS -type f -a -exec file {} \; | \
  sed -n -e 's/^\(.*\):.*ELF.*\(executable\|shared object\).*,.* stripped/\1/p' | \
  $XARGS -n1 $READELF -d | \
  awk '$2 ~ /NEEDED/ && $NF !~ /interpreter/ && $NF ~ /^\[?lib.*\.so/ { gsub(/[\[\]]/, "", $NF); print $NF }' | \
  sort -u

从TARGETS目录下查看到所有的文件。对每个文件并用file命令输入该文件的基本信息。用sed对file的输出进行分析,找出有"ELF"且有"executable"或"shared object"关键字的文件。
再对这个文件用 readelf -d 命令输入ELF文件的信息,再用awk从中提取出所依赖的 *.so 文件名,并打印到标准输出。


我亲手用readelf查看一下cpp-demo依赖什么:

$ readelf -d build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/cpp-demo 

Dynamic section at offset 0x934 contains 23 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x80484e8
...<省略>

它确实依赖 libstdc++.so.6, libm.so.6, libc.so.6 这3个动态库文件。


现在 package-ipk.mk 文件中过程理清楚了。cpp-demo所依赖的库文件,在cpp-demo.provides 文件中找不到就会写入到 cpp-demo.missing。

如果纯粹是想让它打包成功的话,那就把差的文件写入到cpp-demo.provides文件就了事儿了。

这样做会不会有后有后遗症?

试试再说~,结果还是不成功。原因是cpp-demo.provides是自动生成的。就算是我手动改了它,下次make的时候还是会还原的。


那新问题是:Who在生成这个cpp-demo.provides文件?它是根据什么生成这个文件的?

那就grep一下关键字"$(1).provides",应该就可以找到。结果还是在 package-ipk.mk 文件里:

L185,将数据进行排序了之后写入到 cpp-demo.provides。数据由L179~184产生。

L179,将IDIR_$(1)目录下的所有 lib*.so*, *.ko 文件名打印出来,作为已有的库文件,由L185写入cpp-demo.provides文件。

IDIR_$(1)的定义如下:

L180~184这个for循环不太好理解。

其中patsubst,是个字串替换命令,其详细用法见:[makefile中的patsubst

$(patsubst %,$(PKG_INFO_DIR)/%.provides,$(IDEPEND_$(1))) 返回的结果是:将$(IDEPEND_$(1))中的每个结果 item,变成:$(PKG_INFO_DIR)/$(item).provides返回。


那IDEPEND_$(1)是什么?


博主深深地感到脑容量不够了。有哪位高人知道的,请指点一下。


跳出这个洞,回到L180~184,的问题。它就是把其它的某个相关的 xxxx.provides 文件里的内容输出来。

博主通过经验推断,xxxx.provides 代表的是是与cpp-demo依赖的组件所依赖的库。


解决方案一:在 Makefile 中添加 Package/cpp-demo/extra_provides 宏

注意:L184,是 $(Package/$(1)/extra_provides)。也就是说,我们可以在 package/cpp-demo/Makefile 文件中定义 Package/cpp-demo/extra_provides 宏来强制性地将那几个库加进去。比如:

define Package/cpp-demo/extra_provides
    echo "libstdc++.so.6"
    echo "libc.so.6"
    echo "libm.so.6"
endef

经过试验,正确的写法如下:

define Package/cpp-demo/extra_provides
    echo 'libstdc++.so.6'; \
    echo 'libm.so.6'; \
    echo 'libc.so.6';
endef

这样写果然凑效,再 make V=s,能够打包成功。

但是,有点我们必须明确的是:在打包中生成的ipk文件里,是没有libstdc++, libc, libm这3个库的。如果所安装的OpenWrt系统里也没有这3个库,那么我们安装的应用程序是不能正常使用的。
相当于是在骗ipk工具,我们已具备了上面这3个库文件。

比较稳妥的方法是采用方案二,如下:


解决方案二:在 Makefile 中的 Package/cpp-demo/install 宏中准备所需的库文件

还有另一个方法,注意L176,$(call Package/$(1)/install, $$(IDIR_$(1))),这个就是引用了我们在Makefile里写的 Package/cpp-demo/install 宏么?
我们可以在这个宏里,将它需要的几个库文件复制到 $(1) 对应的目录下。

如下修改:

define Package/cpp-demo/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/cpp-demo $(1)/bin

    $(INSTALL_DIR) $(1)/usr/lib
    $(INSTALL_DATA) $(TOOLCHAIN_DIR)/lib/libstdc++.so.6 $(1)/usr/lib
    $(INSTALL_DATA) $(TOOLCHAIN_DIR)/lib/libm.so $(1)/usr/lib/libm.so.6
    $(INSTALL_DATA) $(TOOLCHAIN_DIR)/lib/libc.so $(1)/usr/lib/libc.so.6
endef

其中,INSTALL_DATA 与 TOOLCHAIN_DIR 这两个变量在 rules.mk 文件中定义。
之所以选用 TOOLCHAIN_DIR,是因为libstdc++.so.6这个文件就在这个变量所对应的路径下。不信,你可以用 find 命令查找一下。

好了,这样再make V=s,就能正常打包了。


解决方案三:在 Makefile 文件的 Package/cpp-demo 宏中加 DEPENDS 描述

这个方法不是我想到的,是[GunNRose]给我建议。修改 Makefile:

define Package/cpp-demo
    ...<略>
    DEPENDS:+=libstdcpp
endef

经博主亲自尝试,是OK的。

不过,为什么是叫libstdcpp而不是libstdc++呢?这个有待研究一下。

官方Dependence文档:http://wiki.openwrt.org/doc/devel/dependencies


试用

将生成的 SDK/bin/ar71xx/packages/base/cpp-demo_1_ar71xx.ipk 文件用 scp 传到目标机上进行安装试用。

$ scp bin/ar71xx/packages/base/cpp-demo_1_ar71xx.ipk root@192.168.1.2:
root@192.168.1.2's password: 
cpp-demo_1_ar71xx.ipk                    100%  278KB 278.0KB/s   00:01
$

然后用 SSH 登陆到目标机上去安装。

root@OpenWrt:~# opkg install cpp-demo_1_ar71xx.ipk 
Installing cpp-demo (1) to root...
Configuring cpp-demo.

试执行一下 cpp-demo

root@OpenWrt:~# cpp-demo 
/bin/cpp-demo: line 3: syntax error: unexpected word (expecting ")")

Oops~  运行不起来。


解决运行不起来的问题

检查一下那3个依赖的库文件,都还在。那为什么不能运行起来呢?

之前博主在排查上面库依赖的问题的时候已看出了端倪。

在 SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/ipkg-ar71xx/cpp-demo/ 路径下的所有内容都是直接打包的文件。而这里面的 bin/cpp-demo 可执行文件在开发机上居然都正常运行。

这明显不对,bin/cpp-demo 应该是运行在目标机上的ELF文件,怎么可以在开发机上运行?开发机与目标机都不是同类型的CPU。一定是这里出了问题!

博主在想,是不是在交叉编译的时候,选用了本机的gcc,而非目标机的gcc。如下为 SDK/package/cpp-demo/src/Makefile :

target=cpp-demo

ALL:$(target)

objects=main.o

cpp-demo: $(objects)
    echo "CXX = $(CXX)"
    $(CXX) -o $(target) $(objects)

clean:
    @rm -rf $(objects)

为了知道CXX到底是哪一个编译器。我特地加了 echo "CXX = $(CXX)" 调试信息。

把 SDK/build_dir 删了重新 make。为了方便分析,

$ rm -rf build_dir
$ make V=s | less

分析打印的信息:

CC="mips-openwrt-linux-uclibc-gcc" GCC="mips-openwrt-linux-uclibc-gcc" CXX="mips-openwrt-linux-uclibc-g++"
...
make[4]: Entering directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
make[4]: Nothing to be done for `ALL'.
make[4]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
...

咦?Nothing to be done for 'ALL',表示没有什么需要再编译的了。

我赶紧查看

[SDK]$ ls build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo/
cpp-demo  ipkg-ar71xx  main.cpp  main.o  Makefile

发现cpp-demo已经生成,而且在开发机上可运行。这个cpp-demo是怎么来的?难不出是从 package/cpp-demo/src里来的?

我突然想到,我之前进入 package/cpp-demo/src/ 路径下,执行过一次 make,那时一定生成了一个 cpp-demo 可执行程序。查看之:

[SDK]$ ls package/cpp-demo/src/
cpp-demo  main.cpp  main.o  Makefile

果然有它!在make时,由于它的存在,编译组件就认为已经有了就不必再编译,所以才导致了上述的问题。

删除cpp-demo以及main.o。回到SDK,重新make

$ rm -rf build_dir
$ make V=s | less

分析打印的信息:

CC="mips-openwrt-linux-uclibc-gcc" GCC="mips-openwrt-linux-uclibc-gcc" CXX="mips-openwrt-linux-uclibc-g++"
...
make[4]: Entering directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
mips-openwrt-linux-uclibc-g++ -Os -pipe -mno-branch-likely -mips32r2 -mtune=34kc -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable \
  -msoft-float -mips16 -minterlink-mips16  -I/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/include \
  -I/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/include \
  -I/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/usr/include \
  -I/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/include \
  -c -o main.o main.cpp
echo "DEBUG: CXX = mips-openwrt-linux-uclibc-g++"
DEBUG: CXX = mips-openwrt-linux-uclibc-g++
mips-openwrt-linux-uclibc-g++ -o cpp-demo main.o
make[4]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/cpp-demo'
...

根据调试信息可以知道cpp-demo是用mips-openwrt-linux-uclibs-g++来编译的。这下应该就对了!

再次尝试将ipk文件传到目标机上并安装。运行效果如下:

root@OpenWrt:~# cpp-demo 
This is C++ Demo

成功了!


总结

这一次,一个小小的cpp-demo实验,经历了太多波折。不过在尝试解决这些问题的过程中,我们可以更深入地了解其中的编译机制。

首先,我们知道了创建C++应用与C应用没什么区别,莫非就是在Makefile中将CC改成CXX。

然后我们了解到了在打包的时候,它是如何查找一个ELF文件依赖哪些动态包。并知道如何将所依赖的包加入到我们的ipk中。

最后,我们了解到了在rules.mk中定义了大量有用的变量,在include/package-ipk.mk文件中了解到打包的过程。

总之,这次折腾也算是蛮有收获的。


求被关注

我会坚持天天学习,并写博文。如果小伙伴们想一定来研究,那就关注我吧~

© 著作权归作者所有

临峰不畏
粉丝 221
博文 187
码字总数 98583
作品 0
深圳
架构师
私信 提问
加载中

评论(9)

临峰不畏
临峰不畏 博主

引用来自“子逾”的评论

“为什么是叫libstdcpp而不是libstdc++呢?” 因为OPENWRT里面的库名称是libstdcpp,本地用到的库才是libstdc++。所以应该用前者。

哦~
子逾
“为什么是叫libstdcpp而不是libstdc++呢?” 因为OPENWRT里面的库名称是libstdcpp,本地用到的库才是libstdc++。所以应该用前者。
临峰不畏
临峰不畏 博主

引用来自“GunsNRose”的评论

If you say +PACKAGE_packageb:packagec, it means that packagec will only get selected by the current package (e.g. tcpdump) if packageb is enabled. e.g.

DEPENDS:=+PACKAGE_arpd:libpcap
手机上打字真不方便0

谢谢你的分享81,受教了。
GunsNRose
GunsNRose
If you say +PACKAGE_packageb:packagec, it means that packagec will only get selected by the current package (e.g. tcpdump) if packageb is enabled. e.g.

DEPENDS:=+PACKAGE_arpd:libpcap
手机上打字真不方便0
GunsNRose
GunsNRose
不过,为什么是叫libstdcpp而不是libstdc++呢?
个人判断是因为+这个符合在里面是要用作依赖处理
里面的一些依赖会被perl处理
临峰不畏
临峰不畏 博主

引用来自“GunsNRose”的评论

https://forum.openwrt.org/viewtopic.php?id=42098
DEPENDS:=+libstdcpp
这个方式呢?
我试了一下,可以的。我已将你的提议写入了文章。
GunsNRose
GunsNRose
http://axlrose.blog.51cto.com/434566/1530954 我的学习笔记,共同学习
GunsNRose
GunsNRose
https://forum.openwrt.org/viewtopic.php?id=42098
DEPENDS:=+libstdcpp
这个方式呢?
GunsNRose
GunsNRose
好文章,支持
OpenWRT开发之——对C++11的支持

前言 在上篇文章中博主尝试了在OpenWrt上用C++写个简单的程序测试了一下,可行。 博主这两天又了解了C++11,里面的新特性非常令我兴奋。比如sharedptr, lambda, auto都是非常有用的特性。[点...

临峰不畏
2015/05/18
6.8K
11
OpenWrt学习目标(更新)

最近在研究OpenWrt,总感觉这一看一点那也了解一点,没有目的,也没有重心。 这里,给自己拟定一个目标,就朝着这个目标去学。 目标:在OpenWrt上开发服务器软件,该软件可以通过LuCI进行控制...

临峰不畏
2015/05/01
3.6K
8
OpenSCAD设计的3D打印智能路由器盒子(V1.1)

基于OpenSCAD(http://www.openscad.org/)的一个盒子造型,可以用于了解OpenSCAD的3D造型语言。 这个盒子的尺寸是为WRTnode(http://wrtnode.com/)设计的,可以输出STL后通过3D打印机打印出来直...

openthings
2015/02/25
861
3
OpenWRT开发之——远程debug

想要用gdb对OpenWrt进行远程调试。首先得在OpenWrt目标机上安装gdbserver。 其实在trunk路径下也有gdb的ipk安装包的,不信find一下。 [trunk]$ find bin/ -name "gdb*.ipk"bin/ar71xx/packag...

临峰不畏
2015/05/18
8.7K
9
OpenWrt 和 LEDE 宣布正式合并,名字沿用 OpenWrt

2017 年 5 月,我们曾报道过 OpenWrt 和 LEDE 项目正在讨论合并,现在,二者已在官网正式宣布合并,合并后的项目仍用 OpenWRT 命名。合并后的 OpenWrt 项目将按照 LEDE 制定的规范进行管理。...

王练
2018/01/05
6K
13

没有更多内容

加载失败,请刷新页面

加载更多

新建作业20191011121223

2.编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound,Sally shouted,"By the Great Pumpkin,what was that!" #include<stdio.h>int main(){printf("\a");......

电子197朱妍
15分钟前
1
0
家庭作业——苗钰婷

2 编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound, Sally shouted, "By the Great Pumpkin, what was that! #include<stdio.h>int main(){......

OSC_Okruuv
36分钟前
5
0
经典系统设计面试题解析:如何设计TinyURL(一)

原文链接: https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
37分钟前
4
0
2.面向对象设计原则(7条)

开闭原则 开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 实现方法 可以通过“抽象约束、封装变化”来实...

Eappo_Geng
39分钟前
8
0
8086汇编基础 debug P命令 一步完成loop循环

    IDE : Masm for Windows 集成实验环境 2015     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   ......

志成就
43分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部