Every now and then, someone encounters the following error.
% cc -G -o foo.so foo.o -lbar ld: fatal: file foo.o: wrong ELF class: ELFCLASS64 ld: fatal: File processing errors. No output written to foo
Or perhaps the similar error.
% cc -G -xarch=amd64 -o foo.so foo.o -lbar ld: fatal: file foo.o: wrong ELF class: ELFCLASS32 ld: fatal: File processing errors. No output written to foo
This issue stems from the compiler flags that have been used to compile the relocatable object foo.o, and the compiler flags that are finally used to invoke the link-edit of this object.
The man page for ld(1) hints at the issue.
No command-line option is required to distinguish 32-bit objects or 64-bit objects. The link-editor uses the ELF class of the first relocatable object file that is found on the command line, to govern the mode in which to operate.
When the compiler drivers are used to generate an executable or shared object, the driver typically supplies a couple of their own files to the link-edit. One or more of these additional files will be read by the link-editor before the file foo.o. Expanding the compiler processing might reveal:
% cc -# -G -o foo.so foo.o ... ld crti.o values-xa.o -o foo.so -G foo.o ... crtn.o
Here, the first input file read by the link-editor is crti.o (this is typically a full path to a compiler specific subdirectory). Expanding a 64-bit link-edit request might reveal:
% cc -# -xarch=64 -G -o foo.so foo.o ... ld amd64/crti.o amd64/values-xa.o -o foo.so -G foo.o ... amd64/crtn.o
Armed with this information it should be easy to see how the ELFCLASS error messages can be produced. If for example, you wish to create a 64-bit shared object from one or more relocatable objects, you might first create the 64-bit relocatable object like:
% cc -c -xarch=amd64 foo.c % file foo.o foo.o: ELF 64-bit LSB relocatable AMD64 Version 1
But, if you fail to inform the compiler driver that this object should be linked into a 64-bit object, you'll produce the ELFCLASS64 error message. The first file read by the link-editor will be the 32-bit version of crti.o. This puts ld() into 32-bit mode, and hence when foo.o is read it will be rejected as being incompatible with the mode of the link-edit requested.
Similarly, a 32-bit relocatable object:
% cc -c foo.c
that is handed to a 64-bit link-edit will produce the ELFCLASS32 error message.
Make sure that the architecture flag used to build a relocatable object is also passed to the compiler driver phase of linking the relocatable object into a final executable or shared object.