Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using curl on iOS, I am unable to link with multiple architectures, CurlchkszEQ macro failing

Tags:

curl

xcode

ios

I have built numerous versions of curl using the wonderful "build_curl" script i found on GitHub. I have also rebuild curl using other techniques.

But I always end up with the same issue.

I have an iOS project which links against curl. I can build and debug on the simulator (clearly using i386). I can build and debug with a device as long as I choose to only build the current architecture and the device is plugged in when I build.

However, if I choose to try to build Release OR if I choose to build Debug for 'iOS Device' with no device plugged in. I always end up with the following error:

curlrules.h:143:6: '__curl_rule_01__' declared as an array with a negative size

This is caused by this:

#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
typedef char
  __curl_rule_01__
    [CurlchkszEQ(long, CURL_SIZEOF_LONG)];

This #define exists in curlbuild.h

#define CURL_SIZEOF_LONG 4

Which should be correct, because I am building for a 32 bit architecture, however, Xcode has decided that sizeof(long) != 4, and so the Macro generates an error.

I have chosen to only build for armv7 and armv7s, and still I get this error.

I do not understand why this will not build.

like image 471
Howard Shere Avatar asked Feb 10 '14 16:02

Howard Shere


1 Answers

I have chosen to only build for armv7 and armv7s, and still i get this error.

Have you looked at the Xcode build logs to confirm that only -arch armv7 and -arch armv7s are used for compilation?

Your problem is certainly related to the fact that you use a single set of headers (e.g generated for a 32-bit build of the library) even though you try to build a fat executable that combines armv7/v7s and arm64 architectures.

I think you should refer to Nick Zitzmann libcurl pre-built. As you can see the curlbuild.h header that ships with it includes ad-hoc macros to distinguish between ILP32 and LP64:

/* The size of `long', as computed by sizeof. */
#ifdef __LP64__
#define CURL_SIZEOF_LONG 8
#else
#define CURL_SIZEOF_LONG 4
#endif

Note that the instructions on Nick's page do not include any precision about how this header has been generated - I would say it has been modified specifically to be cross-platform compliant.

UPDATE

The above link is down (one can find a snapshot on the Internet Archive - the latest pre-built was made for libcurl 7.40.0 from 2015-01-08). I made a copy (verbatim) of build-libcurl-ios.sh and curlbuild.h (the single, convenient header made for the iOScURL application) here.

After the armv7 build the build-libcurl-ios.sh makes a copy of the generated 32-bit header:

cp include/curl/curlbuild.h ~/Desktop/curlbuild32.h

Same thing after the arm64 build:

cp include/curl/curlbuild.h ~/Desktop/curlbuild64.h

The final curlbuild.h is no more than a convenient version that includes both 32-bit and 64-bit specifics thanks to #ifdef __LP64__ /* ... */ #else /* ... */ #endif sections. In particular there is more than only CURL_SIZEOF_LONG differences, e.g.:

#define CURL_TYPEOF_CURL_OFF_T int64_t /* 64-bit */
#define CURL_TYPEOF_CURL_OFF_T long    /* 32-bit */
like image 145
deltheil Avatar answered Nov 15 '22 17:11

deltheil