Skip to content

Commit 84fe612

Browse files
committed
Build from source if the ta-lib is not installed
1 parent 81be22e commit 84fe612

File tree

7 files changed

+102
-41
lines changed

7 files changed

+102
-41
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ env:
1515
TA_INCLUDE_PATH=$DEPS_DIR/include
1616
LD_LIBRARY_PATH=$DEPS_DIR/lib
1717
TA_LIBRARY_PATH=$DEPS_DIR/lib
18+
- WITH_TA_LIBRARY=no
1819
cache:
1920
directories:
2021
- $DEPS_DIR

MANIFEST.in

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
include README.md
2+
include AUTHORS
3+
include CHANGELOG
4+
include COPYRIGHT
5+
include DEVELOPMENT
6+
include LICENSE
7+
include requirements.txt
8+
recursive-include vendor *
9+
recursive-include talib *.py *.pyx *.pxi *.pxd *.c
10+
prune vendor/ta-lib/temp
11+
prune vendor/ta-lib/make
12+
prune vendor/ta-lib/ide
13+
prune vendor/ta-lib/src/tools

setup.py

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python
22

3+
import glob
34
import sys
45
import os
56
import warnings
@@ -21,19 +22,22 @@
2122
from distutils.extension import Extension
2223

2324
lib_talib_name = 'ta_lib' # the underlying C library's name
25+
sources = []
2426

