gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > DevKit set up?

#105841 - hickscorp - Thu Oct 12, 2006 2:25 pm

I have a clean DevKit environement set up to work with libNDS and ARM headers. I also have a full set of tools (in C++ but fully C compatible) of my own which i want to use in my Nintendo DS C projects. I have tried to just #include the .h i needed, but it failed. So i have made a lot of testing, and i finally that i needed to include the .cpp files for it to work.

If i include the .h, the compiler gives an error like if it can't find the body of the defined classes. So of course, .hpp (Header + definition in a single file) perfectly works, but i can't make all my tools hpp since i also use them for software i make for PC platform. Way strange thought, because the .cpps are in the same directory than the .h are...

What can it be caused by? Where can i get help elsewhere if i'm asking at the wrong place?

Anyway, thanks for your time!
Bye!

#105843 - Sausage Boy - Thu Oct 12, 2006 2:39 pm

You need to make sure that the .cpp files are actually compiled and linked into your project. This is easiest to achieve with just dropping the ones you need into the source folder of your project.

Another way would be to modify the Makefile to look for .cpp files to include in your other directory as well. This is done by opening the file called Makefile in your project directory with WordPad or another decent editor (Notepad doesn't like UNIX style line endings). You'll see a line like this:
Code:
SOURCES      :=   source

Simply change it to:
Code:
SOURCES      :=   source /c/path/to/directory/with/your/cpps

The Makefile magic should take care of the rest.
_________________
"no offense, but this is the gayest game ever"

#105844 - keldon - Thu Oct 12, 2006 3:02 pm

Also have a look at the [makefile tutorial].

#105845 - hickscorp - Thu Oct 12, 2006 3:07 pm

Hello again guys and thanks for your answers,

My makefile actually includes cpp files (I think?). The thing is, i added two paths in the make file to make sure it knows:
- Standard STD C files.
- My tools (Named CHTools).
The problem is, i can't give it only one directory to look in for CPP since they are in subfolders, and it should be a recursive parsing of those folders which makes the trick.

Here is my makefile, if you have a clue...
Code:

#---------------------------------------------------------------------------------
.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      :=   Source
DATA      :=   data
INCLUDES   :=   include $(BUILD)
CHTOOLSDIR   :=   "D:/Programmation/C++/CHTools"
CPPSTDINC   :=   "C:/Progra~1/DevKitPro/DevKitARM/include/c++/4.1.1"

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH   :=   -mthumb -mthumb-interwork

# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
# *insists* it has a FPU or VFP, and it won't take no for an answer!
CFLAGS   :=   -g -Wall -O2 -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer -ffast-math $(ARCH)

CFLAGS      +=   $(INCLUDE) -DARM9
CXXFLAGS   := $(CFLAGS) -fno-rtti -fexceptions

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)) \
               $(foreach dir,$(DATA),$(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,$(DATA), $(notdir $(wildcard $(dir)/*.*)))
 

 
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
   export LD   :=   $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
   export LD   :=   $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES   :=   $(addsuffix .o, $(BINFILES))\
               $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
 
export INCLUDE   :=   -I$(CHTOOLSDIR) -I$(CPPSTDINC) \
               $(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).arm9
run:
   wmb -data $(OUTPUT).nds
 
#---------------------------------------------------------------------------------
else

DEPENDS   :=   $(OFILES:.o=.d)
 
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).nds   :    $(OUTPUT).arm9
$(OUTPUT).arm9   :   $(OUTPUT).elf
$(OUTPUT).elf   :   $(OFILES)
 
#---------------------------------------------------------------------------------
%.pcx.o   :   %.pcx
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o)
#---------------------------------------------------------------------------------
%.bin.o   :   %.bin
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o)
 
#---------------------------------------------------------------------------------
%.txt.o   :   %.txt
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o)

 
-include $(DEPENDS)
 
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------



Anyway, i'll give a try to each solution you gave.

Bye bye, have fun!
Pierre.

#105859 - Cearn - Thu Oct 12, 2006 6:02 pm

hickscorp wrote:
Hello again guys and thanks for your answers,

My makefile actually includes cpp files (I think?). The thing is, i added two paths in the make file to make sure it knows:
Code:

TARGET      :=   $(shell basename $(CURDIR))
BUILD      :=   build
SOURCES      :=   Source
DATA      :=   data
INCLUDES   :=   include $(BUILD)
CHTOOLSDIR   :=   "D:/Programmation/C++/CHTools"
CPPSTDINC   :=   "C:/Progra~1/DevKitPro/DevKitARM/include/c++/4.1.1"

You may have added variables for the paths to your tools, but you're not actually using those variables anywhere. Include search paths should be added to INCLUDES, source paths to SOURCES and tool executables to PATH.

On another note, makefiles have a different path syntax than DOS. For example, ':' is a path separator, not a volume separator. If you have to add a full path, they should look like Sausage Boy illustated. I'm also quite sure double quotes are bad too.

Also, spaces in paths are generally considered bad news. Spaces like in "Program Files" or "My Documents". In all likelihood, they won't parse right.

#105881 - hickscorp - Thu Oct 12, 2006 9:52 pm

Okay...
Well the variables are used. The proof is, i CAN compile while including the CPP files from my project.

the variables are used here:
Code:

export INCLUDE   :=   -I$(CHTOOLSDIR) -I$(CPPSTDINC) \
               $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               -I$(CURDIR)/$(BUILD)


It just tells the compiler to look there when a file has to be included. If i ask for "ExtPrimitives/CHInteger.h" it looks first in CHTOOLSDIR, then in CPPSTDINC. If FNF, it then looks in each dir listed by the foreach loops on various other directories.

EDIT: The fact i didnt use a foreach on my own source tree is VOLUNTEER. The point is that i have files which for instance are named "Vector.h" (In a specific subdir, java namespace style)... If i use a foreach on the include, and then if i include "Vector.h", i cant be sure wether my or the std::vector header would be included. So just giving the root dir of my source tree allows me to include both Vector.h and for instance ExtPrimitives/Utils/Vector.h. Just to clarify the "why of the what" ^^

EDIT2: Oh yeah i forgot: I know spaces are bad in paths, that's why there are none in my MakeFile. As you can see, i would NEVER include anything "from" "Program Files" (Few win32 rules), but in fact in "Progra~1".

I know about the ":" stuff sincei have tested a lot before i figure this configuration worked. I tried to escape slashs, change the ":" etc... What i never have to do on my Debian server while using "/".

Anyway, my initial problem is, that i am unable to include .h, because the compiler doesn't "finds" the associated .cpp files, which results in an "incomplete" declaration (It only finds protos).

Thanks for your help, i still need a clue on this one ;)

Pierre.

#105885 - Cearn - Thu Oct 12, 2006 10:39 pm

hickscorp wrote:
Okay...
Well the variables are used. The proof is, i CAN compile while including the CPP files from my project.

the variables are used here:
Code:

export INCLUDE   :=   -I$(CHTOOLSDIR) -I$(CPPSTDINC) \
               $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
               -I$(CURDIR)/$(BUILD)

Missed that line, sorry. yes, this would put those dirs in the search path for header files.

hickscorp wrote:
EDIT2: Oh yeah i forgot: I know spaces are bad in paths, that's why there are none in my MakeFile. As you can see, i would NEVER include anything "from" "Program Files" (Few win32 rules), but in fact in "Progra~1".
Fair enough, used like that the makefile won't trip over it. But it's possible that the expanded form may appear somewhere internally, or in the system path. Or the DEVKITARM environment variable. Or maybe you took care of that already. :P

hickscorp wrote:
Anyway, my initial problem is, that i am unable to include .h, because the compiler doesn't "finds" the associated .cpp files, which results in an "incomplete" declaration (It only finds protos).

I don't quite catch that. If you can't find source files (.cpp), there's nothing that's able to #include files in the first place the phrase "can't include .h" is meaningless. As prototypes are usually kept in .h files, being able to find them means that can include the headers, and you do have declarations because that's what a prototype is. Did you mean definitions, perhaps?

Anyway, I take it that the missing source files are in CHTOOLSDIR? Like I said, source folders should be added to the SOURCES list, which will later be added to the VPATH (the search path for sources), and have its files added to the CPPFILES list. If you need to, you can add the line
Code:
   @echo $(CPPFILES)
to, say, the $(BUILD). That should give you a list of files that are to be compiled and point to the root of the problem.

#105893 - hickscorp - Thu Oct 12, 2006 11:12 pm

Haha thanks a lot for your help.
I'm actually getting conscient my explanation was a total mess :)

Let's simplify it (I'll use *nix paths, just trust me for the DOS translation i know it works ;) )
- Let's say my NDS project is in /NDSProject.
- Let's say in "/My/Tools" i have this directory structure:
Code:

   +-Logger/
   |    +-CLogger.h
   |   +-CLogger.cpp
   +-ExtPrimitives/
   |   +-Utils/
   |   |   +-Vector.h
   |   |   +-Vector.cpp
   |   +-CString.h
   |   +-CString.cpp

- Also, i don't want to copy the /My/Tools content to /NDSProject dir (I tried thought, and it didnt solve the thing).
- In my MakeFile, i say -I/NDSProject/Source -I/MyTools.

That was for the basic setup, now:
If from /NDSProject/Source/main_arm9.cpp, i put "#include <ExtPrimitives/Utils/Vector.h>" it fails. It fails for any .h, because the precompiler (Or compiler but i doubt) just doesn't "look" for the cpp files, as weird as it sounds! If i want to make it works, i have to "#include <ExtPrimitives/Utils/Vector.cpp>" (Each of my CPPs include their own .h at the begining of course). Then it works, but it is very trivial because if my included file includes any other .h (For instance, if in Vector.h i have "#include <ExtPrimitives/CString.h>", it *works* but again it doesn't finds the cpp, so in main.h i have to #include each needed *single* cpp dependencies (w00t let me post my main.cpp file so you have fun, there is less code than includes XD ).

Now your questions:
1) Each environement var is OK, i triple checked the whole dev env. I managed to compile each example, without any problem (Yes i have problems, which are that i don't understand all of the 3D API, but let's don't discuss this, would be a shame for me lol).
2) About the prototype declaration definition sorta kinda thing, you're right, i'm totally confused now XD So with my example, let's say that if i only "#include <CClass.h>" the compilation process finds the class proto in the .h (Which is logic) but is then unable to find the full body of the defined class, it doesn't look for the CPP file.
3) I included the echo in my makefile build section, and the output is obviously "main.cpp" only. You're entirely right, all my CPP files in /My/Tools are ignored. So i tried what you suggested, adding my tools path to the SOURCE var:
Code:

SOURCES      :=   Source D:/Programmation/C++/CHTools

And the output of the echo is still only "main.cpp" :(
I really think that it's because all my CPP files are *not* in the root folder "D:/Programmation/C++/CHTools", and the parsing is probably not recursive...

Man i feel very sorry for my explainations, i know it's hard to understand me, so thanks a lot for your time :)
Please keep giving me your idea, i feel like you're about to solve my problem ^^

Maybe, if you have a very simple MakeFile based on a similar approach (I mean, including a bunch of CPP files which are not on a single folder)?

Thanks a lot!
Bye.
Pierre.

EDIT: I just tried:
Code:

CPPFILES   :=   $(foreach dir,$(SOURCES), $(notdir $(wildcard $(dir)/*.cpp)))
CPPFILES   +=   $(foreach dir,$(CHTOOLSDIR), $(notdir $(wildcard $(dir)/*.cpp)))

Doesn't solve it.

EDIT2: I think i have a solution, but i feel it's a ugly one: I can make a loop on the MakeFile which issues a "make" on my Tools directory, then on my Tools directory i put as much as MakeFiles as i have subfolders (In each of them) to recurse-build a clean list of my cpp files? Is it doable? oO

#105899 - hickscorp - Thu Oct 12, 2006 11:30 pm

Okay let me ask you a simple question:
Is there a way to change the foreach loops on directories to recursive loops, which would keep the relative path on each file it finds after it matches the filter .cpp?

If the foreach loop outputs me a complete list of the cpp files, with for each one the relative path from the tools directory, i'm saved...
I love doing "chmod myself:roots ~ -R" from times to times... Tell me it's doable in a MakeFile ^^
Or maybe i can make a "find ./ | grep .cpp > $(CPPFILES)" ? I'm not sure if it's provided by MSYS under MSWin.

XD
oO


Last edited by hickscorp on Fri Oct 13, 2006 12:13 am; edited 1 time in total

#105907 - hickscorp - Fri Oct 13, 2006 12:13 am

I'm still trying stuff, and i can't manage to fix it :)

#105950 - hickscorp - Fri Oct 13, 2006 3:26 pm

++ Up?...

#106089 - hickscorp - Sun Oct 15, 2006 2:10 am

Please just take 1mn to give me a clue if you have a little idea!

#106489 - wintermute - Thu Oct 19, 2006 5:46 pm

clean the project, zip it up and mail it to me, I'll take a look.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog