Closed andyli closed 4 years ago
Looks like maybe Apple Clang uses different name mangling for symbols, can you check if it defines __USER_LABEL_PREFIX__
and maybe dump the contents of the object file's symbols with nm -g file.o
. Once I know what is happening here I can fix the header to use the right prefix
__USER_LABEL_PREFIX__
is defined as _
.
$ nm -g CMakeFiles/asserts.dir/resources.c.o
U gLoremData
U gLoremEnd
U gLoremSize
U gOnebyteData
U gOnebyteEnd
U gOnebyteSize
U gSevenbytesData
U gSevenbytesEnd
U gSevenbytesSize
$ nm CMakeFiles/asserts.dir/resources.c.o
0000000000000000 s _gLoremData
00000000000003c2 s _gLoremEnd
00000000000003d0 s _gLoremSize
00000000000003e0 s _gOnebyteData
00000000000003e1 s _gOnebyteEnd
00000000000003f0 s _gOnebyteSize
0000000000000400 s _gSevenbytesData
0000000000000407 s _gSevenbytesEnd
0000000000000410 s _gSevenbytesSize
U gLoremData
U gLoremEnd
U gLoremSize
U gOnebyteData
U gOnebyteEnd
U gOnebyteSize
U gSevenbytesData
U gSevenbytesEnd
U gSevenbytesSize
That is strange. It appears the symbols are there, maybe the linker expects one to specify symbol visibility ?
I don't know. But I found that the data.c produced by the incbin program can be used with the INCBIN_EXTERN header file. Maybe it is useful for you to look at the data.c.o object: data.c.zip
FYI:
$ nm CMakeFiles/asserts.dir/data.c.o
0000000000000000 S _gLoremData
00000000000003f0 S _gLoremEnd
00000000000003c4 S _gLoremSize
00000000000003d0 S _gOnebyteData
0000000000000400 S _gOnebyteEnd
00000000000003d4 S _gOnebyteSize
00000000000003e0 S _gSevenbytesData
0000000000000410 S _gSevenbytesEnd
00000000000003e8 S _gSevenbytesSize
nm on both seems the same s
and S
are the same according to my man, this seems weird, the U
ones are really interesting tho. I don't have an Apple to dig deeper into this.
Can reproduce this on Apple clang 11.0.0
I think it does have to do with symbol visibility. man nm
says:
Each symbol name is preceded by its value (blanks if undefined). Unless the -m option is specified, this value is followed by one of the following characters, representing the symbol type: U (undefined), A (absolute), T (text section symbol), D (data section symbol), B (bss section symbol), C (common symbol), - (for debugger symbol table entries; see -a below), S (symbol in a section other than those above), or I (indirect symbol). If the symbol is local (non-external), the symbol's type is instead represented by the corresponding lowercase letter. A lower case u in a dynamic shared library indicates a undefined reference to a private external in another module in the same library.
It looks like the linker is looking for the _
-prefixed symbols, but those are “local” so it's not finding them?
I found a workaround. Everything works for me if I change the definition of INCBIN_GLOBAL to:
# define INCBIN_GLOBAL(NAME) ".globl " INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
I don't know much about assemblers so not sure if it's the right fix.
@rogual: thank you for this workaround, it just helped me to resolve a similar problem when switching from 64 bits compilation to 32 bits compilation with MingW (x86_64-8.1.0-release-win32-seh-rt_v6-rev0 vs i686-8.1.0-release-win32-dwarf-rt_v6-rev0). I've yet to confirm this workaround is still compatible with my 64 bits environment.
I'm beginning to think __APPLE__
case never worked. Can someone confirm if it works in any version of AppleClang without any of these changes. If not we may need to put the INCBIN_MANGLE
on the front here.
Fixed
The build error: https://travis-ci.org/andyli/incbin/builds/367773037
My test code can be seen at https://github.com/andyli/incbin/commit/47c3b76c833c9d40d13d1dbf84274638db9d6911
Notice that the test passed in the Linux builds.