2527
platform_supported = False
2628
for prefix in ['darwin', 'linux', 'bsd', 'sunos']:
2729
if prefix in sys.platform:
2830
platform_supported = True
2931
include_dirs = [
30-
'/usr/include',
31-
'/usr/local/include',
32-
'/opt/include',
33-
'/opt/local/include',
32+
'/usr/include/ta-lib',
33+
'/usr/local/include/ta-lib',
34+
'/opt/include/ta-lib',
35+
'/opt/local/include/ta-lib',
3436
]
3537
if 'TA_INCLUDE_PATH' in os.environ:
36-
include_dirs.append(os.environ['TA_INCLUDE_PATH'])
38+
include_dirs.append(
39+
os.path.join(os.environ['TA_INCLUDE_PATH'], "ta-lib")
40+
)
3741
lib_talib_dirs = [
3842
'/usr/lib',
3943
'/usr/local/lib',
@@ -49,7 +53,7 @@
4953
if sys.platform == "win32":
5054
platform_supported = True
5155
lib_talib_name = 'ta_libc_cdr'
52-
include_dirs = [r"c:\ta-lib\c\include"]
56+
include_dirs = [r"c:\ta-lib\c\include\ta-lib"]
5357
lib_talib_dirs = [r"c:\ta-lib\c\lib"]
5458

5559
if not platform_supported:
@@ -66,6 +70,7 @@
6670
except ImportError:
6771
has_cython = False
6872

73+
libraries = [lib_talib_name]
6974
for lib_talib_dir in lib_talib_dirs:
7075
try:
7176
files = os.listdir(lib_talib_dir)
@@ -74,7 +79,51 @@
7479
except OSError:
7580
pass
7681
else:
77-
warnings.warn('Cannot find ta-lib library, installation may fail.')
82+
libraries = []
83+
warnings.warn(
84+
'Cannot find ta-lib library, will try to build from source.'
85+
)
86+
# find vendor/ta-lib -name "*.h" -exec dirname {} \; | sort | uniq
87+
vendor_dir = os.path.join(
88+
os.path.dirname(os.path.abspath(__file__)),
89+
"vendor",
90+
)
91+
vendor_talib_dir = os.path.join(
92+
vendor_dir,
93+
"ta-lib",
94+
)
95+
talib_include_dirs = [
96+
("include", ),
97+
("src", "ta_abstract"),
98+
("src", "ta_abstract", "frames"),
99+
("src", "ta_common"),
100+
("src", "ta_func"),
101+
]
102+
include_dirs.extend((
103+
os.path.join(vendor_talib_dir, *path_args)
104+
for path_args in talib_include_dirs
105+
))
106+
107+
talib_source_dirs = [
108+
("ta_abstract", ),
109+
("ta_abstract", "frames"),
110+
("ta_abstract", "tables"),
111+
("ta_common", ),
112+
("ta_func", )
113+
]
114+
for path_args in talib_source_dirs:
115+
source_dir = os.path.join(vendor_talib_dir, "src", *path_args)
116+
sources.extend(glob.glob(os.path.join(source_dir, "*.c")))
117+
excel_glue_c_file = os.path.join(
118+
vendor_talib_dir, "src", "ta_abstract", "excel_glue.c"
119+
)
120+
try:
121+
sources.remove(excel_glue_c_file)
122+
except ValueError:
123+
pass
124+
libraries = []
125+
lib_talib_dirs = []
126+
78127

79128
cmdclass = {}
80129
if has_cython:
@@ -83,22 +132,22 @@
83132
ext_modules = [
84133
Extension(
85134
'talib._ta_lib',
86-
['talib/_ta_lib.pyx' if has_cython else 'talib/_ta_lib.c'],
135+
['talib/_ta_lib.pyx' if has_cython else 'talib/_ta_lib.c'] + sources,
87136
include_dirs=include_dirs,
88137
library_dirs=lib_talib_dirs,
89-
libraries=[lib_talib_name]
138+
libraries=libraries
90139
)
91140
]
92141

93142
setup(
94-
name = 'TA-Lib',
95-
version = '0.4.10',
96-
description = 'Python wrapper for TA-Lib',
97-
author = 'John Benediktsson',
98-
author_email = 'mrjbq7@gmail.com',
99-
url = 'http://github.com/mrjbq7/ta-lib',
100-
download_url = 'https://github.com/mrjbq7/ta-lib/releases',
101-
classifiers = [
143+
name='TA-Lib',
144+
version='0.4.10',
145+
description='Python wrapper for TA-Lib',
146+
author='John Benediktsson',
147+
author_email='mrjbq7@gmail.com',
148+
url='http://github.com/mrjbq7/ta-lib',
149+
download_url='https://github.com/mrjbq7/ta-lib/releases',
150+
classifiers=[
102151
"License :: OSI Approved :: BSD License",
103152
"Development Status :: 4 - Beta",
104153
"Operating System :: Unix",
@@ -117,8 +166,8 @@
117166
"Intended Audience :: Science/Research",
118167
"Intended Audience :: Financial and Insurance Industry",
119168
],
120-
packages = ['talib'],
121-
ext_modules = ext_modules,
122-
cmdclass = cmdclass,
123-
requires = ['numpy'],
169+
packages=['talib'],
170+
ext_modules=ext_modules,
171+
cmdclass=cmdclass,
172+
requires=['numpy'],
124173
)

talib/_ta_lib.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,14 +429,10 @@ static CYTHON_INLINE float __PYX_NAN() {
429429

430430
#define __PYX_HAVE__talib___ta_lib
431431
#define __PYX_HAVE_API__talib___ta_lib
432-
#if defined(WIN32) || defined(MS_WINDOWS)
433-
#include "ta-libc.h"
434-
#else
435-
#include "ta-lib/ta_defs.h"
436-
#include "ta-lib/ta_common.h"
437-
#include "ta-lib/ta_abstract.h"
438-
#include "ta-lib/ta_func.h"
439-
#endif
432+
#include "ta_defs.h"
433+
#include "ta_common.h"
434+
#include "ta_abstract.h"
435+
#include "ta_func.h"
440436
#include <string.h>
441437
#include <stdio.h>
442438
#include <stdlib.h>

talib/_ta_lib.pxd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cdef extern from "ta-lib/ta_defs.h":
2+
cdef extern from "ta_defs.h":
33
ctypedef int TA_RetCode
44

55
ctypedef int TA_RetCode
@@ -84,7 +84,7 @@ cdef extern from "ta-lib/ta_defs.h":
8484
TA_CandleSettingType TA_Equal = 10
8585
TA_CandleSettingType TA_AllCandleSettings = 11
8686

87-
cdef extern from "ta-lib/ta_common.h":
87+
cdef extern from "ta_common.h":
8888
char *TA_GetVersionString()
8989
char *TA_GetVersionMajor()
9090
char *TA_GetVersionMinor()
@@ -109,7 +109,7 @@ cdef extern from "ta-lib/ta_common.h":
109109
TA_RetCode TA_Initialize()
110110
TA_RetCode TA_Shutdown()
111111

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

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

193193
char* TA_FunctionDescriptionXML()
194194

195-
cdef extern from "ta-lib/ta_func.h":
195+
cdef extern from "ta_func.h":
196196
TA_RetCode TA_ACOS(int startIdx, int endIdx, const double inReal[], int *outBegIdx, int *outNBElement, double outReal[])
197197
int TA_ACOS_Lookback()
198198
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[])

tools/generate_func.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@
1111
# FIXME: don't return number of elements since it always equals allocation?
1212

1313
functions = []
14-
include_paths = ['/usr/include', '/usr/local/include', '/opt/include', '/opt/local/include']
14+
include_paths = ['/usr/include/ta-lib', '/usr/local/include/ta-lib', '/opt/include/ta-lib', '/opt/local/include/ta-lib']
1515
if sys.platform == 'win32':
16-
include_paths = [r'c:\ta-lib\c\include']
16+
include_paths = [r'c:\ta-lib\c\include\ta-lib']
17+
include_paths.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "vendor", "ta-lib", "include"))
1718
header_found = False
1819
for path in include_paths:
19-
ta_func_header = os.path.join(path, 'ta-lib', 'ta_func.h')
20+
ta_func_header = os.path.join(path, 'ta_func.h')
2021
if os.path.exists(ta_func_header):
2122
header_found = True
2223
break
2324
if not header_found:
24-
print('Error: ta-lib/ta_func.h not found', file=sys.stderr)
25+
print('Error: ta_func.h not found', file=sys.stderr)
2526
sys.exit(1)
2627
with open(ta_func_header) as f:
2728
tmp = []

tools/generate_stream.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@
1111
# FIXME: don't return number of elements since it always equals allocation?
1212

1313
functions = []
14-
include_paths = ['/usr/include', '/usr/local/include', '/opt/include', '/opt/local/include']
14+
include_paths = ['/usr/include/ta-lib', '/usr/local/include/ta-lib', '/opt/include/ta-lib', '/opt/local/include/ta-lib']
1515
if sys.platform == 'win32':
16-
include_paths = [r'c:\ta-lib\c\include']
16+
include_paths = [r'c:\ta-lib\c\include\ta-lib']
17+
include_paths.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "vendor", "ta-lib", "include"))
1718
header_found = False
1819
for path in include_paths:
19-
ta_func_header = os.path.join(path, 'ta-lib', 'ta_func.h')
20+
ta_func_header = os.path.join(path, 'ta_func.h')
2021
if os.path.exists(ta_func_header):
2122
header_found = True
2223
break
2324
if not header_found:
24-
print('Error: ta-lib/ta_func.h not found', file=sys.stderr)
25+
print('Error: ta_func.h not found', file=sys.stderr)
2526
sys.exit(1)
2627
with open(ta_func_header) as f:
2728
tmp = []

0 commit comments

Comments
 (0)