LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-06-2004, 03:04 PM   #16
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15

As a thought experiment, I tried the following:

In foo.c _
Code:
int baz();

int foo()
{
	return baz();
}
In bar.c _
Code:
int baz();

int bar()
{
	return baz();
}
In baz.c _
Code:
int baz()
{
	return RESULT;
}
In main.c _
Code:
#include <stdio.h>

int bar();
int foo();

int main(void)
{
	printf("foo %d\n", foo());
	printf("bar %d\n", bar());
}
To build the beast _

Code:
gcc -c foo.c
gcc -c bar.c
gcc -o baz1.o -DRESULT=1 -c baz.c
gcc -o baz2.o -DRESULT=2 -c baz.c
ar rcs libb.a foo.o baz1.o
ar rcs libf.a bar.o baz2.o
gcc --static main.c -L. -lb -lf -o main
When I ran ./main, you can guess what it gave me:

Quote:
foo 1
bar 1
Unless I missed something, the last invocation of gcc links only one copy of baz().

Sorry, Charlie.
 
Old 10-06-2004, 03:21 PM   #17
vose
Member
 
Registered: Aug 2002
Location: tennessee
Distribution: gentoo
Posts: 39

Original Poster
Rep: Reputation: 15
I also can think of many things which do not work!
Hence my question: what does work?

I can certainly write code/scripts which will temporarily change
baz.c so that it's functions are static, and then proceed along the
lines of scenerio one (with includes, etc...), after which baz.c is
restored... That approach does work.

But if there are standard tools which could do the job (with
appropriate flags perhaps) then I would like to know about them
and how they are used to accomplish what otherwise I would
have to write code/scripts for.
 
Old 10-06-2004, 03:22 PM   #18
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Of course, changing the build script to _

Code:
gcc -c foo.c
gcc -c bar.c
gcc -o baz1.o -DRESULT=1 -c baz.c
gcc -o baz2.o -DRESULT=2 -c baz.c
ld -o f.o foo.o baz1.o
ld -o b.o bar.o baz2.o
gcc -o main main.c f.o b.o
gives us _

Quote:
ld: warning: cannot find entry symbol _start; defaulting to 00000000080480b4
ld: warning: cannot find entry symbol _start; defaulting to 00000000080480b4
b.o(.text+0x10): In function `baz':
: multiple definition of `baz'
f.o(.text+0x10): first defined here
collect2: ld returned 1 exit status
Sorry, Charlie.

Unless I've missed something, I think you'd have to do as I suggested previously, and use macro templates to generate functions with different names for your -Dmacro=def. I know it's not what you wanted-and I may have missed something-I'm no expert, by far-but let's use the tools to do as their designers designed them to work.
 
Old 10-06-2004, 03:30 PM   #19
vose
Member
 
Registered: Aug 2002
Location: tennessee
Distribution: gentoo
Posts: 39

Original Poster
Rep: Reputation: 15
Again, you have provided something which does not work.
I also can produce many examples of things which do not work.
That is not the point.
 
Old 10-06-2004, 03:35 PM   #20
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Quote:
I also can think of many things which do not work!
Hence my question: what does work?
By going through things which won't work and giving my interpretation of why they don't work, I'm wondering if one of us will think of something that WILL work.

Your pretend build process _

Quote:
...
d --output=f.o --relocateable --MAKE_STATIC_ALL_FUNCTIONS_IN_FILE=myfile foo.o baz1.o
ld --output=b.o --relocateable --MAKE_STATIC_ALL_FUNCTIONS_IN_FILE=myfile bar.o baz2.o
...
tries to make functions static when you defined them as non-static. Obviously, the developers of ld either hadn't anticipated this use or decided for one reason or another not to implement it (unless you can find a flag that works as you want it to function).

In order to accomplish what you want, our tool would have to remove the symbols that you don't want the linker to see from the symbol table. I played with LFS for a day or so, and I recall that when you wanted to change the libraries with which the tool chain would work, you would awk one of the shared objects to change an entry. Now, obviously these shared libraries were no more than lists of library names, but it might give you ideas.

I don't recall seeing such a tool that would selectively remove entries from the symbol table of an object file.

Sorry, Charlie.
 
Old 10-06-2004, 03:55 PM   #21
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Quote:
Originally posted by vose
Again, you have provided something which does not work.
I also can produce many examples of things which do not work.
That is not the point.
Oh, give me a break. I'm looking at this as a puzzle, and it intrigues me. You asked the question, and I've attempted to find a solution. Have you given any feedback to my experiments, other than complain that I haven't given you the answer? Go cry to your mama, or come up with a better way to solve the problem.

