Skip to content

Commit

Permalink
(#64) package.py now generate windows 64 bits library in dist
Browse files Browse the repository at this point in the history
  • Loading branch information
mario4tier committed Nov 19, 2024
1 parent d8a890b commit 132b8b7
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 20 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# top-most EditorConfig file
root = true

# Python files
[*.py]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

# Custom settings for Visual Studio
[*.py]
editor.formatOnPaste = false
editor.formatOnSave = true
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ autom4te.cache
ar-lib
**/.history/

# Ignore the generated binaries, but keep the bin soft links.
# TA-Lib specific tools (must be built for each platform)
src/tools/gen_code/gen_code
src/tools/ta_regtest/ta_regtest
bin/*.class
bin/gen_code
bin/ta_regtest
bin/gen_code*
bin/ta_*
lib/ta_*
!bin/HOLDER

## File system
Expand All @@ -55,7 +56,7 @@ venv
.#
TODO
tmp
temp/*.tmp
temp/

## Editors
*.swp
Expand All @@ -73,6 +74,7 @@ Session.vim
# Visual Studio
.vs/
out/
*.vcxproj.user

## MSVC Windows builds (debug info)
*.pdb
Expand Down
24 changes: 16 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
CMAKE_MINIMUM_REQUIRED(VERSION 3.22)

PROJECT(ta-lib)

Expand Down Expand Up @@ -290,19 +290,27 @@ SET(ta-lib_CSOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/ta_abstract/tables/table_m.c"
)


ADD_LIBRARY(ta_lib SHARED ${ta-lib_CSOURCES})
SET_TARGET_PROPERTIES(ta_lib PROPERTIES
SOVERSION ${TA_LIB_VERSION_FULL}
DEFINE_SYMBOL TA_LIB_SHARED
OUTPUT_NAME "ta_lib"
)
ADD_LIBRARY(ta_lib_static STATIC ${ta-lib_CSOURCES})

IF(UNIX)
ADD_LIBRARY(ta_lib SHARED ${ta-lib_CSOURCES})
ADD_LIBRARY(ta_lib_static STATIC ${ta-lib_CSOURCES})
SET_TARGET_PROPERTIES(ta_lib_static PROPERTIES OUTPUT_NAME ta_lib)
ENDIF(UNIX)

IF(WIN32)
INCLUDE(GenerateExportHeader)
ADD_LIBRARY(ta_lib SHARED ${ta-lib_CSOURCES})
ADD_LIBRARY(ta_lib_static STATIC ${ta-lib_CSOURCES})
SET_TARGET_PROPERTIES(ta_lib_static PROPERTIES OUTPUT_NAME ta_lib_a)
# Note: WIN32 is defined regardless of 32 or 64 bits host.
SET_TARGET_PROPERTIES(ta_lib_static PROPERTIES OUTPUT_NAME ta_lib_static)
ENDIF(WIN32)

SET_TARGET_PROPERTIES(ta_lib PROPERTIES SOVERSION ${TA_LIB_VERSION_FULL} DEFINE_SYMBOL TA_LIB_SHARED)
IF(MSVC)
add_compile_options(/deterministic)
ENDIF(MSVC)

TARGET_INCLUDE_DIRECTORIES(ta_lib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
TARGET_INCLUDE_DIRECTORIES(ta_lib_static PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
Binary file added dist/ta-lib-0.6.0-win64.zip
Binary file not shown.
148 changes: 141 additions & 7 deletions scripts/package.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,145 @@
#!/usr/bin/env python3

# Create/update the ta-lib-<version>-src.tar.gz for unix systems.

# This package is for users wanting to rebuild on their machine
# with the typical "./configure; make"

# Produces and tests the assets to be released.
#
# The output depends of the host system.
#
# For linux/ubuntu: ta-lib-<version>-src.tar.gz
# with contents for doing "./configure; make; sudo make install"
#
# For windows: ta-lib-<version>-win64.zip
# with contents:
# lib/ta_lib.dll (dynamic library)
# lib/ta_lib.lib (import library)
# lib/ta_lib_static.lib (static library)
# include/*.h (all necessary headers)
#
# How to run it?
# Do './scripts/package.py' from root of your ta-lib repository.
#
# Windows Specific:
# - You must have Visual Studio installed (free community version works).
# - Host machine must be x64
# - Scripts must be run in a "VS Development Command Shell" (for the convenience
# of CMake and Ninja be on the Path and already be configured).
#
# (FYI, you can optionally do all this in a Windows VM)
#
# How to change the version?
# Edit MAJOR, MINOR, BUILD in src/ta_common/ta_version.c
# You do not need to modify other files (this script will update all needed files).

import filecmp
import os
import subprocess
import sys
import glob
import platform
import shutil
import tempfile
import zipfile
import zlib

from common import verify_git_repo, get_version_string, verify_src_package

def compare_zip_files(zip_file1, zip_file2):
# Does a binary comparison of the contents of the two zip files.
# Ignores file creation time.
with tempfile.TemporaryDirectory() as temp_extract_dir:
temp_extract_path1 = os.path.join(temp_extract_dir, 'temp1')
temp_extract_path2 = os.path.join(temp_extract_dir, 'temp2')
os.makedirs(temp_extract_path1, exist_ok=True)
os.makedirs(temp_extract_path2, exist_ok=True)

with zipfile.ZipFile(zip_file1, 'r') as zip_ref:
zip_ref.extractall(temp_extract_path1)

with zipfile.ZipFile(zip_file2, 'r') as zip_ref:
zip_ref.extractall(temp_extract_path2)

dir_comparison = filecmp.dircmp(temp_extract_path1, temp_extract_path2)
return not dir_comparison.diff_files and not dir_comparison.left_only and not dir_comparison.right_only

def create_zip_file(source_dir, zip_file):
with zipfile.ZipFile(zip_file, 'w', compression=zipfile.ZIP_DEFLATED, compresslevel=zlib.Z_BEST_COMPRESSION) as zipf:
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, start=source_dir)
zipf.write(file_path, arcname)

def package_windows(root_dir: str, version: str):
os.chdir(root_dir)

# Clean-up any previous packaging
dist_dir = os.path.join(root_dir, 'dist')
#glob_all_packages = os.path.join(root_dir, 'dist', 'ta-lib-*-win64.zip')
#for file in glob.glob(glob_all_packages):
# os.remove(file)

glob_all_temp_packages = os.path.join(root_dir, 'temp', 'ta-lib-*-win64.zip')
for file in glob.glob(glob_all_temp_packages ):
os.remove(file)

build_dir = os.path.join(root_dir, 'build')
if os.path.exists(build_dir):
shutil.rmtree(build_dir)

glob_all_temp_packages = os.path.join(root_dir, 'temp', 'ta-lib-*-win64')
for directory in glob.glob(glob_all_temp_packages):
shutil.rmtree(directory)

# Run CMake and build
try:
os.makedirs(build_dir)
os.chdir(build_dir)
subprocess.run(['cmake', '-G', 'Ninja', '..'], check=True)
subprocess.run(['cmake', '--build', '.'], check=True)
except subprocess.CalledProcessError as e:
print(f"Error running CMake or build: {e}")
return

# Create temporary package dirs (including its subdirs)
temp_dir = os.path.join(root_dir, 'temp')
os.makedirs(temp_dir, exist_ok=True)
package_temp_dir = os.path.join(temp_dir, f'ta-lib-{version}-win64')
os.makedirs(package_temp_dir, exist_ok=True)
os.makedirs(os.path.join(package_temp_dir, 'lib'), exist_ok=True)
os.makedirs(os.path.join(package_temp_dir, 'include'), exist_ok=True)

# Copy the built files to the temporary package directory
try:
shutil.copy('ta_lib.dll', os.path.join(package_temp_dir, 'lib'))
shutil.copy('ta_lib.lib', os.path.join(package_temp_dir, 'lib'))
shutil.copy('ta_lib_static.lib', os.path.join(package_temp_dir, 'lib'))
for header in glob.glob(os.path.join(root_dir, 'include', '*.h')):
shutil.copy(header, os.path.join(package_temp_dir, 'include'))
except subprocess.CalledProcessError as e:
print(f"Error copying files: {e}")
return

# Create the zip file
package_temp_file = os.path.join(temp_dir, f'ta-lib-{version}-win64.zip')
try:
# subprocess.run(['powershell', 'Compress-Archive', '-Path', package_temp_dir, '-DestinationPath', package_temp_file], check=True)
create_zip_file(package_temp_dir, package_temp_file)
except subprocess.CalledProcessError as e:
print(f"Error creating zip file: {e}")
return

# TODO Add testing of the package here.

# Copy package_temp_file into dist, but only if its content is binary different.
os.makedirs(dist_dir, exist_ok=True)
package_final = os.path.join(dist_dir, f'ta-lib-{version}-win64.zip')
if not os.path.exists(package_final) or not compare_zip_files(package_temp_file, package_final):
print(f"Copying package to dist\\ta-lib-{version}-win64.zip")
shutil.copy(package_temp_file, package_final)
else:
print(f"Generated ta-lib-{version}-win64.zip identical to one already in dist directory. Skipping copy.")

print(f"Packaging completed successfully.")

def package_linux(root_dir: str, version: str):
os.chdir(root_dir)

Expand Down Expand Up @@ -73,11 +201,17 @@ def package_linux(root_dir: str, version: str):
print(f"Packaging to dist/ta-lib-{version}.tar.gz successful.")

if __name__ == "__main__":
root_dir = verify_git_repo()
version = get_version_string(root_dir)

if sys.platform == "linux":
root_dir = verify_git_repo()
version = get_version_string(root_dir)
package_linux(root_dir,version)
elif sys.platform == "win32":
arch = platform.architecture()[0]
if arch == '64bit':
package_windows(root_dir, version)
else:
print( f"Architecture [{arch}] not yet supported. Only 64 bits supported on windows.")
else:
print("For now, this script is only for Linux systems.")
sys.exit(1)
2 changes: 1 addition & 1 deletion scripts/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Update *local* dev with latest from both dev and main *remote* branch.
#
# Such merging is often needed prior to a 'push origin dev'.
# Such merging is often needed prior to a 'git push'.
#
# The local dev changes (if any) are temporarly stashed and merge back...
# so conflicts may need to be resolved manually (an error will be displayed).
Expand Down

0 comments on commit 132b8b7

Please sign in to comment.