Bug 16536 – DMD master does not build on OS X 10.11.6/Xcode 7.3.1
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2016-09-24T21:55:00Z
Last change time
2016-11-04T09:05:25Z
Keywords
pull
Assigned to
nobody
Creator
code
Comments
Comment #0 by code — 2016-09-24T21:55:54Z
---
$ cd dmd
$ git show
commit d8be50edd4106ca498ed09a9b3a445240de5cf47
[…]
$ make -f posix.mak
[…]
Undefined symbols for architecture x86_64:
"symboldata(unsigned long long, unsigned int)", referenced from:
el_ptr(Symbol*) in backend.a(el.o)
el_convstring(elem*) in backend.a(el.o)
out_readonly_sym(unsigned int, void*, int) in backend.a(out.o)
Obj::sym_cdata(unsigned int, char*, int) in backend.a(machobj.o)
"_align(unsigned long long, unsigned long long)", referenced from:
codgen() in backend.a(cgcod.o)
stackoffsets(int) in backend.a(cgcod.o)
outjmptab(block*) in backend.a(cod3.o)
outswitab(block*) in backend.a(cod3.o)
type_paramsize(TYPE*) in backend.a(type.o)
alignOffset(int, unsigned long long) in backend.a(out.o)
cdfunc(elem*, unsigned int*) in backend.a(cod1.o)
...
---
This is on linking the DMD executable.
Xcode 7.3.1:
---
$ clang --version
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
---
Host DMD from Homebrew:
---
$ dmd --version
DMD64 D Compiler v2.071.1
---
This seems to be fallout from translating msc.c to D.
Comment #1 by bugzilla — 2016-09-24T22:50:38Z
Note the following from cdef.h:
#if defined(__UINT64_TYPE__)
typedef __INT64_TYPE__ targ_llong;
typedef __UINT64_TYPE__ targ_ullong;
#elif defined(__UINTMAX_TYPE__)
typedef __INTMAX_TYPE__ targ_llong;
typedef __UINTMAX_TYPE__ targ_ullong;
#else
typedef long long targ_llong;
typedef unsigned long long targ_ullong;
#endif
Which of these is the C++ compiler on your machine doing? Is there another macro it should be doing? Getting this right is necessary for the name mangling to match what D generates for 'long' and 'ulong'.
The way to determine the pertinent macro is to have your C++ compiler dump all its predefined macros, once for -m32 and once for -m64. Diff the two, and find the relevant macro.
Same problem with Xcode/Clang 8. I looks like "size_t" is defined as "__SIZE_TYPE__" which is defined as "long unsigned int". Replacing defining "targ_ullong" as "size_t" fixes the problem for 64bit, but not for 32bit.
Comment #4 by doob — 2016-09-26T13:20:07Z
Should it be using d_size_t instead of targ_ullong?
Comment #5 by john.loughran.colvin — 2016-10-03T23:03:38Z
This is preventing testing 2.072.0-b1 on os x.
Comment #6 by doob — 2016-10-04T06:15:33Z
I manually patch the compiler by replacing targ_size_t with size_t/d_size_t where the linker complains. I could create a PR but I don't know if it's the correct solution.
Comment #7 by code — 2016-10-04T21:20:14Z
Well, from the error message, it seems to me we're using `unsigned long long` on the C side (typedef unsigned long long targ_ullong), but `unsigned long` on the D side (alias targ_ullong = ulong).
(In reply to Jacob Carlborg from comment #6)
> I manually patch the compiler by replacing targ_size_t with size_t/d_size_t
> where the linker complains. I could create a PR but I don't know if it's the
> correct solution.
Well we want to always use unsigned long long on both sides (and for 32 and 64-bit dmds), b/c it must be able to hold any target's size_t (hence the name targ_size_t).
It's a slightly different problem than the fix for Issue 16000 https://github.com/dlang/dmd/pull/5788/files#diff-5910c4bad5eadf90caa32a46ab678aa0R12, where we wanted size_t (4/8 bytes depending on 32/64-bit dmd) on both sides.
Not too sure, but I guess if you `typedef unsigned long targ_ullong` on OSX/64 it should work, but that stuff starts to become really messy.
Comment #8 by code — 2016-10-05T18:13:55Z
*** Issue 16596 has been marked as a duplicate of this issue. ***
Comment #9 by code — 2016-10-07T16:07:11Z
Looks like the difference between Xcode 7.3.x and older versions (tried 5.1.1) is the lack of __UINTMAX_TYPE__.
Strangely David reports __UINTMAX_TYPE__ to be "long unsigned int" (compatible w/ dmd's ulong).
Could someone who can reproduce the problem please run.
touch test.c
clang -dM -E test.c | grep UINTMAX
prints
#define __UINTMAX_TYPE__ long unsigned int
for me.
Comment #10 by code — 2016-10-07T16:10:42Z
(In reply to Martin Nowak from comment #9)
> Looks like the difference between Xcode 7.3.x and older versions (tried
> 5.1.1) is the lack of __UINTMAX_TYPE__.
> Strangely David reports __UINTMAX_TYPE__ to be "long unsigned int"
> (compatible w/ dmd's ulong).
>
> Could someone who can reproduce the problem […]
Just for the sake of completeness, I still get the same in both C and C++ mode
$ clang -dM -E test.c | grep UINTMAX
#define __UINTMAX_C_SUFFIX__ UL
#define __UINTMAX_FMTX__ "lX"
#define __UINTMAX_FMTo__ "lo"
#define __UINTMAX_FMTu__ "lu"
#define __UINTMAX_FMTx__ "lx"
#define __UINTMAX_MAX__ 18446744073709551615UL
#define __UINTMAX_TYPE__ long unsigned int
#define __UINTMAX_WIDTH__ 64
$ clang++ -dM -E test.cpp | grep UINTMAX
#define __UINTMAX_C_SUFFIX__ UL
#define __UINTMAX_FMTX__ "lX"
#define __UINTMAX_FMTo__ "lo"
#define __UINTMAX_FMTu__ "lu"
#define __UINTMAX_FMTx__ "lx"
#define __UINTMAX_MAX__ 18446744073709551615UL
#define __UINTMAX_TYPE__ long unsigned int
#define __UINTMAX_WIDTH__ 64
Comment #11 by schveiguy — 2016-10-07T16:12:55Z
(In reply to David Nadlinger from comment #10)
> Just for the sake of completeness, I still get the same in both C and C++
> mode
>
I get the same.
Comment #12 by doob — 2016-10-07T17:36:01Z
I have the same error with Clang 7.0.2 as well. I also have the same output.
Comment #13 by code — 2016-10-07T20:21:42Z
Let's please answer the question of comment 1, which typedef is active.
Looks like you have a __UINT64_TYPE__ long long unsigned int now.
Comment #14 by code — 2016-10-07T20:39:33Z
(In reply to Martin Nowak from comment #13)
> Let's please answer the question of comment 1, which typedef is active.
> Looks like you have a __UINT64_TYPE__ long long unsigned int now.
Indeed the __UINT64_TYPE__ isn't present on my version of XCode/clang.
It seems the better fix would be to rely on <stdint.h> and always use uint64_t.
That would be unsigned long long, so we'd need to change D's ulong to match that.
I'll go with a workaround for newer XCode versions for now, but this needs to be sorted out clearly.
And now:
Undefined symbols for architecture x86_64:
"choose_multiplier(int, unsigned long, int, unsigned long*, int*)", referenced from:
cdmul(elem*, unsigned int*) in backend.a(cod2.o)
"udiv_coefficients(int, unsigned long, int*, unsigned long*, int*)", referenced from:
cdmul(elem*, unsigned int*) in backend.a(cod2.o)
ld: symbol(s) not found for architecture x86_64
Looks like the prototype in cod2.c does not match the type (one is targ_ullong, one is ullong). I tried the obvious fix of changing the prototype in cod2.c, but it complains of not knowing what ullong is there.
I'll let the more experienced take this :)
Comment #18 by github-bugzilla — 2016-10-09T10:54:32Z