diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,2 +1,8 @@
+Version 0.0.1.2 2017-06-27 by luispedro
+	* Fix cabal release: include C header files in extra-source-files
+
+Version 0.0.1.1 2017-06-27 by luispedro
+	* Fix cabal release: include C header files
+
 Version 0.0.1 2017-06-27 by luispedro
 	* First release. Basic funcionality
diff --git a/diskhash.cabal b/diskhash.cabal
--- a/diskhash.cabal
+++ b/diskhash.cabal
@@ -1,5 +1,5 @@
 name:               diskhash
-version:            0.0.1.1
+version:            0.0.1.2
 synopsis:           Disk-based hash table
 description:        Disk-based hash table
 category:           Data
@@ -10,14 +10,13 @@
 cabal-version:      >= 1.10
 build-type:         Simple
 bug-reports:        https://github.com/luispedro/diskhash/issues
-extra-source-files: README.md ChangeLog
+extra-source-files: README.md ChangeLog src/diskhash.h src/primes.h
 
 library
   default-language: Haskell2010
   exposed-modules: Data.DiskHash
   hs-source-dirs: haskell/
   C-sources: haskell/Data/diskhash2.c src/diskhash.c
-  includes: src/diskhash.h src/primes.h
   Include-dirs: src/
   ghc-options: -Wall
   build-depends:
@@ -29,8 +28,6 @@
   type: exitcode-stdio-1.0
   main-is: Data/DiskHash/Tests.hs
   other-modules: Data.DiskHash
-  C-sources: haskell/Data/diskhash2.c src/diskhash.c
-  includes: src/diskhash.h src/primes.h
   ghc-options: -Wall
   hs-source-dirs: haskell/
   include-dirs: src/
@@ -38,6 +35,7 @@
     base > 4 && < 5,
     bytestring,
     directory,
+    diskhash,
     HUnit,
     QuickCheck,
     test-framework,
diff --git a/src/diskhash.h b/src/diskhash.h
new file mode 100644
--- /dev/null
+++ b/src/diskhash.h
@@ -0,0 +1,156 @@
+#ifndef DISKHASH_H_INCLUDE_GUARD__
+#define DISKHASH_H_INCLUDE_GUARD__
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * key_maxlen is the maximum key length not including the terminator NUL, i.e.,
+ * diskhash will check that for every key you insert `strlen(key) <
+ * opts.key_maxlen`.
+ *
+ * Internally, space is allocated on 8-Byte aligned boundaries, so numbers such
+ * as 7, 15, 23, 31, ... (i.e., multiples of 8 minus 1 for NUL) are good
+ * choices for key_maxlen.
+ *
+ * object_datalen is the number of Bytes that your data elements occupy.
+ */
+typedef struct HashTableOpts {
+    size_t key_maxlen;
+    size_t object_datalen;
+} HashTableOpts;
+
+typedef struct HashTable {
+    int fd_;
+    const char* fname_;
+    void* data_;
+    size_t datasize_;
+} HashTable;
+
+
+/** Zero-valued options
+ */
+HashTableOpts dht_zero_opts(void);
+
+/** Open a hash table file
+ *
+ * fpath is the file path
+ * flags are passed to call to open() and the user should read the documentation therein
+ *
+ * Values returned from dht_open must be freed with dht_free.
+ *
+ * Examples:
+ *
+ * Read-write:
+ *
+ *      HashTableOpts opts;
+ *      opts.key_maxlen = 15;
+ *      opts.object_datalen = 8;
+ *      char* err;
+ *      HashTable* ht = dht_open("hashtable.dht", opts, O_RDWR|O_CREAT, &err);
+ *
+ * Read-only:
+ *
+ *      char* err;
+ *      HashTable* ht = dht_open("hashtable.dht", opts, O_RDONLY, &err);
+ *
+ * When opening an existing disk table, you can pass `{ 0, 0 }` (the return
+ * value of `dht_zero_opts()`) as the options, in which case the values will be
+ * taken from the table on disk. If you do pass values, they are checked
+ * against the values on disk and it is an error if there is a mismatch.
+ *
+ * The last argument is an error output argument. If it is set to a non-NULL
+ * value, then the memory must be released with free(). Passing NULL is valid
+ * (and no error message will be produced). An error return with *err == NULL
+ * will mean an out-of-memory error (when dht fails to allocate memory, it does
+ * not try to allocate memory for an error message).
+ */
+HashTable* dht_open(const char* fpath, HashTableOpts opts, int flags, char**);
+
+/** Lookup a value by key
+ *
+ * If the hash table was opened in read-write mode, then the memory returned
+ * can be written to (the hash table itself does not inspect the values in any
+ * way). Writing to a read-only hashtable will probably trigger a segmentation
+ * fault.
+ *
+ * If the object is not found, returns NULL.
+ *
+ * Thread safety: multiple concurrent reads are perfectly safe. No guarantees
+ * are given whenever writing is performed. Similarly, if you write to the
+ * output of this function (the ht_data field), no guarantees are given.
+ */
+void* dht_lookup(const HashTable*, const char* key);
+
+/** Insert a value.
+ *
+ * The hashtable must be opened in read write mode.
+ *
+ * If a value with the given key is already present in the table, then no
+ * action is performed and 0 is returned. If you want to overwrite that value,
+ * you can use `dht_lookup` and write to its output.
+ *
+ * This operation is typically O(1) amortized. However, if table is at capacity
+ * when dht_insert is called, then it must be grown which can be a
+ * time-consuming operation as all the values are copied to the newly allocated
+ * memory block (see dht_reserve).
+ *
+ * Errors can occur if table expansion is needed and memory cannot be
+ * allocated.
+ *
+ * Returns 1 if the value was inserted.
+ *         0 if the key was already present in the table. The hash table was
+ *         not modified.
+ *         -EINVAL : key is too long
+ *	   -ENOMEM : dht_reserve failed.
+ *
+ * The last argument is an error output argument. If it is set to a non-NULL
+ * value, then the memory must be released with free(). Passing NULL is valid
+ * (and no error message will be produced). An error return with *err == NULL
+ * will mean an out-of-memory error (when dht fails to allocate memory, it does
+ * not try to allocate memory for an error message).
+ */
+int dht_insert(HashTable*, const char* key, const void* data, char** err);
+
+/** Preallocate memory for the table.
+ *
+ * Calling this function if the number of elements is known apriori can improve
+ * performance. Additionally, if capacity exists, then dht_insert never fails.
+ *
+ * This function returns the actual capacity allocated (which may be more than
+ * requested, but never less). Calling dht_reserve asking for _less_ capacity
+ * than is currently used is a no-op.
+ *
+ * If capacity cannot be allocated, this function returns 0 (but no changes to
+ * the hash table are made).
+ *
+ * This function can be used to query the current capacity by passing the value
+ * 1 as the desired capacity.
+ *
+ * The last argument is an error output argument. If it is set to a non-NULL
+ * value, then the memory must be released with free(). Passing NULL is valid
+ * (and no error message will be produced).
+ */
+size_t dht_reserve(HashTable*, size_t capacity, char** err);
+
+/**
+ * Return the number of elements
+ */
+size_t dht_size(const HashTable*);
+
+/** Free the hashtable and sync to disk.
+ */
+void dht_free(HashTable*);
+
+/** For debug use only */
+void show_ht(const HashTable*);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* DISKHASH_H_INCLUDE_GUARD__*/
diff --git a/src/primes.h b/src/primes.h
new file mode 100644
--- /dev/null
+++ b/src/primes.h
@@ -0,0 +1,66 @@
+#ifndef DISKHASH_PRIMES_H__INCLUDE_GUARD__
+#define DISKHASH_PRIMES_H__INCLUDE_GUARD__
+
+#include <inttypes.h>
+uint64_t primes [] = {
+7, 
+11, 
+19, 
+37, 
+67, 
+113, 
+193, 
+331, 
+563, 
+967, 
+1657, 
+2819, 
+4793, 
+8161, 
+13873, 
+23593, 
+40111, 
+68207, 
+115963, 
+197137, 
+335149, 
+569759, 
+968593, 
+1646609, 
+2799239, 
+4758707, 
+8089817, 
+13752701, 
+23379599, 
+39745319, 
+67567091, 
+114864059, 
+195268963, 
+331957243, 
+564327347, 
+959356547, 
+1630906177, 
+2772540503, 
+4713318893, 
+8012642153, 
+13621491703, 
+23156535937, 
+39366111097, 
+66922388873, 
+113768061101, 
+193405703917, 
+328789696673, 
+558942484349, 
+950202223409, 
+1615343779807, 
+2746084425691, 
+4668343523687, 
+7936183990283, 
+13491512783501, 
+22935571732013, 
+38990471944439, 
+66283802305549, 
+0 /* sentinel */
+};
+
+#endif
