This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
openwrt_coding [2009/06/11 03:18] eric |
openwrt_coding [2013/05/21 16:12] (current) eric |
||
---|---|---|---|
Line 3: | Line 3: | ||
//Written by Eric Bishop < | //Written by Eric Bishop < | ||
- | Part I: A Simple Program In C added 8/23/2007 | + | [[openwrt_coding# |
- | Part II: C++ and the Standard Template Library (STL) added 10/10/2007 | + | [[openwrt_coding# |
- | Part III: Building and Using the Kamikaze SDK added 12/9/2007 | + | [[openwrt_coding# |
=====Tutorial Moved To New Location -- 7/ | =====Tutorial Moved To New Location -- 7/ | ||
- | I haven' | + | I haven' |
- | This tutorial now makes use of external stylesheets to fit in with the Gargoyle website theme. I realize this may make it more difficult to download and easily reference on your local computer, so I will continue to make the old version of this tutorial available. This version can be found here. | + | This tutorial now makes use of external stylesheets to fit in with the Gargoyle website theme. I realize this may make it more difficult to download and easily reference on your local computer, so I will continue to make the old version of this tutorial available. This version can be found [[http:// |
Line 22: | Line 22: | ||
- | The code for the examples in this tutorial can be downloaded from here. The example from the first part of the tutorial is in the **openwrt-programming-examples/ | + | The code for the examples in this tutorial can be downloaded from [[http:// |
=====Part I: A Simple Program in C -- 8/ | =====Part I: A Simple Program in C -- 8/ | ||
Line 51: | Line 51: | ||
helloworld: helloworld.o | helloworld: helloworld.o | ||
- | $(CC) $(LDFLAGS) helloworld.o -o helloworld helloworld.o: | + | $(CC) $(LDFLAGS) helloworld.o -o helloworld |
- | helloworld.c $(CC) $(CFLAGS) -c helloworld.c | + | |
+ | helloworld.o: | ||
+ | $(CC) $(CFLAGS) -c helloworld.c | ||
# remove object files and executable when user executes "make clean" | # remove object files and executable when user executes "make clean" | ||
Line 286: | Line 288: | ||
</ | </ | ||
- | Now, ssh into the router. We just copied the package to root's home directory so we are finally ready to install our program. In root's home directory, (where we end up immediately after connecting to the router via ssh) type "ipkg install helloworld_1_mipsel.ipk" | + | Now, ssh into the router. We just copied the package to root's home directory so we are finally ready to install our program. In root's home directory, (where we end up immediately after connecting to the router via ssh) type "ipkg install helloworld_1_mipsel.ipk" |
< | < | ||
Line 439: | Line 441: | ||
<fc red> | <fc red> | ||
+ | < | ||
+ | # build helloworld executable when user executes " | ||
+ | helloworld: helloworld.o | ||
+ | $(CXX) $(LDFLAGS) helloworld.o -o helloworld | ||
+ | helloworld.o: | ||
+ | $(CXX) $(CXXFLAGS) -c helloworld.cpp | ||
+ | |||
+ | # remove object files and executable when user executes "make clean" | ||
+ | clean: | ||
+ | rm *.o helloworld | ||
+ | |||
+ | </ | ||
+ | |||
+ | If you use the exact same OpenWrt Makefile as before, this program will compile just fine. It will even install properly when you copy the helloworld_1_mipsel.ipk file to the router and type "ipkg install helloworld_1_mipsel.ipk" | ||
+ | |||
+ | < | ||
+ | root@OpenWrt: | ||
+ | helloworld: can't load library ' | ||
+ | root@OpenWrt: | ||
+ | </ | ||
+ | |||
+ | So, what went wrong? | ||
+ | |||
+ | What needs to be done to fix the problem depends on which version of OpenWrt you are running. If you are running // | ||
+ | |||
+ | Before we adjust our Makefiles to use to this alternate library, let's first make sure that it's installed on the router so that it is available to link to. Log into your router. | ||
+ | |||
+ | < | ||
+ | root@OpenWrt: | ||
+ | Downloading http:// | ||
+ | Updated list of available packages in / | ||
+ | Downloading http:// | ||
+ | Updated list of available packages in / | ||
+ | Downloading http:// | ||
+ | Updated list of available packages in / | ||
+ | Downloading http:// | ||
+ | Updated list of available packages in / | ||
+ | Successfully terminated. | ||
+ | root@OpenWrt: | ||
+ | </ | ||
+ | |||
+ | Once you have updated your package list, install **uclibcxx** by typing "ipkg install uclibcxx" | ||
+ | |||
+ | < | ||
+ | root@OpenWrt: | ||
+ | Installing uclibcxx (0.2.1-1) to root... | ||
+ | Downloading http:// | ||
+ | Configuring uclibcxx | ||
+ | Successfully terminated. | ||
+ | root@OpenWrt: | ||
+ | </ | ||
+ | |||
+ | Otherwise, if the library is already installed, you'll see this confirmation: | ||
+ | |||
+ | < | ||
+ | root@OpenWrt: | ||
+ | Package uclibcxx (0.2.1-1) installed in root is up to date. | ||
+ | Nothing to be done | ||
+ | Successfully terminated. | ||
+ | root@OpenWrt: | ||
+ | </ | ||
+ | |||
+ | Now it's time to modify the Makefiles. | ||
+ | |||
+ | < | ||
+ | helloworld: helloworld.o | ||
+ | $(CXX) $(LDFLAGS) helloworld.o -o helloworld < | ||
+ | helloworld.o: | ||
+ | $(CXX) $(CXXFLAGS) -c helloworld.cpp | ||
+ | |||
+ | # remove object files and executable when user executes "make clean" | ||
+ | clean: | ||
+ | rm *.o helloworld | ||
+ | </ | ||
+ | |||
+ | The OpenWrt Makefile needs a slightly more complex modification. | ||
+ | |||
+ | < | ||
+ | define Build/ | ||
+ | CFLAGS=" | ||
+ | LDFLAGS=" | ||
+ | $(MAKE) -C $(PKG_BUILD_DIR) \ | ||
+ | $(TARGET_CONFIGURE_OPTS) \ | ||
+ | CROSS=" | ||
+ | CXXFLAGS=" | ||
+ | ARCH=" | ||
+ | $(1); | ||
+ | endef | ||
+ | </ | ||
+ | |||
+ | This code specifies the make command (the third line) and a bunch of flags and parameters for compilation. In order to link to **uclibcxx** or, **uClibc++** as it is known to the linker, we add the definition of the $(LIBS) variable as " | ||
+ | |||
+ | |||
+ | **~/ | ||
+ | < | ||
+ | ############################################## | ||
+ | # OpenWrt Makefile for helloworld program | ||
+ | # | ||
+ | # | ||
+ | # Most of the variables used here are defined in | ||
+ | # the include directives below. We just need to | ||
+ | # specify a basic description of the package, | ||
+ | # where to build our program, where to find | ||
+ | # the source files, and where to install the | ||
+ | # compiled program on the router. | ||
+ | # | ||
+ | # Be very careful of spacing in this file. | ||
+ | # Indents should be tabs, not spaces, and | ||
+ | # there should be no trailing whitespace in | ||
+ | # lines that are not commented. | ||
+ | # | ||
+ | ############################################## | ||
+ | |||
+ | include $(TOPDIR)/ | ||
+ | |||
+ | # Name and release number of this package | ||
+ | PKG_NAME: | ||
+ | PKG_RELEASE: | ||
+ | |||
+ | |||
+ | # This specifies the directory where we're going to build the program. | ||
+ | # The root build directory, $(BUILD_DIR), | ||
+ | # directory in your OpenWrt SDK directory | ||
+ | PKG_BUILD_DIR := $(BUILD_DIR)/ | ||
+ | |||
+ | |||
+ | include $(INCLUDE_DIR)/ | ||
+ | |||
+ | # Specify package information for this program. | ||
+ | # The variables defined here should be self explanatory. | ||
+ | # If you are running Kamikaze, delete the DESCRIPTION | ||
+ | # variable below and uncomment the Kamikaze define | ||
+ | # directive for the description below | ||
+ | define Package/ | ||
+ | SECTION: | ||
+ | CATEGORY: | ||
+ | TITLE: | ||
+ | DESCRIPTION: | ||
+ | If you can't figure out what this program does, \\\ | ||
+ | you' | ||
+ | medical attention. | ||
+ | endef | ||
+ | |||
+ | |||
+ | # Uncomment portion below for Kamikaze and delete DESCRIPTION variable above | ||
+ | #define Package/ | ||
+ | # If you can't figure out what this program does, you're probably | ||
+ | # | ||
+ | #endef | ||
+ | |||
+ | |||
+ | # Specify what needs to be done to prepare for building the package. | ||
+ | # In our case, we need to copy the source files to the build directory. | ||
+ | # This is NOT the default. | ||
+ | # PKG_SOURCE which is not defined here to download the source from the web. | ||
+ | # In order to just build a simple program that we have just written, it is | ||
+ | # much easier to do it this way. | ||
+ | define Build/ | ||
+ | mkdir -p $(PKG_BUILD_DIR) | ||
+ | $(CP) ./src/* $(PKG_BUILD_DIR)/ | ||
+ | endef | ||
+ | |||
+ | |||
+ | ######################################################################################### | ||
+ | # The Build/ | ||
+ | # and linking of our program. | ||
+ | # do NOT want to link to the standard template library. | ||
+ | # | ||
+ | # To do this we define the LIBS variable. | ||
+ | # add " | ||
+ | # there are no unresolved references to internal GCC library subroutines. Finally | ||
+ | # " | ||
+ | # this flag is case sensitive. | ||
+ | # in the compiler flags to tell the compiler that c++ standard template library functions | ||
+ | # and data structures will be linked to in specified external libraries and not the | ||
+ | # standard libraries. | ||
+ | ######################################################################################### | ||
+ | define Build/ | ||
+ | $(MAKE) -C $(PKG_BUILD_DIR) \ | ||
+ | LIBS=" | ||
+ | LDFLAGS=" | ||
+ | CXXFLAGS=" | ||
+ | $(TARGET_CONFIGURE_OPTS) \ | ||
+ | CROSS=" | ||
+ | ARCH=" | ||
+ | $(1); | ||
+ | endef | ||
+ | |||
+ | |||
+ | # Specify where and how to install the program. Since we only have one file, | ||
+ | # the helloworld executable, install it by copying it to the /bin directory on | ||
+ | # the router. The $(1) variable represents the root directory on the router running | ||
+ | # OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install | ||
+ | # directory if it does not already exist. | ||
+ | # command to copy the binary file from its current location (in our case the build | ||
+ | # directory) to the install directory. | ||
+ | define Package/ | ||
+ | $(INSTALL_DIR) $(1)/bin | ||
+ | $(INSTALL_BIN) $(PKG_BUILD_DIR)/ | ||
+ | endef | ||
+ | |||
+ | |||
+ | # This line executes the necessary commands to compile our program. | ||
+ | # The above define directives specify all the information needed, but this | ||
+ | # line calls BuildPackage which in turn actually uses this information to | ||
+ | # build a package. | ||
+ | $(eval $(call BuildPackage, | ||
+ | </ | ||
+ | |||
+ | That's it! That modification should be sufficient to enable linking to **uClibc++**. Compile it as before, copy the .ipk file to the router, install it with ipkg and run it: | ||
+ | < | ||
+ | mockingbird@linuxbox: | ||
+ | rm -rf build_* bin | ||
+ | mockingbird@linuxbox: | ||
+ | make package/ | ||
+ | make[1]: Entering directory `/ | ||
+ | Collecting package info... | ||
+ | make -C package compile SDK=1 | ||
+ | make[2]: Entering directory `/ | ||
+ | make[2]: Leaving directory `/ | ||
+ | make[2]: Entering directory `/ | ||
+ | make[4] -C package compile-targets | ||
+ | make[5] -C package/ | ||
+ | make[2]: Leaving directory `/ | ||
+ | make[1]: Leaving directory `/ | ||
+ | ( \ | ||
+ | cd package; \ | ||
+ | find . -maxdepth 2 -name Config.in | \ | ||
+ | sed -e ' | ||
+ | xargs -r -n1 make compile -C; \ | ||
+ | ) | ||
+ | mockingbird@linuxbox: | ||
+ | ipsel.ipk root@192.168.1.1: | ||
+ | root@192.168.1.1' | ||
+ | helloworld_1_mipsel.ipk | ||
+ | mockingbird@linuxbox: | ||
+ | root@192.168.1.1' | ||
+ | |||
+ | |||
+ | BusyBox v1.00 (2007.01.30-11: | ||
+ | Enter ' | ||
+ | |||
+ | _______ | ||
+ | | ||
+ | | ||
+ | | ||
+ | |__| W I R E L E S S F R E E D O M | ||
+ | WHITE RUSSIAN (0.9) ------------------------------- | ||
+ | * 2 oz Vodka Mix the Vodka and Kahlua together | ||
+ | * 1 oz Kahlua | ||
+ | * 1/2oz cream milk on the top. | ||
+ | | ||
+ | root@OpenWrt: | ||
+ | Installing helloworld (1) to root... | ||
+ | Configuring helloworld | ||
+ | Successfully terminated. | ||
+ | root@OpenWrt: | ||
+ | Hell! Why won't my c++ code run? | ||
+ | root@OpenWrt: | ||
+ | </ | ||
+ | |||
+ | It works! | ||
+ | |||
+ | Once again, please do **not** contact me about any issues you might have with your own programs. | ||
+ | |||
+ | =====PART III: Building and Using the Kamikaze SDK -- 12/ | ||
+ | |||
+ | The OpenWrt SDK for Kamikaze is available only for 64 bit processors. If you're one of us mere mortals who posesses only one of those antique 32 bit processors, you have a problem. You can sometimes get away with using the //White Russian// SDK if you only need your program to run on the MIPS architecture, | ||
+ | |||
+ | First, download the source from [[http:// | ||
+ | |||
+ | < | ||
+ | ockingbird@linuxbox: | ||
+ | mockingbird@linuxbox: | ||
+ | mockingbird@linuxbox: | ||
+ | BSDmakefile | ||
+ | Config.in | ||
+ | mockingbird@linuxbox: | ||
+ | </ | ||
+ | |||
+ | In order to specify the architecture of the router and to specify that we want to build the SDK, we need to run "make menuconfig" | ||
+ | < | ||
+ | mockingbird@linuxbox: | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Checking ' | ||
+ | Collecting target info: done | ||
+ | Collecting package info: package/ | ||
+ | Collecting package info: done | ||
+ | </ | ||
+ | |||
+ | You will see the following screen. Select the architecture of your router on the top " | ||
+ | |||
+ | < | ||
+ | | ||
+ | | ||
+ | | ||
+ | [ ] Select all packages by default (NEW) | ||
+ | [ ] Advanced configuration options (for developers) (NEW) ---& | ||
+ | [ ] Build the OpenWrt Image Builder (NEW) | ||
+ | [*] Build the OpenWrt SDK | ||
+ | [ ] Image configuration (NEW) ---> | ||
+ | Base system | ||
+ | | ||
+ | |||
+ | < Select > < Exit > < Help > | ||
+ | |||
+ | </ | ||
+ | |||
+ | Now, make sure you have at least 1.5 GB of disk space and a good book (I recommend [[http:// | ||
+ | |||
+ | < | ||
+ | mockingbird@linuxbox: | ||
+ | make[2] -C / | ||
+ | make[3] -C tools install | ||
+ | make[4] -C tools/sed prepare | ||
+ | make[4] -C tools/sed compile | ||
+ | make[4] -C tools/sed install | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/lzma prepare | ||
+ | make[4] -C tools/lzma compile | ||
+ | make[4] -C tools/lzma install | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[4] -C tools/ | ||
+ | make[2] -C / | ||
+ | make[3] -C toolchain install | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[4] -C toolchain/ | ||
+ | make[2] -C / | ||
+ | make[3] -C target compile | ||
+ | make[4] -C target/ | ||
+ | make[5] -C target/ | ||
+ | make[4] -C target/ | ||
+ | make[2] -C / | ||
+ | make[3] -C package compile | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/mtd compile | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ | ||
+ | make[4] -C package/ppp compile | ||
+ | make[2] -C / | ||
+ | make[3] -C package install | ||
+ | make[4] -C package install-targets | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/mtd install | ||
+ | make[5] -C package/ | ||
+ | make[5] -C package/ppp install | ||
+ | make[5] -C package/ | ||
+ | make[4] -C package preconfig | ||
+ | make[2] -C / | ||
+ | make[3] -C target install | ||
+ | make[4] -C target/ | ||
+ | make[5] -C target/ | ||
+ | make[4] -C target/ | ||
+ | make[4] -C target/ | ||
+ | make[5] -C target/ | ||
+ | make[4] -C target/sdk install | ||
+ | make[2] -C / | ||
+ | make[3] -C package index | ||
+ | mockingbird@linuxbox: | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | That's all there is to compiling the SDK The SDK tar.bz2 file is now in the bin subdirectory. You can install it just as I describe above for the White Russian SDK that can be downloaded in its compiled form. | ||
+ | |||
+ | However, if you are working with Kamikaze 7.09 (the latest as of this writing) or before, you're likely to have trouble compiling packages with your newly compiled SDK. There' | ||
+ | |||
+ | **Excerpt from ~/ | ||
+ | < | ||
+ | world: FORCE | ||
+ | $(MAKE) package/ | ||
+ | -( \ | ||
+ | cd package; \ | ||
+ | find . -maxdepth 2 -name Config.in | \ | ||
+ | sed -e ' | ||
+ | xargs -n1 $(MAKE) compile -C; \ | ||
+ | ) | ||
+ | |||
+ | </ | ||
+ | |||
+ | With this, fixed, code: | ||
+ | |||
+ | **Excerpt from ~/ | ||
+ | < | ||
+ | world: FORCE | ||
+ | $(MAKE) package/ | ||
+ | -( \ | ||
+ | cd package; \ | ||
+ | for configfile in `find . -maxdepth 2 -name Config.in` ; do \ | ||
+ | $(MAKE) compile -C `dirname $$configfile` ; \ | ||
+ | done \ | ||
+ | ) | ||
+ | </ | ||
+ | |||
+ | You should now be able to compile your code just as you did with the //White Russian// SDK. | ||
+ | |||
+ | I toyed with the idea of not reiterating, | ||
+ | |||
+ | |||
+ | This tutorial is provided under the [[http:// |