I'm quite new at Linux but I have been developing for Win32 for many years. I wrote an application in C++/Win32 a couple of years ago and I have now been asked to port it to an embedded Linux computer (please see hardware and software details at the end of this post).
Since Linux is new to me, I first tried compiling on my development workstation a simple "Hello World" program written in C. The program runs fine on the target computer.
I then tried compiling a C++ version of the Hello World program (with only a single class) using g++, but this program does not work on the target. It complains about certain libraries that were missing.
To find out the dependencies of the program, I ran on the workstation: # ldd hello libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x4001e000) libm.so.6 => /lib/libm.so.6 (0x400d0000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f2000) libc.so.6 => /lib/libc.so.6 (0x400fb000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
And here is the list of libraries already present on the target computer: # ls /lib ld-linux.so.2 libext2fs.so.2 libstdc++-libc6.2-2.so.3 libc.so.6 libcom_err.so.2 libm.so.6 libutil.so.1 libcrypt.so.1 libnsl.so.1 libuuid.so.1 libdl.so.2 libnss_files.so.2 libe2p.so.2 libresolv.so.2
I copied the libraries libgcc_s.so.1 and libstdc++.so.5 from the development workstation to the target computer. I did not copy libc.so.6, libm.so.6 or ld-linux.so.2 because then already exist on the target.
Now when I run hello on the target it gives the error: ./hello: /lib/libc.so.6: version `GLIBC_2.3' not found (required by /lib/libstdc++.so.5)
I tried copying the libc.so.6 library from the workstation to the target, but this crashed the target so bad and I had to reGhost the drive. I now know better than to overwrite those libraries.
Can anyone help me understand how to select and install the correct libraries in order to run a C++ application on the target?
HARDWARE/SOFTWARE DETAILS
------------------------- Development workstation: Intel PC with Mandrake Linux 9.1 Compiling with g++ 3.2.2
Target computer: ICOP 6015 Embedded 386SX Tiny board with 2S/4MB DRAM onboard/GPIO/Ethernet
formatting link
I comes with an OS called X-Linux preinstalled. They told me that it is a trimmed down version of RedHat Linux.
Since your workstation is running a more recent glibc, you can't simply install correct libraries on the target (libc, libm and ld-linux all form a "package", and must be upgraded together; you saw what happens when they are not).
Your choices are (in order of increasing difficulty, I think):
- upgrade target to the same version of glibc as that on workstation.
- install a gcc x86 => x86 cross-compiler (details in "info gcc").
- downgrade workstation to the same version of glibc as that on the target (you'll have to find a distribution that used the "old" glibc; simply downgrading glibc by itself will likely render the workstation unusable).
Cheers,
--
In order to understand recursion you must first understand recursion.
Or link the program statically (e.g. with the compiler switch "-all-static") and run "strip programname" afterwards. Of course, this is not a good idea if you have more programs as each will become several 100 kbytes larger.
--
Alexander Popov ProSyst Bulgaria Inc.
RTOS Leader 48 Vladajska Str.
RTOS and JVM Dept. Sofia 1606, Bulgaria
Phone: +359 2 952 3581/203 http://www.prosyst.com
Mobile: +359 887 663 193 OSGi Technology Leaders
----------------------------------------------------------
The wonderful thing about Linux is that there is always at
least one more undiscovered way to do almost anything.
Lewin A.R.W. Edwards (comp.os.linux.embedded)
----------------------------------------------------------
Eventually I will want to link with shared libraries because I will be developing other applications for the target. Right now I will try to link the program statically, this will allow me to start development right now and give me more time to resolve the shared library issue later.
I tried the compiler switch you suggested, but it errors: # g++ -all-static -o hello.out hello.cpp cc1plus: unrecognized option `-all-static'
So I tried this: # g++ -static -o hello.out hello.cpp /usr/bin/ld: cannot find -lstdc++ collect2: ld returned 1 exit status
I don't know why it does not find libstdc++, I think it's there: # ls /usr/lib/*stdc++* /usr/lib/libstdc++-3-libc6.2-2-2.10.0.so* /usr/lib/libstdc++.so.5@ /usr/lib/libstdc++-libc6.1-1.so.2@ /usr/lib/libstdc++.so.5.0.3* /usr/lib/libstdc++-libc6.2-2.so.3@
Is it because I only have the shared version of the library and not the static version? If so, how do I get the static version?
-all-static seems to work only after the -o flag. I use KDevelop and added # the library search path: myprogram_LDFLAGS = $(all_libraries) -all-static
If I use -all-static on another place (e.g. like in your example) it won't work either.
Yes. you need the *.a or *.o files.
*.a is an archive of *.o files.
maybe here:
formatting link
If you are using a distribution, it might be on the CD as a separate package. Otherwise, I guess, you have to "make" it from the source. But I have never done this myself. 8-)
Greetings Ernst
PS: I think configuration of the development system is more complicated than programming. 8-)
I finally succeeded in compiling the thing statically.
By reading your replies, I understood that I had to find the static versions of the libraries. I had a look on rpmfind.net and searched for stdc++* and saw the library libstdc++5-static-devel-3.2.2-3mdk.i586.rpm for my Mandrake distribution. I then took a second look at the CDs that I had used for the installation and sure enough, it was there, so I installed it and recompiled. When I saw that the error message had changed and said it could not find libm, I knew I was making progress. I installed the static version of glibc, recompiled and voilà. I now have a whopping
665KB "Hello World" program! Not very compact, but it's a first step. I runs fine on the embedded device.
I simply used the following command: $ g++ -static -o hello.out hello.cpp
I'll post back here later when I'll need to link to the shared libraries, but in the mean time I can start working on my code.
It discards debugging symbols (typically). As you can see below, there are debugging sections of the binary, which strip removes. You can also use it to remove specific sections (not commonly used). This is a ~reasonably large C++ application compiled using GCC 3.3.2. strip removes the DWARF2 debugging symbol tables:
[before strip]
-rwxr-xr-x 1 roger roger 6204796 2003-11-17 15:51 someprog
OK, I think I was wrong. according to the man page unused relocation information and debugging symbols are removed. In my case this is 3/4 of the file size.
But why cannot functions be removed (what is unused relocation information)? I could imagine that a segment, where no jump goes to, could be removed.
(I'm not a C++ expert, so I give this example in C): static void f(); main() { void (*p)() =3D &f; (*f)(); } void f(){ printf("Hello, world!\n"); }
No jump to f, but f is not unused. You could make this arbitrarily complex.
As for the "unused relocation information": if you're referring to the "--strip-unneeded" option, the relocation table contains reference to symbols which must be relocated during linking. Those entries in the symbol table which are not referenced in the relocation table can be removed. A quick test on a simple program reveals that gcc2_compiled is one of such symbols.
Josef
--
Josef M=F6llers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett
How does this contradict what I wrote? As you write yourself: it just removes debugging information. All sections which contain CODE are left untouched: =2Einit, .plt, .text, .fini, so no unused functions have been removed.
--
Josef M=F6llers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett
They could even be removed by the code generator itself (an unused static function does not need code to be generated). As for the linker, IMHO this would violate the task of the linker. It would re-arrange code within a linkable object. But then, it could do this, because it knows that there is no reference to the function label.
--
Josef M=F6llers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett
Any sensible linker with some kind of library utility would not include any library routines that are not referenced by the main program or modules needed by the main program.
However, if the execution environment supports dynamic linking (such as xxx.dll or xxx.so files), it would be quite dangerous to remove any globally available symbol (variable or function) from the final image, if the module has been specified on the linker command line, since the linker can not know, if this symbol will ever be referenced by any dynamically loaded function during run time.
Up to now I never considered dynamic linking and so I don't know what goes on there (but I did watch the GCC linker working for statically linked projects in embedded environments). I suppose you need to tell the linker about the dynamic option.
Does dynamic linking include a jump table to access the referenced functions or do the calls go directly in the midst of the code ?
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.