Synology DS416j – From Stock to pycurl

I got a Synology DS416j NAS and wanted to use it for some basic network infrastructure tasks on top of data storage. One of these network infrastructure tasks involves updating a DNS record with my service provider, which requires a python script that uses curl, and therefore pycurl. You can install python with the package manager, but it doesn’t come with much. If you pip install pycurl, it’ll complain about curl-config not existing. To fix that, you need to go down a rabbit hole into a messy world of missing dependancies; proceed at your own discretion.

First, you’ll need the community package manager “ipkg” that’ll let you install most of what you need. It’s called a bootstraper, and there’s an easy installer available here.

Dump that on your NAS, go to the package manager, and “manually install” it. You’ll also need to enable SSH.

By default the new “ipkg” binaries and associated bits will not be in your path, so you’ll have to modify your path to include it. I did this with a PATH=$PATH:/usr/opt in a .bashrc.

You can then “ipkg install” several packages as root. You’ll need a bunch:

  • busybox
  • binutils
  • diffutils
  • gawk
  • gcc
  • libc-dev
  • libcurl
  • libcurl-dev
  • make
  • openssl
  • openssl-dev
  • patch
  • sed

This is what I needed for pycurl, anyway.

Next, you need the python headers, which you are not going to be able to get via ipkg. You have to go to python.org and get the appropriate source tarball for the version you have (python –version). Dump that in /tmp, extract it, run ./configure to produce pythonconfig.h. I had to modify pythonconfig.h so that Py_UNICODE_SIZE was 4, not 2, as it seems the binary I have installed was compiled with that. If you don’t change this you’ll get some undefined references to a symbol “PyUnicodeUCS2_Decode”.

Make a directory /opt/lib/python, dump everything in your extracted tarballs Include directory in there, and also put your modified pythonconfig.h in there.

Now you can pip install pycurl, except that won’t work. Run it with “pip install –no-clean pycurl” so you can manually complete it. It’ll leave a directory in “/tmp/pip-build-something/pycurl”, go there.

setup.py/distutils is going to look for gcc in the wrong place. There’s probably a good way to fix that, but it was really quick to just symlink the wrong place to the right one:

ln -s /opt/bin/gcc /usr/local/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-ccache-gcc

It’s also not going to know where to find those python includes we just collected. There’s probably a proper way to do that too, but I just modified setup.py so that:

self.include_dirs = [‘/opt/include/python’]

Under the instantiation definition for the class ExtensionConfiguration.

Now, you can make and make install and you’ll have pycurl.

Matt has been a freelance software developer specializing in gluing incompatible systems together for 10 years. He is also a integration specialist with six years' experience in commercial building automation. Matt develops back-end software that help businesses get the data they need to make better decisions faster.