I suggested template macros. It sounded like an elegant solution to me. I even suggested it twice. You gave me no feedback.

You suggested a script to alter the code, but you want an alternative.

If you've looked for a tool to do what you want to do and haven't found it, and you think you've looked in all the right places and feel that you won't find it, write the tool. I told you what the tool needs to do. Sure I haven't delved into all of the details-and I don't know all of the details by rote-but I think my explanation sums it up.

Put up or shut up. Someone is interested in finding the same solution that you want to find. I would think that you would welcome it. But NO! All I get from you is that you could make as many mistakes trying to find an answer. Well, LA-TI-FREAKING-DA. So what?

I give up.

Last edited by Stranger; 10-06-2004 at 04:09 PM.
 
Old 10-06-2004, 04:21 PM   #22
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Come on girls, play nice.

vose: you're not paying anyone here, so stop whining,
he has the right to add ideas even if they don't do what
you expect.

stranger: if you don't like him (or his attitude), don't post
to his thread. No accusations.


Cheers,
Tink
 
Old 10-06-2004, 05:52 PM   #23
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Tinkster: I apologize for my outburst. But.... Oh, nevermind. Back to our program.

baz.h

Code:
#define BAZ(R) \
int baz##R() \
{ \
	return R; \
}

#if RESULT == 1
#define baz baz##1
#elif RESULT == 2
#define baz baz##2
#endif
baz.c

Code:
#include "baz.h"

#if RESULT == 1
BAZ(1)
#elif RESULT == 2
BAZ(2)
#endif
foo.c

Code:
#include "baz.h"

int foo()
{
	return baz();
}
bar.c

Code:
#include "baz.h"

int bar()
{
	return baz();
}
main.c

Code:
#include <stdio.h>

int bar();
int foo();

int main(void)
{
	printf("foo %d\n", foo());
	printf("bar %d\n", bar());
}
build

Code:
gcc -c -DRESULT=1 foo.c
gcc -c -DRESULT=2 bar.c
gcc -o baz1.o -DRESULT=1 -c baz.c
gcc -o baz2.o -DRESULT=2 -c baz.c
gcc -o main main.c foo.o baz1.o bar.o baz2.o
Code:
$ ./main
foo 1
bar 2
$
Good = fast + correct. You implied that you're comfortable with macros. It would require almost zero maintenance. And it works.

By the way, debugging might prove difficult.

Last edited by Stranger; 10-06-2004 at 06:54 PM.
 
Old 10-06-2004, 07:28 PM   #24
vose
Member
 
Registered: Aug 2002
Location: tennessee
Distribution: gentoo
Posts: 39

Original Poster
Rep: Reputation: 15
Your last post has caught up to my question.

But I am not attempting to resolve name conflicts
by redefining foo.c and bar.c as in

gcc -c -DRESULT=1 foo.c
gcc -c -DRESULT=2 bar.c

in order to create new names, so as to then create matching names
in baz.c by

gcc -o baz1.o -DRESULT=1 -c baz.c
gcc -o baz2.o -DRESULT=2 -c baz.c

Instead, I hope to leave foo.c, bar.c, and baz.c *alone* so that I
don't have to rewrite them or make them any more complicated
than they already are.

My intent -- and the point of my question -- is indicated fairly well
by the "pretend" answer

gcc -c foo.c
gcc -c bar.c
gcc -Dmacro=def1 -o baz1.o -c baz.c
gcc -Dmacro=def2 -o baz2.o -c baz.c
ld --output=f.o --relocateable --MAKE_STATIC_ALL_FUNCTIONS_IN_FILE=myfile foo.o baz1.o
ld --output=b.o --relocateable --MAKE_STATIC_ALL_FUNCTIONS_IN_FILE=myfile bar.o baz2.o
gcc -o a.out f.o b.o

I realize that the above does not work, BUT, I am well aware of my ingorance as
to what compilation/linking tools there are. And even if I were cognizant of all
available compilation/linking tools, I certainly would not believe I knew every way
they might be used.

Whereas I most certainly could be wrong as to whether there infact do exist some
tool(s) (like ld, or gcc, or ???) which if provided appropriate arguments (and flags)
would be able to produce an a.out as in senerio one given foo.c, bar.c and baz.c
as in scenerio two---see my original question---it nevertheless seemed plausible
to me that such tool(s) might exist.

Therefore, my question is: what are those tools, and how would I use
them to accomplish that objective?

There could be no better answer (to the question I seek to have answered) than
to simply write code/scripts which will temporarily change baz.c so that it's
functions are static, and then proceed along the lines of scenerio one (with
includes, etc...), after which baz.c is restored... However, for all I know, there
*is* (which is why I asked).
 
