Makefile Question

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using AVR Studio 4.18sp3, WinAVR.

The makefile generated by the IDE concludes with the line:

## Other dependencies
-include $(shell mkdir dep 2>NUL) $(wildcard dep/*) 

What does this line do? When I build the project from within AVR Studio, the project builds normally.

When I build the project (using the same Makefile, with slashes flipped) in Cygwin, it creates a NUL file in the ./default directory -- which I can only delete from within Cygwin (i.e., Windows can't delete it). When I delete the line, the project still builds successfully.

I think the ">NUL" part is telling it to dump some stuff in a file called NUL (hence the file creation), but I can't figure out what. I also don't know why it only creates the NUL file when I make it in Cygwin (and not when I make it within AVR Studio).

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
What does this line do? When I build the project from within AVR Studio, the project builds normally.
It includes the dependency rules which were generated by the compiler during the prior build.

Quote:
I think the ">NUL" part is telling it to dump some stuff in a file called NUL (hence the file creation), but I can't figure out what.
The "2>..." means "redirect the output of stderr to ...". NUL is on windows a "black hole" (like /dev/null on Unix/Linux), so effectively it means "discard the output of stderr".

Quote:
I also don't know why it only creates the NUL file when I make it in Cygwin (and not when I make it within AVR Studio).
Cygwin tries to emulate an unix-like environment, and there is "NUL" not special in any way and therefore a regular file with that name is created.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Stefan,

Thanks again for the rapid response. I changed the line to 2>errLog.txt, and can now manipulate the file normally in Windows. That said, it this just a way of speeding up the make process? Meaning, if I were building for the very first time (i.e., no dependecy rules from a prior build exist), there would be no dependency rules, and the compiler would have to generate them (which I assume takes time). If I remove this line from the makefile, it still works, but just takes longer. Is this correct?

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hobbss wrote:
If I remove this line from the makefile, it still works, but just takes longer. Is this correct?
Not quite. Imagine you change a header file. Without the dependencies nothing is rebuild then during a normal build, so I would not say "it still works". To be on the safe side every build must be forced to be a full rebuild then (by using "make clean" prior every build or by adding 'clean' to the 'all' target). Or you manually create your own dependency rules in the Makefile, which is a maintenance nightmare.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok. Because I am paranoid (and do not fully understand make), I always do a "make all". If I understand you correctly, as long as I have that line in the make file, I should only have to "make" (not "make all") if I change a header file.

To break the line down: -include $(shell mkdir dep 2>NUL) $(wildcard dep\*)

-include //include what follows (?)
$(shell mkdir dep 2>errLog.txt)
//Not sure on "shell". "mkdir dep" I get (this actually creates an error in errLog.txt if dep already exists).. 2>errLog.txt I get (stderr = 2, >errLog.txt tells it where to put it).
$(wildcard dep\*) -- need a little help here. I read the Gnu make page, and am still confused about hte usage of the wildcard keyword.

I think this part of the line says to include all files located in dep\ (hence the *). What is the word wildcard for?

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hobbss wrote:
ok. Because I am paranoid (and do not fully understand make), I always do a "make all". If I understand you correctly, as long as I have that line in the make file, I should only have to "make" (not "make all") if I change a header file.
"make" and "make all" are both the same. 'all' is the default target. If you remove that line, then "make all" is not enough in every case. You either have to do "make clean; make all", or you need to modify the Makefile further.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
What is the word wildcard for?
It enforces the wildcard expansion at places where the expansion normally would not happen. IMO it is not necessary here, but it doesn't hurt either.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok. Still reading the makefile, I am having trouble with a few of the compiler flags.

Specifically:

CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 

I believe this pertains to my earlier question. What exactly are the -MD, -MP, and -MT flags doing? I have searched both the GNU Make manual and the avrgcc manual, and can't find them (I probably missed them).

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hobbss wrote:
What exactly are the -MD, -MP, and -MT flags doing? I have searched both the GNU Make manual and the avrgcc manual, and can't find them (I probably missed them).
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Preprocessor-Options.html#Preprocessor-Options

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perfect. Thanks.

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But as Stefan says if you are willing to have all the files rebuilt every time (doesn't really matter for AVR sized projects) then just "make clean all" and forget about trying to get the dependency stuff working.

Just out of interest what's the appeal of building from within Cygwin anyway?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just use Cygwin for running test code when I don't have a board handy, and want to test something that isn't I/O related. A coworker pointed it out to me a long time ago as an easy development environment on a Windows machine.

I'm trying to learn more about makefiles rather than to blindly rely on what AVR Studio creates. On a whim, I tried to compile my project in Cygwin (rather than from within AVR Studio), just to see how it was different. It is definitely possible that I am a glutton for punishment. When I was in college, taking the single [mandatory] programming class (C++), I miserably swore that, once I graduated, I would never write another line of code. Turned out to be rather short sighted. I almost enjoy it now, even if I am not particularly skilled at it. That's what I have 'Freaks for - to point out the errors in my way.

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the point is that you can use make and Makefiles in DOS, I don't really see what Cygwin adds except the ability to use "sh" but WinAVR has a DOS (msys) build of that anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I just use cygwin out of habit (used to use it for other purposes).

Another make question:

I have a project that is using the LwMesh stack. As such, the files are scattered throughout several directories. All of my files (that I have written), are in the top level directory.

I.e.:

./projDir -> contains all my files
./projDir/lwMesh/* contains the LwMesh files (spread over ./hal, ./nwk, ./phy, ./service, and ./sys)
./projDir/default contains my Makefile.

If possible, I want to make a generic make file that I can use on multiple projects with minimal changes.

At the top, I create a var called PRJSRC that has all of my .c files (this is the part that changes from project to project).

I also have a variable called INCLUDES that points to the locations of all of my header files (this woudl also change, based on project), including all the LwMesh headers in this case.

PRJSRC= myCode.c myCode2.c, hal.c, halTimer.
INCLUDES= -I"..\lwMesh\nwk\inc" \
          -I"..\lwMes\hal\inc" \ ...

I then do the following:

CFILES=$(filter %.c, $(PRJSRC))
OBJECTS=$(CFILES:.c=.o)

To compile the files and create the object files, I have:

%.o: ../%.c
     $(CC) $(LDFLAGS) $(LIBS) -o $(TARGET) $(OBJECTS)

This works great for "my" files that are in teh top level directory (i.e., one above default), but obviously it breaks for the LwMesh files, as they have a different path. Is there a way to tell it to look in all subdirectories for a file? Otherwise, I wuold need a separate line for each different section of the LwMesh stack.

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

as they have a different path

VPATH: http://www.gnu.org/software/make...

It's a very good manual - you probably want to read it first. Don't try to take in everything on the first reading but when you later ask "I wonder if you can do this?" or "I wonder how you do that?" you may then think "wait a minute I seem to remember there was some directive/variable/whatever you can use to achieve that".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you. I agree -- it is a very good manual, and well written. At this time, I am a little overwhelmed by its 192 page length. Until I read through it, I am not always sure what term to search on, and sometimes my google searches are not much better.

Thanks again for your help (and to Stefan). I think I finally have my makefile where I want it...

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do a thread search here for VPATH though I think there are some possible problems/issues with it's use I've read about here but I cannot remember what they were right now (that's old age for you!).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I rather doubt your memory is going... In any event, VPATH is working properly. I attempted to use vpath to filter out some headers, but found that I still need to include them with the -I flag in the compile command. A little additional digging through the manual confirmed this.

Science is not consensus. Science is numbers.