New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Build on illumos / Solaris #33
Conversation
Hi guys, I've added svaarala/duktape#453 to ensure this fix (or its equivalent) makes it into the next Duktape release. The generation of |
Fix Build on illumos / Solaris
v1.3.0.4 includes this fix and has been tagged and released. |
@svaarala yes i would like to see that. Not that |
Hmm, Could you paste the error what happens when you don't define |
This results in an #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \
defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \
defined(__BIG_ENDIAN__) The first comparison, So the only way this statement works is if both __BIG_ENDIAN and _BIG_ENDIAN are defined, otherwise one of the == comparisons will fail. The clean way of fixing this, in my opinion, would be to figure out whether __BYTE_ORDER, _BYTE_ORDER, __BIG_ENDIAN, and _BIG_ENDIAN are defined first. Then based on those results make "==" comparisons. I.E. if only one set is defined, then only test that set, if both are defined then test both. If that sounds right to you, i can make another patch implementing that logic. |
Ok, now I know what's going on :) That undefined value thing is only an issue on some older compilers AFAIK; others seem to handle it using short circuiting so that they don't barf like that. For example, it's not an issue on GCC. This is actually one cleanup item for |
@svaarala FWIW, i am using GCC 4.8.5, which isn't that old. |
That's interesting. I was thinking maybe the order of comparison matters, but it seems not. Using Test 1, compiles and works correctly:
Test 2, with order of comparison changed, still compiles and works correctly:
I wonder what happens when you compile these? |
@svaarala Both of those tests succeed for me as well.
So i did a little more investigating, and it turns out that _BIG_ENDIAN is defined, but it's defined with no value. So i did this.... #include <stdio.h>
#define FOO 123
#define BAR
int main(int argc, char *argv[]) {
#if defined(FOO) && defined(BAR) && (FOO == BAR)
printf("FOO == BAR\n");
#else
printf("FOO != BAR\n");
#endif
return 0;
} and i got this back...
EDIT: _BIG_ENDIAN is not defined in endian.h, so i am not sure where it's being defined with no value. I also checked endian.h's includes. |
Ok, thanks. Now we at least know what the actual preprocessor trigger is :) |
@svaarala What about pulling this information from GCC?
GCC should always know what the byte order is, but maybe other compilers don't provide this information by default? This could also be useful for anyone cross compiling for architectures with different endians. EDIT: Note, im using SPARC here. This is the result from an x86 box.
Duktape probably has more uses than Rails, but in this case i can't see anyone not using GCC. illumos is GCC only, and Oracle recommends using GCC for any software not built specifically for Sun Studio (Oracle's compiler). I imagine other Unix vendors have the same view, as most Linux software falls flat on their face without GCC or Clang, and sometimes even with Clang. |
I can add these to the byte order detection code. |
Oh, actually those are already used (later in duk_config.h):
Maybe they could be checked first though. I guess it doesn't really matter if the preprocessor equality comparisons are #ifdef guarded. |
@svaarala Maybe it would make more sense to have it check for GCC / Clang first, then if that fails check endian.h? As most of us use GCC / Clang that should solve any issues with this on any os. |
I agree, although assuming that the #include is in place and the preprocessor comparisons are #ifdef guarded, that shouldn't make a difference. But I'll change it to work like that in any case. Edit: it would also be possible to move the endianness include into the byte order detection part. But since you can't "trial include" a header, the platform detection ladder would need to be replicated there to be sure which header is safe to include. This wouldn't be very nice, so that's why I was assuming above that the endianness header is in place already. |
Come to think of it, the #ifdef guards don't solve the problem. Even with the following there will be a comparison error because a comparison argument is empty:
So I'll change the gcc/clang check to be first; the less safe check is then avoided because the whole block will be skipped. With the more modular |
On illumos and Solaris, endian.h does not define _BIG_ENDIAN, but rather only defines __BIG_ENDIAN. Also, endian.h is located in /usr/include/ast/endian.h compared to /usr/include/endian.h as expected by the generic unix macro.
Sorry for the previous bad pull request, I applied an improper patch. This request contains the proper changes.