Old 10-06-2004, 07:41 PM   #25
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Code:
#if LINKAGE == 0
#define QUICKFIX static
#else
#define QUICKFIX
#endif

...

QUICKFIX void function_name(int param1) {
...
}

...
Code:
gcc -DLINKAGE=0 -c baz.c
Do you really need a script to do this?
 
Old 10-06-2004, 07:53 PM   #26
vose
Member
 
Registered: Aug 2002
Location: tennessee
Distribution: gentoo
Posts: 39

Original Poster
Rep: Reputation: 15
Yes!!! That answer is so simple and beautiful I did not see it.

It is now a more academic question, but one which nevertheless
interests me, namely, whether standard compilation/linking tools
could also do the job.

P.S. The last paragraph is not intended to diminish your reply.
Your answer may very well be as perfect as is possible!
 
Old 10-06-2004, 08:21 PM   #27
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
Ah! But your compiler does do the job! You just use the source and a command-line option to tell it what to do.

I also noticed a particular flag in ld's man page that looks useful for this situation. I just haven't figured out how.

Quote:
-R filename
--just-symbols=filename
Read symbol names and their addresses from filename, but do not relocate it or include it in the output. This allows your output file to refer symbolically to absolute locations of memory defined in other programs. You may use this option more than once. For compatibility with other ELF linkers, if the -R option is followed by a directory name, rather than a file name, it is treated as the -rpath option.
I don't know if it's at all useful.
 
Old 10-06-2004, 08:42 PM   #28
Stranger
Member
 
Registered: Feb 2004
Posts: 38

Rep: Reputation: 15
You could even simplify the above example even further.

Code:
#if defined(LINKAGE)
#define QUICKFIX static
#else
#define QUICKFIX
#endif

...

QUICKFIX void function_name(int param1) {
...
}

...
Code:
gcc -DLINKAGE=1 -c baz.c

or

gcc -c baz.c
 
Old 10-07-2004, 05:57 AM   #29
WhiteChedda
Member
 
Registered: Aug 2003
Location: Florida
Distribution: Mandrake 9.1 for now
Posts: 205

Rep: Reputation: 30
Would using a function pointer within each source, change the way the compiler resolved the symbols at all?
 
Old 10-08-2004, 07:28 AM   #30
vose
Member
 
Registered: Aug 2002
Location: tennessee
Distribution: gentoo
Posts: 39

Original Poster
Rep: Reputation: 15
I don't know, and whereas what I have to say below does not answer your question, it does
fill out to some extent the context of this thread to make things a bit less abstract.
My hope is that by my doing so, readers of this thread may come away with some useful
programming ideas.

First, foo and bar can be generalized to foo, bar-1, bar-2, .... That was the context of
our actual application. Foo was the "master thread" and threads bar-1, bar-2,... were
helper threads running on different processors of a smp gnu/linux system.

The point of the code was to simulate a complex stochastic system. However, having every
thread obtain it's random number stream from a single source lead to debugging problems
since race conditions caused unrepeatable behavior (by single source I mean that each
thread would call the same random number generator; in some sense, of course, these are
"different" generators since each call uses the stack of the calling thread). Debugging aside,
race conditions trashed repeatability.

The simplest answer was to move a copy of the random generator into each thread such that
each thread maintains a separate and independent copy of the random number generator's
state. How to do this without changing the code?!? And we did NOT want to change
the code for at least the reasons that:
1) The better half of the staff would walk out the door if asked to put up with C++ bullshit.
2) Speed mattered, and passing the state as an argument would slow things down.
3) Simplicity was a concern; we did not want to make anything Except Maybe The Make File
more complicated than it already was.
4) We wanted to keep a single simple source file for the generator.
5) We wanted to preserve the accumulated experience with debugging in terms of what
names, variables, etc., one encounters/manipulates during a debugging session.

The method of changing the build (as indicated in the posts to this thread) satisfied all our
criteria and solved our repeatability problems, with the added benefit that the independent
builds of our random generator (i.e., baz) allowed us to independently instanciate the
semantics of each thread's random stream as well.

Happy Hacking.
Vose
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Compiling and linking 64bit code fskmh Slackware 0 01-15-2005 07:04 AM
Compiling C code with libraries OldGuru Programming 4 09-18-2004 07:06 PM
Help compiling code for install jagrom Linux - Newbie 9 09-04-2004 08:15 AM
Compiling Kernel Code vbhatia_81 Programming 1 06-21-2004 06:53 AM
compiling code ripmaster Linux - Software 2 03-06-2004 09:07 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:10 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration