Skip to content

Commit

Permalink
Build from source if the ta-lib is not installed
Browse files Browse the repository at this point in the history
  • Loading branch information
mckelvin committed Feb 7, 2017
1 parent 81be22e commit 84fe612
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 41 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env:
TA_INCLUDE_PATH=$DEPS_DIR/include
LD_LIBRARY_PATH=$DEPS_DIR/lib
TA_LIBRARY_PATH=$DEPS_DIR/lib
- WITH_TA_LIBRARY=no
cache:
directories:
- $DEPS_DIR
Expand Down
13 changes: 13 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
include README.md
include AUTHORS
include CHANGELOG
include COPYRIGHT
include DEVELOPMENT
include LICENSE
include requirements.txt
recursive-include vendor *
recursive-include talib *.py *.pyx *.pxi *.pxd *.c
prune vendor/ta-lib/temp
prune vendor/ta-lib/make
prune vendor/ta-lib/ide
prune vendor/ta-lib/src/tools
91 changes: 70 additions & 21 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python

import glob
import sys
import os
import warnings
Expand All @@ -21,19 +22,22 @@
from distutils.extension import Extension

lib_talib_name = 'ta_lib' # the underlying C library's name
sources = []

platform_supported = False
for prefix in ['darwin', 'linux', 'bsd', 'sunos']:
if prefix in sys.platform:
platform_supported = True
include_dirs = [
'/usr/include',
'/usr/local/include',
'/opt/include',
'/opt/local/include',
'/usr/include/ta-lib',
'/usr/local/include/ta-lib',
'/opt/include/ta-lib',
'/opt/local/include/ta-lib',
]
if 'TA_INCLUDE_PATH' in os.environ:
include_dirs.append(os.environ['TA_INCLUDE_PATH'])
include_dirs.append(
os.path.join(os.environ['TA_INCLUDE_PATH'], "ta-lib")
)
lib_talib_dirs = [
'/usr/lib',
'/usr/local/lib',
Expand All @@ -49,7 +53,7 @@
if sys.platform == "win32":
platform_supported = True
lib_talib_name = 'ta_libc_cdr'
include_dirs = [r"c:\ta-lib\c\include"]
include_dirs = [r"c:\ta-lib\c\include\ta-lib"]
lib_talib_dirs = [r"c:\ta-lib\c\lib"]

if not platform_supported:
Expand All @@ -66,6 +70,7 @@
except ImportError:
has_cython = False

libraries = [lib_talib_name]
for lib_talib_dir in lib_talib_dirs:
try:
files = os.listdir(lib_talib_dir)
Expand All @@ -74,7 +79,51 @@
except OSError:
pass
else:
warnings.warn('Cannot find ta-lib library, installation may fail.')
libraries = []
warnings.warn(
'Cannot find ta-lib library, will try to build from source.'
)
# find vendor/ta-lib -name "*.h" -exec dirname {} \; | sort | uniq
vendor_dir = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"vendor",
)
vendor_talib_dir = os.path.join(
vendor_dir,
"ta-lib",
)
talib_include_dirs = [
("include", ),
("src", "ta_abstract"),
("src", "ta_abstract", "frames"),
("src", "ta_common"),
("src", "ta_func"),
]
include_dirs.extend((
os.path.join(vendor_talib_dir, *path_args)
for path_args in talib_include_dirs
))

talib_source_dirs = [
("ta_abstract", ),
("ta_abstract", "frames"),
("ta_abstract", "tables"),
("ta_common", ),
("ta_func", )
]
for path_args in talib_source_dirs:
source_dir = os.path.join(vendor_talib_dir, "src", *path_args)
sources.extend(glob.glob(os.path.join(source_dir, "*.c")))
excel_glue_c_file = os.path.join(
vendor_talib_dir, "src", "ta_abstract", "excel_glue.c"
)
try:
sources.remove(excel_glue_c_file)
except ValueError:
pass
libraries = []
lib_talib_dirs = []


cmdclass = {}
if has_cython:
Expand All @@ -83,22 +132,22 @@
ext_modules = [
Extension(
'talib._ta_lib',
['talib/_ta_lib.pyx' if has_cython else 'talib/_ta_lib.c'],
['talib/_ta_lib.pyx' if has_cython else 'talib/_ta_lib.c'] + sources,
include_dirs=include_dirs,
library_dirs=lib_talib_dirs,
libraries=[lib_talib_name]
libraries=libraries
)
]

setup(
name = 'TA-Lib',
version = '0.4.10',
description = 'Python wrapper for TA-Lib',
author = 'John Benediktsson',
author_email = 'mrjbq7@gmail.com',
url = 'http://github.com/mrjbq7/ta-lib',
download_url = 'https://github.com/mrjbq7/ta-lib/releases',
classifiers = [
name='TA-Lib',
version='0.4.10',
description='Python wrapper for TA-Lib',
author='John Benediktsson',
author_email='mrjbq7@gmail.com',
url='http://github.com/mrjbq7/ta-lib',
download_url='https://github.com/mrjbq7/ta-lib/releases',
classifiers=[
"License :: OSI Approved :: BSD License",
"Development Status :: 4 - Beta",
"Operating System :: Unix",
Expand All @@ -117,8 +166,8 @@
"Intended Audience :: Science/Research",
"Intended Audience :: Financial and Insurance Industry",
],
packages = ['talib'],
ext_modules = ext_modules,
cmdclass = cmdclass,
requires = ['numpy'],
packages=['talib'],
ext_modules=ext_modules,
cmdclass=cmdclass,
requires=['numpy'],
)
12 changes: 4 additions & 8 deletions talib/_ta_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,14 +429,10 @@ static CYTHON_INLINE float __PYX_NAN() {

#define __PYX_HAVE__talib___ta_lib
#define __PYX_HAVE_API__talib___ta_lib
#if defined(WIN32) || defined(MS_WINDOWS)
#include "ta-libc.h"
#else
#include "ta-lib/ta_defs.h"
#include "ta-lib/ta_common.h"
#include "ta-lib/ta_abstract.h"
#include "ta-lib/ta_func.h"
#endif
#include "ta_defs.h"
#include "ta_common.h"
#include "ta_abstract.h"
#include "ta_func.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down
8 changes: 4 additions & 4 deletions talib/_ta_lib.pxd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

cdef extern from "ta-lib/ta_defs.h":
cdef extern from "ta_defs.h":
ctypedef int TA_RetCode

ctypedef int TA_RetCode
Expand Down Expand Up @@ -84,7 +84,7 @@ cdef extern from "ta-lib/ta_defs.h":
TA_CandleSettingType TA_Equal = 10
TA_CandleSettingType TA_AllCandleSettings = 11

cdef extern from "ta-lib/ta_common.h":
cdef extern from "ta_common.h":
char *TA_GetVersionString()
char *TA_GetVersionMajor()
char *TA_GetVersionMinor()
Expand All @@ -109,7 +109,7 @@ cdef extern from "ta-lib/ta_common.h":
TA_RetCode TA_Initialize()
TA_RetCode TA_Shutdown()

cdef extern from "ta-lib/ta_abstract.h":
cdef extern from "ta_abstract.h":

TA_RetCode TA_GroupTableAlloc(TA_StringTable **table)
TA_RetCode TA_GroupTableFree(TA_StringTable *table)
Expand Down Expand Up @@ -192,7 +192,7 @@ cdef extern from "ta-lib/ta_abstract.h":

char* TA_FunctionDescriptionXML()

cdef extern from "ta-lib/ta_func.h":
cdef extern from "ta_func.h":
TA_RetCode TA_ACOS(int startIdx, int endIdx, const double inReal[], int *outBegIdx, int *outNBElement, double outReal[])
int TA_ACOS_Lookback()
TA_RetCode TA_AD(int startIdx, int endIdx, const double inHigh[], const double inLow[], const double inClose[], const double inVolume[], int *outBegIdx, int *outNBElement, double outReal[])
Expand Down
9 changes: 5 additions & 4 deletions tools/generate_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@
# FIXME: don't return number of elements since it always equals allocation?

functions = []
include_paths = ['/usr/include', '/usr/local/include', '/opt/include', '/opt/local/include']
include_paths = ['/usr/include/ta-lib', '/usr/local/include/ta-lib', '/opt/include/ta-lib', '/opt/local/include/ta-lib']
if sys.platform == 'win32':
include_paths = [r'c:\ta-lib\c\include']
include_paths = [r'c:\ta-lib\c\include\ta-lib']
include_paths.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "vendor", "ta-lib", "include"))
header_found = False
for path in include_paths:
ta_func_header = os.path.join(path, 'ta-lib', 'ta_func.h')
ta_func_header = os.path.join(path, 'ta_func.h')
if os.path.exists(ta_func_header):
header_found = True
break
if not header_found:
print('Error: ta-lib/ta_func.h not found', file=sys.stderr)
print('Error: ta_func.h not found', file=sys.stderr)
sys.exit(1)
with open(ta_func_header) as f:
tmp = []
Expand Down
9 changes: 5 additions & 4 deletions tools/generate_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@
# FIXME: don't return number of elements since it always equals allocation?

functions = []
include_paths = ['/usr/include', '/usr/local/include', '/opt/include', '/opt/local/include']
include_paths = ['/usr/include/ta-lib', '/usr/local/include/ta-lib', '/opt/include/ta-lib', '/opt/local/include/ta-lib']
if sys.platform == 'win32':
include_paths = [r'c:\ta-lib\c\include']
include_paths = [r'c:\ta-lib\c\include\ta-lib']
include_paths.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "vendor", "ta-lib", "include"))
header_found = False
for path in include_paths:
ta_func_header = os.path.join(path, 'ta-lib', 'ta_func.h')
ta_func_header = os.path.join(path, 'ta_func.h')
if os.path.exists(ta_func_header):
header_found = True
break
if not header_found:
print('Error: ta-lib/ta_func.h not found', file=sys.stderr)
print('Error: ta_func.h not found', file=sys.stderr)
sys.exit(1)
with open(ta_func_header) as f:
tmp = []
Expand Down

0 comments on commit 84fe612

Please sign in to comment.