{"action":"created","issue":{"url":"https://api.github.com/repos/lpereira/lwan/issues/155","repository_url":"https://api.github.com/repos/lpereira/lwan","labels_url":"https://api.github.com/repos/lpereira/lwan/issues/155/labels{/name}","comments_url":"https://api.github.com/repos/lpereira/lwan/issues/155/comments","events_url":"https://api.github.com/repos/lpereira/lwan/issues/155/events","html_url":"https://github.com/lpereira/lwan/issues/155","id":161855446,"number":155,"title":"Linker error when using different C library","user":{"login":"fischermario","id":10214295,"avatar_url":"https://avatars.githubusercontent.com/u/10214295?v=3","gravatar_id":"","url":"https://api.github.com/users/fischermario","html_url":"https://github.com/fischermario","followers_url":"https://api.github.com/users/fischermario/followers","following_url":"https://api.github.com/users/fischermario/following{/other_user}","gists_url":"https://api.github.com/users/fischermario/gists{/gist_id}","starred_url":"https://api.github.com/users/fischermario/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fischermario/subscriptions","organizations_url":"https://api.github.com/users/fischermario/orgs","repos_url":"https://api.github.com/users/fischermario/repos","events_url":"https://api.github.com/users/fischermario/events{/privacy}","received_events_url":"https://api.github.com/users/fischermario/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-06-23T07:15:55Z","updated_at":"2016-06-23T07:57:59Z","closed_at":null,"body":"Embedded platforms usually use different libraries than glibc to lower the memory footprint. For example OpenWRT uses uClibc, LEDE uses musl and there are some more.\r\n\r\nWhen I tried to build Lwan for OpenWRT and LEDE I ran into the following linker error:\r\n\r\n> Linking C executable lwan\r\n(...)\r\n/tmp/cc6UKH83.ltrans1.ltrans.o: In function `coro_entry_point.5491':\r\ncc6UKH83.ltrans1.o:(.text+0xa04): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans15.ltrans.o: In function `lwan_write.part.0.5897':\r\ncc6UKH83.ltrans15.o:(.text+0xa78): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans0.ltrans.o: In function `lwan_process_request':\r\ncc6UKH83.ltrans0.o:(.text+0xe24): undefined reference to `swapcontext'\r\ncc6UKH83.ltrans0.o:(.text+0xe5c): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans2.ltrans.o: In function `coro_yield':\r\ncc6UKH83.ltrans2.o:(.text+0x18): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans2.ltrans.o:cc6UKH83.ltrans2.o:(.text+0xe4): more undefined references to `swapcontext' follow\r\n/tmp/cc6UKH83.ltrans2.ltrans.o: In function `coro_reset':\r\ncc6UKH83.ltrans2.o:(.text+0x10c8): undefined reference to `getcontext'\r\ncc6UKH83.ltrans2.o:(.text+0x1108): undefined reference to `makecontext'\r\n/tmp/cc6UKH83.ltrans7.ltrans.o: In function `serve_files_handle_cb.7749':\r\ncc6UKH83.ltrans7.o:(.text+0x9a8): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans7.ltrans.o: In function `cache_coro_get_and_ref_entry':\r\ncc6UKH83.ltrans7.o:(.text+0xb78): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans8.ltrans.o: In function `apply_until.9226':\r\ncc6UKH83.ltrans8.o:(.text+0x3d0): undefined reference to `swapcontext'\r\ncc6UKH83.ltrans8.o:(.text+0x4c0): undefined reference to `swapcontext'\r\ncc6UKH83.ltrans8.o:(.text+0x604): undefined reference to `swapcontext'\r\n/tmp/cc6UKH83.ltrans8.ltrans.o:cc6UKH83.ltrans8.o:(.text+0xf50): more undefined references to `swapcontext' follow\r\ncollect2: error: ld returned 1 exit status\r\n\r\nI can confirm this at least when linking against uClibc and musl. The problem is that both do not seem to implement the functions defined in ucontext.h (Reference: [musl Wiki](http://wiki.musl-libc.org/wiki/Open_Issues#ucontext.h)).\r\n\r\nThese functions, if I understand correctly, are not (or no more?) part of POSIX ([Reference](http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html)). This problem seems to be affecting others too ([Github bugreport](https://github.com/9fans/plan9port/issues/36)).\r\n\r\nOne way to go could be to implement the necessary functions as part of Lwan for all major platforms (right now the inline definitions in lwan-coro.c only cover x86_64 and i386) without relying on an external library. A good starting point for that (as mentioned in the bugreport in the link above) seems to be this project: [libtask](https://github.com/0intro/libtask)\r\n\r\nAnother way could be to drop ucontext.h and replace it entirely with functionality from pthreads. There is a discussion on Stack Overflow [here](http://stackoverflow.com/questions/4298986/is-there-something-to-replace-the-ucontext-h-functions) about the topic.\r\n\r\nUnfortunately this time I do not have a simple solution. I would rather want to discuss the problem first before writing a patch."},"comment":{"url":"https://api.github.com/repos/lpereira/lwan/issues/comments/227977135","html_url":"https://github.com/lpereira/lwan/issues/155#issuecomment-227977135","issue_url":"https://api.github.com/repos/lpereira/lwan/issues/155","id":227977135,"user":{"login":"lpereira","id":15001,"avatar_url":"https://avatars.githubusercontent.com/u/15001?v=3","gravatar_id":"","url":"https://api.github.com/users/lpereira","html_url":"https://github.com/lpereira","followers_url":"https://api.github.com/users/lpereira/followers","following_url":"https://api.github.com/users/lpereira/following{/other_user}","gists_url":"https://api.github.com/users/lpereira/gists{/gist_id}","starred_url":"https://api.github.com/users/lpereira/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lpereira/subscriptions","organizations_url":"https://api.github.com/users/lpereira/orgs","repos_url":"https://api.github.com/users/lpereira/repos","events_url":"https://api.github.com/users/lpereira/events{/privacy}","received_events_url":"https://api.github.com/users/lpereira/received_events","type":"User","site_admin":false},"created_at":"2016-06-23T07:57:59Z","updated_at":"2016-06-23T07:57:59Z","body":"Yes, I'm aware that `ucontext.h` is deprecated from POSIX; which is weird, because they still depend on that to have a machine context in case of, say, segmentation faults. I remember that it's optional in uClibc (at least for the i386 version, which I've used before to run Lwan on an Intel Galileo board, that's why there's an inline version for that architecture).\r\n\r\nI'm not comfortable with ARM assembly, so I didn't do what I did for the inline assembly versions in Lwan. These were ripped from a Glibc disassembly, and I've removed stuff that wasn't required for the coroutines.\r\n\r\nThe pthreads version won't work, as that works with a number of threads, rather than coroutines, to work. Instead, a better fallback than writing inline assembly for various platforms might be using `_setjmp()` and `_longjmp()`.\r\n\r\nIf performance on these platforms end up being a problem, and coroutine context switch ends up being the bottleneck, we can write the inline assembly version for that."}}
{"actor":{"display_login":"lpereira"}}