![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Patrick Elliott wrote:
> > Trying to work out what went wrong, and why, from the damn code, and the
> > code that built the code, and the code that ran the code, that built the
> > code... o.O
> Precisely. When the configuration file to create the build tools is based on
> turing-complete macro processing, you're gonna just be screwed if there's
> anything wrong.
So let me get this straight: He was trying to compile a program with
Visual C++, the project did not have a Visual C++ project file, he was
trying to compile it in Windows which is not Unix and hence does not use
the same core tools, and consequently he had big problems in compiling
the program. Yet this is still somehow a problem with makefiles.
It seems to me that anybody could make a post with any random problem
they had, and if a makefile was somehow involved, you would immediately
rush to agree with a "precisely!" answer regardless of what was the real
cause of the problem.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
>> In Ada, you don't calculate the checksums of every source. You calculate the
>> checksum of the file you're compiling when you compile it. In C#, your file
>> is either associated with a project (i.e., with the equivalent of a
>> makefile) or it's installed in the global assembly cache with a version
>> number and a cryptographic checksum on it you can check against.
>
> So if you have thousands of files in your project, the compiler will
> calculate the checksums of every single one of them every time you want
> to compile? And it was you who complained how creating makefile rules for
> C files is inefficient... Right.
Read the second sentence again. You calculate the checksum of the file when
you compile it. You then store that in the object code.
If you have library A and B, and program C that uses them, then you compile
the headers for A and B, generating two checksums in the object code. Then
you compile the body of library A, which puts the checksum for the header
for A into the body of A, along with the checksum for the body of A. Same
with B. Then you compile C against the headers for A and B, and generate a
checksum for C into C, along with storing the checksums for A and B's header
object code.
When you link, the linker checks that every reference to A's object code has
the same checksum, that every reference to B's object code has the same
checksum, etc.
If you change A's header file and recompile it, you'll have a different
checksum in A's header file object code, and you'll have to recompile both
A's body and C before you can relink. You can, however, recompile A's
implementation without having to recompile C.
> Yeah, and if your hard drive dies, you also get a failure. Also a big
> difference. I still don't get your point.
That you know the code you're running isn't the code you have the source for.
> You talk as if accidentally touching an object file is a relatively
> common happenstance.
So you've never updated a library that you'd already compiled against? What
do you think "DLL Hell" is?
If I compile, today, against September's libraries, then I install
November's libraries, stuff doesn't recompile.
> in the fifteen or so years I have been using
> makefiles, guess how many times that has happened to me.
It *can* work OK, if everything is done carefully and you're not using
pre-compiled stuff for half of what you're doing. C has always been pretty
good as long as you have all the source code and everyone working on it is
careful.
>>> There are like a million scenarios where you accidentally do something to
>>> your files which will cause a malfunction (regardless of your IDE).
>
>> Sure. You're apparently trying to miss my point here, which is that the idea
>> that basing dependency information and content-change information solely on
>> file timestamps is iffy.
>
> The situations where it causes problem are so extremely rare that it just
> isn't worth the price of the compiler calculating checksums of every single
> file in the project every time you want to do a quick compile.
Nobody does that, tho. Nobody *needs* to, because type information and
declarations are actually stored in object files. Neither Ada nor C#
calculate any checksums except when they compile the code they're
calculating the checksums for. Given that calculating the checksum is
undoubtedly faster than even -M on gcc, and you only do it when you actually
recompile something, I'm not sure why you think it would be a bad idea.
You can't do it in C because there's no place to store the checksum from a
.h file, because a .h file doesn't create code. (Generally speaking, of course.)
> Imagine that
> every time you want to compile your project, you had to wait a minute for
> the compiler to check all the checksums, when with the current scheme it
> can do it in a few seconds.
Yeah, that would suck. Good thing nobody works it that way.
Of course, the projects I've worked on spent at least that much time
recursing into makefiles just to check, so that's no biggy.
> Nevertheless, you are still blaming the programming language for a
> defect you see in the compiling tools. All this has nothing to do with C.
See above. C doesn't generate object files for .h files, so *if* you wanted
to use checksums, then yes, you *would* have to do it this sucky way. But
the languages that don't use #include don't have to do it this sucky way.
You have pointed out exactly what my point in this part of the discussion
is, and exactly why C (and other source-include macro languages) sucks in
this particular respect.
>>> Of course the makefile assumes that you have specified all the necessary
>>> dependencies. It cannot read your mind.
>
>> I have never seen a makefile that lists as a dependency of my code all the
>> things that stdio.h includes.
>
> And that makes it impossible to create such a makefile (especially if you
> are using a dendepency-generation tool)?
No. I'm just saying that in practice, it doesn't happen, so in practice,
there are still times when you have to either do a make-clean or risk having
broken code.
> Anyways, exactly why would you want to recompile your program if stdio.h
> changes? You see, stdio.h is standardized, and if it was changed in such
> way that programs would need to be recompiled for them to work, it would
> mean that the C standard has been changed to be backwards-incompatible and
> it would break basically all programs in existence.
Nope. All I need to do is redefine O_RDWR to have a different value or
something like that. (OK, not stdio.h, because that's very modularized.)
Or, if you want, errno.h or any of the other less-well-thought-out include
files.
Of course, if someone comes along and does a #define in some include file
that conflicts with something in stdio.h, then you're screwed too. Ever
spend three days trying to figure out why putting
extern int write(int,char*,int);
at the top of your source code so you could print some debugging info throws
a compiler error saying "too many close braces"?
>>> If you are using a tool to create the dependency lists and that tool
>>> fails for some reason, blame the tool, not make.
>
>> If I'm using a tool to create makefiles, then sure, but that's just saying
>> makefiles are so useless that I have to automate their creation. Why would I
>> use a tool to create makefiles using a tool that just does the job properly?
>
> You could make the same argument for any program that doesn't do everything,
> and needs to work in conjunction with another program in order to perform
> some task. Your argument is moot.
No. I'm saying that make only does one thing, and it does it so poorly that
almost nobody actually uses it manually. I'm not against independent tools.
> As for makefiles, not all things that can be done with makefiles can be
> automated.
No. And those things that can be done with makefiles like that shouldn't be
using makefiles to start with, because it's probably the wrong tool.
>> There's really only one task going on here - dependency checking. That's the
>> one and only thing Make does.
>
> Make can't know if eg. a code-generating program depends on some data
> files unless you tell it.
Yep! And there's the problem.
Right now, for example, I have an XML file I use to specify the levels for
my game. In those XML files I include the lists of animations going on in
different places, the textures, etc etc etc.
Know what? Make doesn't handle that. Know what else? The tool I'm using
does, because as I compile that XML file into the internal format, I'm
telling the build system "By the way, the results of compiling this XML also
depends on that texture, that sound effect, and those two animations."
If I were to try to do this with Make, I'd either be repeating all the
information manually, or I'd have to write a program to parse that XML file
and pull out the appropriate dependencies, except output them in a different
way.
> I gave an example in my other post of an actual project I have been
> working in where makefiles are useful for something else besides purely
> compiling C++.
Yes, I think we crossed in the mail.
>> I'm sorry, but if anyone in the world asked me "how do I invoke the gcc
>> compiler", I'd say "use /usr/bin/gcc" or something. I would *not* add "but
>> be careful not to pass the -M flag, because that doesn't invoke the compiler."
>
> Actually I'm invoking the C preprocessor. I could call it directly, but
> gcc does it automatically when you specify the -M parameter. The calls
> "gcc -M test.cc" and "cpp -M test.cc" produce the exact same result.
> I could simply use the latter if I wanted to be pedantic.
I'll just let this one drop, if you're actually going to argue that "C
preprocessor" isn't a part of the compiler.
> Instead, we have "project files" in IDEs which do... what? Well, exactly
> the same thing as makefiles.
No. They solve the same problem that makefiles are supposed to solve. They
don't do the same thing as makefiles. And that's the distinction I'm making.
It's like saying "C++ does exactly the same thing as C: It takes a fairly
machine-oriented source file and turns it into machine code." But you would
give me grief for saying that without pointing out that C++ does it much
*better* than C, and solves some of the problems that C simply can't handle,
right?
> In fact, "project files" are just makefiles,
No, they're not.
> using some other IDE-specific syntax. (They might have features that 'make'
> doesn't support, but in principle they are the same thing.)
And in principle, C++ is the same thing as C, it just has some features that
C doesn't support, right?
> The only difference is that most IDEs generate the dependency rules for
> source code files automatically so you don't have to write the few magic
> lines into the project file yourself.
No. Most of them have a different way of both specifying and evaluating
dependency rules.
> However, again, in principle it's
> no different from a generic makefile that generates dependency rules
> automatically (like the one I pasted in an earlier post).
No, that's exactly what I'm saying. Did you even read what I wrote is in the
"makefile" of a C# project? In what sense is that "the same thing as a
makefile", other than it solves the problem of only recompiling what needs
to be recompiled?
In C#'s project files, there are names of neither source code files nor
object code files, other than "here's the list of files to compile into this
project". They're just not in there. You don't have to specify other files
you depend on. You don't have a list saying "this file depends on that file
and the other file".
> You still can't get past the fact that in unix different tasks are
> separated into different tools. Fine, you hate that. Move on.
You're completely ignoring what I'm saying. Fine, move on.
Actually, now that I think about it, yes, this actually is part of the
problem. The problem is that the thing that actually *depends* on those
dependencies is indeed independent of the build system, and that means you
have to put the same dependency information in two different places.
Thinking on it (see the end of this mess), this is exactly how the Visual
Studio build system gets around the problem, regardless of the complexity of
the dependency chain. The first time you compile the program, it saves what
other files it depended on. So, basically, the first "make" creates the
makefile for you. It also, incidentally, thus knows what the output files
are that were created and can safely delete them when you clean without
accidentally clobbering something else.
I prefer the DRY principle, where my dependencies are only held in one
place, especially when that place is checked automatically. Your suggesting
that -M is sufficient is simply making the thing ass-backwards, building the
dependency list for the compiler instead of vice versa. You're basically
running the code thru the compiler to figure out what the dependencies are,
then using those dependencies to run the code through the compiler *again*.
Other build systems eliminate that first step, which is one less set of
duplicated data you have to manually keep up to date right there.
>> Now, go regenerate the rules without
>> the -M flag.
>
> And why exactly would I want to do that? You might as well ask "compile
> the program without using the compiler".
And you'd complain if one of the steps of compiling the program was to tell
the compiler what machine code to generate for different parts of your code,
right?
>> I'm not saying that generating the dependencies, *today*, isn't
>> easy. I'm saying that the job Make was created to handle, namely recording
>> and evaluating dependencies, is obsolete.
>
> And how do you propose to handle dependencies on things that the compiler
> does not handle, such as creating data files from some input files using
> some tools (and perhaps recompile the program only if those data files
> change)?
Yet, oddly enough, that's what I've been doing all week. Funny, that.
Certainly I say what compiler handles each kind of source code: I can't run
a PNG file through gcc. But that's just setting a default rule for a
particular piece of code.
>> Makefile dependency lists are, for
>> the most part, created by other tools
>
> Only program source code dependencies. If you have other types of
> dependencies you still need to specify them by hand because no automated
> tool can read your mind.
No, this is just factually incorrect. I have no need to specify by hand
that my animation as specified in my XML depends on those six files. (Well,
obviously, I'm specifying it in the XML just like I'd be writing #include
into my C sources. I'm not specifying it anywhere outside my own data files,
tho.)
Note also that this means when I change compiler options (like whether I
have debugging or optimization turned on, etc) then I can recompile the
code, because the compiler has the opportunity to store a dependency on its
own command-line arguments, or at least the command-line arguments that
might make a difference in whether the object code will be different.
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Patrick Elliott wrote:
>>> Trying to work out what went wrong, and why, from the damn code, and the
>>> code that built the code, and the code that ran the code, that built the
>>> code... o.O
>
>> Precisely. When the configuration file to create the build tools is based on
>> turing-complete macro processing, you're gonna just be screwed if there's
>> anything wrong.
>
> Yet this is still somehow a problem with makefiles.
Where did I say makefiles in there?
I'm railing against arbitrarily complex build systems where you can't look
at the configuration file and figure out what it's going to compile. It's
the same thing I have against C include files: if they were limited to
declarations, it would be far, far less of a problem.
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Warp wrote:
>>> Darren New <dne### [at] san rr com> wrote:
>>>> Besides, I thought you don't like C either.
>>> The issue was the #include scheme, which you seem to hate and I really
>>> can't understand why.
>
>> Experience! :-)
>
> Or lack thereof, it seems.
Nope nope. Shell shock. Zeno's Debugging.
I had a function that looked something like this:
RMint open(RMchar* name)
{
RMerr err;
RMthing = RMDoThing1(name);
RMother = RMDoOther(name, RMthing);
RMstuff = RMStuff(RMthing);
.....
return (RMint) 0;
failure:
return err;
}
And what was coming back from that function was 0x19382. And I had to figure
out which function was doing that.
Nowhere in the function do we actually have a goto, nor do we assign to err.
Nowhere in any source file anywhere was there the number 19382 or its
decimal or octal equivalent.
I attempted to use the debugger, but there were calls to precompiled
libraries without debugging information that was calling back to this
routine, so that didn't work.
After I figured out that RMDoThing1 and ilk were actually macros that
assigned to err and did "goto failure" if it wasn't zero, I then had to do a
full recompile of all the code with stdout redirected to a file, then track
down the name of the .c file this code appeared in, then look thru the
command line arguments to gcc to see which include file directories appeared
in what order, then look at each of the dozen RMblah.h files in those
directories in the right order (because each of them appeared in several
directories) and do that recursively looking for the definition of each of
those files to find the one that actually had each of those macros in it.
(In hindsight, I probably should have used -E to see if I could figure it
out, but that probably would have failed the way my luck was going.)
*Then* I had to figure out that somewhere in the dozens and dozens of
include files was a line that said
#define char }}}}
because they didn't want you using a char, they wanted you using a RMui8 or
some such nonsense. Spend half a day trying to figure out why
extern int write(int,char*,int);
won't compile at the top of your file and see how much you like C #includes.
Once I tracked that down, I had to figure out what the string was for that
error message. I.e., what the defined symbol was. But the actual value
didn't appear in any of the files. Indeed, the #include files wwere full of
crap likle
#define ERR_NOTFOUND (ERRCURR+1)
#define ERRCURR (ERRCURR+1)
which means if you included the include files in a different order, or added
one or left it out, your error numbers would change.
OK, so finally add -E. Nope, sorry, the makefile depends on environment
variables passed down from several makefiles above, *and* parts of it get
recreated as part of that process, so changes you make to this makefile get
clobbered. You have to go track down the source code for the makefile that's
actually compiling the code. Good thing you saved the complete log of stdout
and stderr while you were compiling so you could see which makefile in the
process clobbers the makefile you're trying to modify, and see where it's
coming from, assuming they didn't put an @ in front of that bit.
Over a week of work to track down which function call was returning the
error and what it meant, due directly to #include, #define, and makefiles.
And, admittedly, really really *bad* programming of those things.
So, in summary, no, not everyone who disagrees with your conclusions is a
fool with no knowledge of the process.
> It just looks to me that whenever there is a problem with something,
> you just love to blame it on C/C++ if it's somehow involved.
I believe that's because you don't look at what I'm saying objectively, and
instead you simply say "Oh, Darren's on about C again, and since I don't
have problems with it, he must just not know what he's talking about."
> And which tool, exactly, did you recommend instead? I remember you
> mentioning shell scripts. Yeah, those can track dependencies just fine.
Indeed they can, when you don't have nested dependencies. The original
question wasn't about dependencies at all. His original question was how to
compile a bunch of .c files into corresponding executables without getting
a.out as the result. That has nothing to do with dependencies, and telling
him to use make when a simple one-line shell script works is overkill.
Really. Go back and read the first post. Nowhere in there is a question
about dependency tracking.
> You *could* have a separate dependency rule creation tool that does
> nothing else. On the other hand, it was easier to add that to the C
> preprocessor, so they did that.
Or, you could have the tools generate dependency information as they compile
the first time.
>>> *That* is essentially what
>>> you are complaining about. In other words, the C/C++ compilers doesn't do
>>> everything out-of-the-box, but instead you need additional tools.
>
>> Nope. Other languages have separate tools too. It's just built into the
>> compiler for simple cases.
>
> So when other languages have dependency rule generation built in, it's ok,
> but when the C compiler has, it's somehow not ok.
You're completely ignoring the point I'm making, apparently solely to be
right.
>>> Well, if you don't like it, then don't.
>
>> And *that*, my friend, is how this discussion started.
>
> In other words, you didn't answer his question, which is my point.
I *did* answer his question. I provided him a shell script to recompile the
programs he wants compiled. He didn't ask about make. He asked about how to
name the files. Someone else said "use make". I said "make is inappropriate
for that."
>> Andrew asked about
>> make, I said "You won't like it, so use something else", and you got upset
>> that I explained why he won't like it. :-)
>
> And what exactly is that "something else"? How was your answer helpful
> in any way?
You said "if you find yourself compiling the same programs over and over,
that's what Make is for." No, make is for tracking dependencies. I
suggested he hit the up-arrow key, or use !!, or put the command line to
compile all his programs into a shell script, all of which would answer hsi
original question of "how do I take a .c file and turn it into an object
file with the same name as the .c file without the extension."
Yes, Make can do that. But a shell script is easier for someone who doesn't
want to learn make.
>>> You are, hence, barking up the wrong tree. It's not the programming
>>> language that is the "problem". It's the separation of compiler and
>>> dependency file system that irks you.
>
>> No, it's the inability to correctly figure out dependencies based on the
>> source files that's really the cause of the troubles.
>
> So now you are changing the argument.
No. The programming language is such that it is impossible to figure out by
looking at the source code what the dependencies are on other source code.
Most other systems don't have that feature. In Java, the .class file
depends on the .java file, for example, and nothing else.
> First the problem was that you
> need a separate tool to generate the dependency rules, but now the problem
> is "the inability to *correctly* figure out dependencies", whatever that
> means.
If I give you a collection of source files, you can't tell by looking at
them what the dependencies are. That information isn't stored in or with the
program itself.
> Which tool incorrectly figures out the dependencies?
It's non-trivial to figure out the correct dependencies, to the point where
you (a) need a tool to do it and (b) very often need to run the entire build
system to figure out what gets included where.
> Why does it feel that you are desperately trying to pile up more and more
> perceived problems to the issue?
Because you keep dismissing the problems I present as "not a problem", so I
keep backing farther and farther up the chain of causality until you go
"yes, I agree that happens."
>> > You just love
>>> to hate C, so you just can't miss an opportunity to bash it.
>
>> I actually like C.
>
> You are certainly making a very good job at hiding it.
There are things with C that cause problems. This is one of them. It's
something you have to be very careful about. Building big systems in C is a
difficult thing to do and takes great care, and I have been burned many
times in my life working on big systems in C that
>> Yet, oddly enough, that's precisely what the XNA content pipeline does, and
>> you just give it a list of all the source files, including the graphics and
>> audio and stuff. Sure, you mention the name of the code used to compile it,
>> but there's enough information from that to track down where the executable
>> and such is. It also makes it possible for the thing that's compiling your
>> collection of frames into an animation to say "the resultant animation
>> depends on this list of frames as well as the text file specifying the list
>> of frames", which you can't do with a makefile.
>
> I don't get it. That's exactly what you do with make,
Nope. It's not what you do with Make, any more than writing C++ code is the
same thing you do when writing C code.
> Why does it feel that you are desperately trying to pile up more and more
> perceived problems to the issue?
Why does it seem you're off-hand dismissing significant differences without
even thinking about what I'm saying?
> Maybe what irks you is that with makefiles you need to write a bit more
> syntax to get the same effect.
No, it is, in part, that the information in the makefiles is separate from
the actual build system, so you have to duplicate the information.
>> You can achieve it with a makefile, yes, but primarily not by having the
>> dependency stuff going on, but by building them as different projects. That
>> is, one tends to have a top-level makefile that says "first run make on the
>> content generator, then run make on the content, then run make on the
>> packaging directory."
>
> I suppose you could do that, but I don't think it's necessary.
I've never seen it done differently. I suppose you could have one giant
makefile for a complex project, but most times I've seen it done with
recursive makefile invocation. Indeed, there are entire sections of the make
manual and options to makefile variables that provide for this usage, so
it's not exactly uncommong.
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> Warp wrote:
>>> In Ada, you don't calculate the checksums of every source. You
>>> calculate the checksum of the file you're compiling when you compile
>>> it. In C#, your file is either associated with a project (i.e., with
>>> the equivalent of a makefile) or it's installed in the global
>>> assembly cache with a version number and a cryptographic checksum on
>>> it you can check against.
>>
>> So if you have thousands of files in your project, the compiler will
>> calculate the checksums of every single one of them every time you want
>> to compile? And it was you who complained how creating makefile rules for
>> C files is inefficient... Right.
>
> Read the second sentence again. You calculate the checksum of the file
> when you compile it. You then store that in the object code.
Oh, and just as an aside, GNAT did it this way for a while, and then they
found it really was faster to actually re-read the header file and generate
the checksum and (essentially) recompile it than it was to track a separate
object file for the header file. So, yeah, in practice, not a problem. Read
their documentation for details. :-)
--
Darren New, San Diego CA, USA (PST)
"How did he die?" "He got shot in the hand."
"That was fatal?"
"He was holding a live grenade at the time."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 1/30/2011 1:54 AM, Warp wrote:
> Darren New<dne### [at] san rr com> wrote:
>> Patrick Elliott wrote:
>>> Trying to work out what went wrong, and why, from the damn code, and the
>>> code that built the code, and the code that ran the code, that built the
>>> code... o.O
>
>> Precisely. When the configuration file to create the build tools is based on
>> turing-complete macro processing, you're gonna just be screwed if there's
>> anything wrong.
>
> So let me get this straight: He was trying to compile a program with
> Visual C++, the project did not have a Visual C++ project file, he was
> trying to compile it in Windows which is not Unix and hence does not use
> the same core tools, and consequently he had big problems in compiling
> the program. Yet this is still somehow a problem with makefiles.
>
> It seems to me that anybody could make a post with any random problem
> they had, and if a makefile was somehow involved, you would immediately
> rush to agree with a "precisely!" answer regardless of what was the real
> cause of the problem.
>
It did have a VC++ project file, unfortunately that project file
included calls to Unix tools, to generate the changes needed to make it
compile. A project file is just another name for a MAKE file (at least
on Windows). It has processing logic, and can call externals, etc.
--
void main () {
if version = "Vista" {
call slow_by_half();
call DRM_everything();
}
call functional_code();
}
else
call crash_windows();
}
<A HREF='http://www.daz3d.com/index.php?refid=16130551'>Get 3D Models,
3D Content, and 3D Software at DAZ3D!</A>
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 28/01/2011 05:28 PM, Darren New wrote:
> But here's a question: Does it only regenerate the pages of
> documentation for the files where the source of the documentation has
> changed?
There are two kinds of documentation to consider.
GHC comes with a User Guide and a handful of other miscellaneous files,
which are written in DocBook. GHC also comes with a small handful of
Haskell libraries, which each have API reference documentation embedded
in the source code. This is extracted and turned into HTML by a tool
called Haddock.
Due to the amount of cross-referencing possible, editing any single
source file can potentially affect an arbitrary number of documentation
files. Short of a tool to actually analyse a source tree and figure out
all the dependencies, it's difficult to handle this properly. You would
need a tool to read the entire source and compute the dependencies.
GHC doesn't bother. If any source file changes, the whole documentation
is rebuilt. Notice, however, that if the source for document X changes,
only document X is rebuilt. So some level of dependency analysis *is*
being done. (And especially since the documentation is of more than one
form, so you have to know how to rebuild it correctly.)
> Does it only re-run test cases for code that has been
> recompiled since it last ran test cases?
AFAIK, all of the test cases work by running the final, finished
compiler. I don't think there are any "unit tests" that test just one
program module or something. Thus, if any compiler source code changes,
the entire compiler is recompiled, and the entire test suite rerun. Same
for the benchmarks. (Benchmarks of course depend on almost every part of
the compiler, so it would be infeasible to do it any other way.)
> Or is it more like "this would
> be a shell script, but we already have a makefile so we might as well
> put it in there"?
Well, to some extent, yes. Although Make is selecting the correct shell
script to run in each case...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> > Anyways, exactly why would you want to recompile your program if stdio.h
> > changes? You see, stdio.h is standardized, and if it was changed in such
> > way that programs would need to be recompiled for them to work, it would
> > mean that the C standard has been changed to be backwards-incompatible and
> > it would break basically all programs in existence.
> Nope. All I need to do is redefine O_RDWR to have a different value or
> something like that. (OK, not stdio.h, because that's very modularized.)
> Or, if you want, errno.h or any of the other less-well-thought-out include
> files.
And you would immediately break like every single program in your system.
Way to go. (And please don't claim that you don't know why they would break.)
> Of course, if someone comes along and does a #define in some include file
> that conflicts with something in stdio.h, then you're screwed too. Ever
> spend three days trying to figure out why putting
> extern int write(int,char*,int);
> at the top of your source code so you could print some debugging info throws
> a compiler error saying "too many close braces"?
Never miss a chance to bash C.
> > Make can't know if eg. a code-generating program depends on some data
> > files unless you tell it.
> Yep! And there's the problem.
The problem is that 'make' cannot read your mind, it seems.
Of course it cannot know which files a something depends on unless you
tell it. Seems rather obvious to me.
> Right now, for example, I have an XML file I use to specify the levels for
> my game. In those XML files I include the lists of animations going on in
> different places, the textures, etc etc etc.
> Know what? Make doesn't handle that.
Sounds like something 'make' was specifically designed for.
> Know what else? The tool I'm using
> does, because as I compile that XML file into the internal format, I'm
> telling the build system "By the way, the results of compiling this XML also
> depends on that texture, that sound effect, and those two animations."
> If I were to try to do this with Make, I'd either be repeating all the
> information manually, or I'd have to write a program to parse that XML file
> and pull out the appropriate dependencies, except output them in a different
> way.
You are constantly shifting the goalposts, and don't seem to be able to
decide if you want to bash makefiles or C, whether what you want is
impossible to do with makefiles or simply more laborious, whether the
problem is that what you want to do is not possible solely with 'make' but
instead you need a third-party tool, or what.
Sometimes it's "make sucks because of the include file system in C",
sometimes it's "make sucks because it can't do this", sometimes it's
"make sucks because while you can do this, it's more laborious than with
this other fancy tool I have", sometimes it's "make sucks because you
need to use the compiler to generate dependencies".
You don't seem to understand that 'make' is a generic tool. Or more
precisely, you don't seem to understand what the word "generic" means.
You seem to think that it should mean "supports all programming and
markup languages in existence out-of-the-box, and is able to read your
mind". That's not what "generic" means.
You have made it abundantly clear that you don't like the fact that
you need, oh gosh, third-party tools if you want to automatically create
dependency lists for some specific file formats. "Hey, I have these files
in this format, and I have this specialized tool that tracks dependencies
on them automatically, and 'make' cannot do that automatically, hence
'make' sucks." Way to miss the point.
And the best part of all this? So far you haven't given even a single
alternative that would do everything that 'make' does and is better by
your definition (whichever that might be). And preferably one that can
be run in most systems.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Patrick Elliott <sel### [at] npgcable com> wrote:
> A project file is just another name for a MAKE file (at least
> on Windows).
Not according to Darren.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> >>> The issue was the #include scheme, which you seem to hate and I really
> >>> can't understand why.
> >
> >> Experience! :-)
> >
> > Or lack thereof, it seems.
> Nope nope. Shell shock. Zeno's Debugging.
You have seen a lot of bad C code. I understand that. That's not what
I'm arguing.
> > And which tool, exactly, did you recommend instead? I remember you
> > mentioning shell scripts. Yeah, those can track dependencies just fine.
> Indeed they can, when you don't have nested dependencies.
"Indeed thay can"? Shell scripts don't have any kind of dependency
tracking whatsoever. I think you are somehow splitting hairs with
terminology.
> The original
> question wasn't about dependencies at all. His original question was how to
> compile a bunch of .c files into corresponding executables without getting
> a.out as the result. That has nothing to do with dependencies, and telling
> him to use make when a simple one-line shell script works is overkill.
Exactly how do you compile a bunch of .c files into corresponding
executables with "a simple one-line shell script"?
Ok, you could write a 'for' loop which goes through a list of .c files
and compiles them (resolving the name of the executable by removing the
".c" part) and put all that in one line, but putting all commands into
one single long line is not what is usually meant by a "one-liner"
(except perhaps in the IOCCC). "One-liner" usually refers to being able
to express the task with one single command (a 'for' and its body are
usually considered separate commands).
Perhaps what you meant was one line per program. That could probably
work for what he wants to do, if he doesn't mind that *every* program
will be recompiled every time he wants to recompile just one of them.
This is exactly where a makefile would be useful: It would compile
only the program that needs recompiling, skipping the others. And even
if you wanted to go the easy way and just not have to specify any
dependencies, you can still use the makefile to compile only what you
want to compile (with something like "make program3").
The advantage of that over having a separate shell script for every
single program? You only need to specify compiler options (eg. warnings
and optimizations) once, rather than duplicating it in each script.
(Of course you could have each script call a common script that has the
options, but that starts already being a lot more complicated than the
makefile would be, for no discernible benefit.)
If you want to compile only one single program, or automatically compile
only the programs that need to be compiled, the *easiest* way is to use
a makefile. A shell script would be significantly more complicated. After
all, that's precisely what makefiles are for.
> I *did* answer his question. I provided him a shell script to recompile the
> programs he wants compiled. He didn't ask about make. He asked about how to
> name the files. Someone else said "use make". I said "make is inappropriate
> for that."
Which is BS. You seem to think that you can't create a makefile that
compiles programs without the dependency lists. It's not like you are
forced to provide them.
Creating a shell script for this is the hard way.
> >>> You are, hence, barking up the wrong tree. It's not the programming
> >>> language that is the "problem". It's the separation of compiler and
> >>> dependency file system that irks you.
> >
> >> No, it's the inability to correctly figure out dependencies based on the
> >> source files that's really the cause of the troubles.
> >
> > So now you are changing the argument.
> No. The programming language is such that it is impossible to figure out by
> looking at the source code what the dependencies are on other source code.
If that were true, then it would be impossible to compile the program.
After all, it's impossible for the compiler to figure out which files are
being included just by looking at the source code.
I suppose compilers do it by magic, then.
Besides, you *are* changing the argument. First it was "make cannot figure
it out on its own", then it was "it's not possible to correctly figure out
the dependencies" (whatever that means, as I still don't get it).
Let's see where will you move the goalposts next.
> > Which tool incorrectly figures out the dependencies?
> It's non-trivial to figure out the correct dependencies, to the point where
> you (a) need a tool to do it and (b) very often need to run the entire build
> system to figure out what gets included where.
Oh, now "inability to correctly figure out dependencies" has been changed
to "it's non-trivial to figure out the correct dependencies".
Keep moving the goalposts. Which fancy term will you use next?
Why does it feel like you are desperately trying to find problems and
just can't seem to be able to decide what the actual problem is?
> >> Yet, oddly enough, that's precisely what the XNA content pipeline does, and
> >> you just give it a list of all the source files, including the graphics and
> >> audio and stuff. Sure, you mention the name of the code used to compile it,
> >> but there's enough information from that to track down where the executable
> >> and such is. It also makes it possible for the thing that's compiling your
> >> collection of frames into an animation to say "the resultant animation
> >> depends on this list of frames as well as the text file specifying the list
> >> of frames", which you can't do with a makefile.
> >
> > I don't get it. That's exactly what you do with make,
> Nope. It's not what you do with Make, any more than writing C++ code is the
> same thing you do when writing C code.
Maybe *you* don't use 'make' for that, but I do.
Then, perhaps your preferences are "right" and mine are "wrong".
> > Maybe what irks you is that with makefiles you need to write a bit more
> > syntax to get the same effect.
> No, it is, in part, that the information in the makefiles is separate from
> the actual build system, so you have to duplicate the information.
But it's what allows you to generate building rules for things that don't
have any automated tools. (And yes, the same thing can be done with the
'project' files of most IDEs. They are, after all, doing basically the same
task.)
I wrote an example earlier: Suppose you have written a program that
generates code, and it generates the code from some data files. Obviously
you would want the program to be run if (and only if) some of those data
files change. Exactly which automated tool would you use to do this?
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |