Go back to Richel Bilderbeek's homepage.
Go back to Richel Bilderbeek's C++ page.
A Hello World program for NDS, using
Qt Creator under Ubuntu is not simple.
This page actually shows
how to cross-compile a 'Hello World' Qt Creator project from Ubuntu to NDS?
The tool ndsmake allows to
cross-compile
directly from Qt Creator under Ubuntu to NDS.
Prerequisites
devkitpro needs to be installed in /opt/devkitpro. Follow the steps described by [1].
For the Qt Creator project
to compile, also install the libnds source code (the libnds-src-1.4.7 tarball).
Folder structure
I have used the following folder structure (as in the downloadable project above):
- build
- CppHelloWorldQtCreatorUbuntuNds.map: generated by the important Makefile
- main.d: generated by the important Makefile
- main.o: generated by the important Makefile
- source
- CppHelloWorldQtCreatorUbuntuNds (unknown OS executable)
- CppHelloWorldQtCreatorUbuntuNds.pro
- CppHelloWorldQtCreatorUbuntuNds.pro.user
- main.cpp: where our code lives
- main.o: useless object file generated by QtCreator
- Makefile: useless Makefile generated by QtCreator
- Makefile: the important Makefile
- CppHelloWorldQtCreatorUbuntuNds.elf: elf file generated by the important Makefile
- CppHelloWorldQtCreatorUbuntuNds.nds: the NDS executable
main.cpp
A Hello World program for NDS additionally needs
to call 'consoleDemoInit' from the libnds library
and end in a waiting loop: if the program reaches the end of main, it terminates.
A valid Qt Creator project file
is practical for development. It will result in an unknown OS's executable.
#-------------------------------------------------
#
# Project created by QtCreator 2010-10-07T22:25:11
#
#-------------------------------------------------
INCLUDEPATH += /opt/devkitpro/libnds-1.4.7/include
INCLUDEPATH += /opt/devkitpro/libnds-src-1.4.7/include/nds
INCLUDEPATH += /opt/devkitpro/devkitARM/arm-eabi/include
LIBS += -L/opt/devkitpro/libnds-1.4.7/lib -lnds9
LIBS += -L/opt/devkitpro/devkitARM/arm-eabi/lib -lstdc++
DEFINES += ARM9
TARGET = CppHelloWorldQtCreatorUbuntuNds
CONFIG += console
CONFIG -= qt
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
QMAKE_CC = /opt/devkitpro/devkitARM/bin/arm-eabi-g++
QMAKE_CXX = /opt/devkitpro/devkitARM/bin/arm-eabi-g++
QMAKE_LINK = /opt/devkitpro/devkitARM/bin/arm-eabi-g++
QMAKE_LFLAGS = -T/opt/devkitpro/devkitARM/arm-eabi/lib/ds_arm9.ld
|
The Makefile generated by Qt Creator
will not result in a valid .nds file. This is a correct Makefile:
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := gfx source data
INCLUDES := include build /opt/devkitpro/libnds-1.4.7/include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork
CFLAGS := -g -Wall -O2\
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lnds9
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(BINFILES:.bin=.o) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).ds.gba
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds : $(OUTPUT).elf
$(OUTPUT).elf : $(OFILES)
#---------------------------------------------------------------------------------
%.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
|
Qt Creator does not generate a valid executable. Using a terminal, navigate
to the folder with the important makefile. Then call make:
This hopefully results in the following success output:
Nintendo DS rom tool 1.48 - Jul 7 2010
by Rafael Vuijk, Dave Murphy, Alexei Karpenko
built ... CppHelloWorldQtCreatorUbuntuNds.nds
|
Running the program
The generated NDS executable (CppHelloWorldQtCreatorUbuntuNds.nds)
can be run in an NDS emulator
or copied on an R4 (and other ways I do not know the details (and success) of, like WiFi-ing the code, or passing
through a Gameboy Advanced)
Personally, I call the NDS emulator from command line:
desmume CppHelloWorldQtCreatorUbuntuNds.nds
|
- Devkitpro wiki 'Getting started/devkitARM'
The first thing that you need to do is create a folder for the devkitPro toolchains. Start by opening a terminal - on OSX use the apple key + space, then type terminal. In the terminal window type the following command to create a new folder - all these commands are executed by pressing the return key. You'll need to create the initial folder with root privileges
sudo mkdir -p /opt/devkitpro
Once you've done that you can grant world access to the folder so you can extract the archives with normal privileges.
sudo chmod 777 /opt/devkitpro
When we're done the layout for your devkitPro folder should end up like this, each folder links to the appropriate sourceforge package.
devkitpro
|
+-- devkitARM
+-- examples
| |
| +-- gba
| +-- gp32
| +-- nds
+-- libgba
+-- libmirko
+-- libnds
Nothing else should be placed inside these folders unless otherwise instructed by the devkitPro toolchain maintainers. On Windows several of these folders are removed and replaced by the update system.
The first package to install is the devkitARM tarball, obtained from the devkitARM link shown above. Download the appropriate tarball for your host platform - the files are named as devkitARM_<revision>-<processor>-<os>.tar.bz2. For OSX we provide universal binaries - devkitARM_<revision>-osx.tar.bz2.
Once the file is downloaded then you need to extract it into the devkitpro folder
cd /opt/devkitpro
tar -xvjf <file you downloaded>
Obviously replace <file you downloaded> with the name of the file obtained from sourceforge. On OSX you can simply drag & drop the downloaded file into the terminal window to get the file path.
Now you need to obtain the support libraries for your target platform - we'll start with the Nintendo DS libraries.
Download the latest binary of libnds then create a new folder and extract the tarball from the terminal window as before. Note: This is the file without "-src-" in the name.
mkdir libnds
cd libnds
tar -xvjf <libnds tarball>
Again, replace <libnds tarball> with the name of the file obtained from sourceforge. On OSX you can simply drag & drop the downloaded file into the terminal window to get the file path.
Now download libfat-nds, this is the libfat-nds tarball and may not be in the release at the top of the list. You may need to expand the second section to find the appropriate file. This should be extracted to the same folder as the libnds tarball earlier.
tar -xvjf <libfat-nds tarball>
Download the dswifi tarball and extract in the same place.
tar -xvjf <dswifi tarball>
Download the maxmod tarball and extract in the same place.
tar -xvjf <maxmod-nds tarball>
Download the libfilesystem tarball and extract in the same place.
tar -xvjf <libfilesystem tarball>
Lastly you'll need the arm7 binary that handles the wifi, audio and touchscreen on the DS.
Download the default arm7 tarball and extract, still inside the libnds folder.
tar -xvjf <default arm7 tarball>
Now all that remains for DS programming is the examples archive. Move back to the devkitpro folder and create an examples/nds folder.
cd ..
mkdir -p examples/nds
cd examples/nds
Grab the nds examples archive from sourceforge & extract it here.
tar -xvjf <examples tarball>
Add these variables in your execution environment, for instance, editing the .bashrc file located in your home folder:
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=$DEVKITPRO/devkitARM
|
Go back to Richel Bilderbeek's C++ page.
Go back to Richel Bilderbeek's homepage.
