I am creating a program in assembler, using several modules. The Assembler manual states that using the EXPORT directive, without any arguments, exports all symbols from the module. When I use this construct, I get flooded with undefined symbol errors. I have to go back and individually export each symbol in order to get a clean assembly and link. Is this an artifact of using an evaluation license, or is something screwy going on. I tried EXPORT * and it really yelled at me. Having to individually export all of the variable names and equates would be a major hurt. Thanks.
>>Having to individually export all of the variable names and equates would be a major hurt.
Scratches head, and writes an AWK script..
Puts common stuff in an include file.
You really don't want to pollute the global name space with everything, I wouldn't even try using EXPORT in the fashion suggested.
I talked that over with one of the other guys here, and it does seem that an include file would work. It still doesn't get around the question of why the EXPORT everything doesn't work as advertised. Thanks.
I am creating a program in assembler, using several modules.
Apparently not really. If they really were several modules, as opposed to just a single, monolithic program split into several files, you wouldn't be trying to export everything to everybody.
Having to individually export all of the variable names and equates would be a major hurt.
That's one of the most helpful hurts you'll have suffered in a while. Let me explain that by way of an adage that even made it to the Jargon File:
Patient: Doctor, help me! Every time I do {insert wild gesture here}, it hurts like heck! Doctor: Well, so don't do that, then!
That pain you're facing is, figuratively speaking, your program yelling at you: "Don't do that, then!"
The way you're planning to do this offers essentially no benefits over just pasting the entire source code back into a single source file. Modules worthy of that name have interface specifications, and they export only that interface, not their entire inner workings. That interface is then published in an include file for other modules to refer to. Things should go into the module's inferface on a strict needs-to-be-there basis, only.
Right now, your point-of-view seems to be: "Because I don't know what needs to be exported, I'll just export everything." But not knowing is hardly ever a good basis for any decision. The exact opposite approach is what you should do: export nothing to begin with, then add only those things that really need to be. Among other things, this way you'll end up knowing more about your program. You'll not just have figured out what had to be in the interface, but also why.
Is the error coming from the LINKER or the ASSEMBLER?
Common equates would fit in an include file, symbol dependent ones obviously not so much.
This is a user forum, not a Keil Support venue.
In my 8051 code, I did just have one program, with a lot of individual subroutines to do the actual work. I would keep all of the equate and variable definitions in one place, at the start of the source code. That kept everything in one spot and let me keep track of them. Since all of the ARM stuff seemed to urge the use of separately assembled and linked modules, I decided to try that. It would seem to have been the same amount of work. The module that I was trying to export everything from was the one where I defined all of my RAM variables and the program equates. There is a bunch of these, so it would be best not to have to export them one-by-one. The rest of the modules just export a few items, and those should be exported by name.
I assume that it is the linker that is screwing up. I can assemble the modules individually and they all do OK. It is when I build the entire project that it can't resolve the external symbols.
I have a number of work-arounds, but I was curious if anyone else had run into the same situation.
Tim
Nothing specifically to do with ARM there - that has been a basic tenet of all forms of software development for decades now!
"In my 8051 code, I did just have one program"
I guess you mean one file?
You can get away with that on small projects with a single developer on a simple chip - but even then it's not a great way to go.
"I decided to try that"
There's more to it than just using a number of different files.
As already noted, a key part of Modular Design is to have well-defined interfaces - not just to make everything globally visible.
"I have a number of work-arounds (sic)"
That's like saying, "I'd like to use one of these new-fangled car thingies, but I can't see how to hitch-up my horse. As a workaround, I did..."
en.wikipedia.org/.../Modular_programming
My first Pascal program was just a single file. It grew and grew and grew and I scrolled and I scrolled and I scrolled. That editor refused to make the file larger than 64kB in which case I just had to split the code into multiple source files.
For some strange reason, I liked having multiple files where each file contained functions with a specific purpose, and where I didn't had to scroll so much. So I decided to continue to use multiple source files even when the editor wasn't the limiting factor - I have never seen a reason to change my mind.
Modern tools can handle truly huge source files, and even a full recompile after each change is normally quite quick. But it just is no fun to try to maintain such a project.
But as noted earlier - when splitting code into modules, not all of the code in the modules needs to be accessible from the outside. Each module should have a public interface and have everything else hidden.
A huge number of global variables? The question then is if not much of these global variables should have been combined as individual fields in structures or maybe C++ classes. Or if some of the data should have been completely hidden inside different modules, with only some accessor functions available to operate on the actual data values.
But the global name space should really not be too littered with symbols.
The module that I was trying to export everything from was the one where I defined all of my RAM variables and the program equates.
Even having such a "module" is bad news already, because that really isn't a module.
The vast majority of those RAM variables almost certainly belong to other modules, and should be in those modules, not in a single big "all things that go into RAM" module. And a good portion probably doesn't have to be exported at all, once they're in the right module, because they'll only be used from inside that module. That's a big part of what modularization is about: making a clear distinction between things that belong together and things that don't, thus having a lot fewer things out in public.
I assume that it is the linker that is screwing up.
To put none too fine a point on it: no, you are. The linker is doing exactly what you told it (and the assembler) to do. You screwed by telling the assembler the wrong things to do.
And FWIW: being this quick at blaming at their tools isn't exactly a promising sign in new programmers.
Most people know better than to run themselves into that situation in the first place.