Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
# Generated from piper.cpp and piper.h
Language: Cpp
BasedOnStyle: Google

# Basic Indentation
IndentWidth: 4
TabWidth: 4
UseTab: Never
ContinuationIndentWidth: 4

# Braces (Attached as seen in piper.cpp)
BreakBeforeBraces: Attach
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false

# Pointer Alignment (Right aligned as per 'piper_synthesizer *synth')
PointerAlignment: Right
DerivePointerAlignment: false

# Spacing
SpaceAfterCStyleCast: false
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false

# Layout
ColumnLimit: 80
BinPackArguments: false
BinPackParameters: false

# Include Management
SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3

# Ensure access modifiers in structs don't over-indent
AccessModifierOffset: -4
...
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ src/piper/train/vits/monotonic_align/core.c
*.so

lightning_logs/

# Application location
/bin

lib/
download/
cmake-build/

/CMakeUserPresets.json
73 changes: 62 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
cmake_minimum_required(VERSION 3.26)
# Builds Python module for Piper using espeak-ng and cmake.
#
# This is called automatically by scikit-build from setup.py.
cmake_minimum_required(VERSION 3.26)
project(piper LANGUAGES C CXX)

# Get the required variable 'GIT_EXECUTABLE'.
find_package(Git REQUIRED)

option(BUILD_TESTING "Enable project tests" ON)
if(BUILD_TESTING)
enable_testing()
endif()

include(ExternalProject)

if (NOT PIPER_BUILD_LIB_ONLY)
# scikit-build-core will forward Python_* variables
find_package(Python COMPONENTS Development.Module Development.SABIModule REQUIRED)
find_package(Python COMPONENTS Development.Module Development.SABIModule REQUIRED)
# include(CMakePrintHelpers)
# cmake_print_variables(Python_VERSION Python_INCLUDE_DIRS Python_LIBRARIES)
endif ()


# Install location for espeak-ng
set(ESPEAKNG_BUILD_DIR ${CMAKE_BINARY_DIR}/espeak_ng)
set(ESPEAKNG_INSTALL_DIR ${CMAKE_BINARY_DIR}/espeak_ng-install)

if(WIN32)
if(WIN32 AND MSVC)
# Special handling for Windows
set(ESPEAKNG_STATIC_LIB ${ESPEAKNG_INSTALL_DIR}/lib/espeak-ng.lib)
set(UCD_STATIC_LIB ${ESPEAKNG_BUILD_DIR}/src/espeak_ng_external-build/src/ucd-tools/ucd.lib)
Expand All @@ -22,13 +35,25 @@ else()
set(UCD_STATIC_LIB ${ESPEAKNG_BUILD_DIR}/src/espeak_ng_external-build/src/ucd-tools/libucd.a)
endif()

# Add the external 'espeak' project and apply the patch to use it as a static library only.
ExternalProject_Add(espeak_ng_external
GIT_REPOSITORY https://github.com/espeak-ng/espeak-ng.git
GIT_TAG 212928b394a96e8fd2096616bfd54e17845c48f6 # 2025-Mar-22
PREFIX ${ESPEAKNG_BUILD_DIR}
CMAKE_ARGS
-DCMAKE_CROSSCOMPILING:BOOL=${CMAKE_CROSSCOMPILING}
# To allow this to work the minimum cmake version is also patched.
# By linking the VCRT static libs it will prevent MSVC linker errors in dependent projects.
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded$<$<CONFIG:Debug>:Debug>
# Forward the current toolchain file.
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMAKE_INSTALL_PREFIX=${ESPEAKNG_INSTALL_DIR}
-DBUILD_SHARED_LIBS:BOOL=OFF
# Do not compile intonation files when Piper used as a module in another project.
-DCOMPILE_INTONATIONS:BOOL=${PROJECT_IS_TOP_LEVEL}
# When not disabling tests when not the top level project, the build fails.
-DENABLE_TESTS:BOOL=${PROJECT_IS_TOP_LEVEL}
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
-DUSE_ASYNC:BOOL=OFF
-DUSE_MBROLA:BOOL=OFF
Expand All @@ -45,12 +70,18 @@ ExternalProject_Add(espeak_ng_external
${ESPEAKNG_STATIC_LIB}
${UCD_STATIC_LIB}
UPDATE_DISCONNECTED TRUE
# Headers are only importing or exporting functions but no consideration when only as a private static library.
# Does not make cmake abort when the patch has already been performed by first checking it.
PATCH_COMMAND "${GIT_EXECUTABLE}" apply --check --reverse "${CMAKE_CURRENT_LIST_DIR}/libpiper/src/espeak.patch" ||
"${GIT_EXECUTABLE}" apply "${CMAKE_CURRENT_LIST_DIR}/libpiper/src/espeak.patch"
)

include_directories(
${ESPEAKNG_INSTALL_DIR}/include
)

if (NOT PIPER_BUILD_LIB_ONLY)

# espeak bridge
add_library(espeakbridge MODULE
src/piper/espeakbridge.c
Expand Down Expand Up @@ -86,12 +117,32 @@ install(TARGETS espeakbridge
RUNTIME DESTINATION .
)

# Copy espeak-ng-data
set(DATA_SRC ${CMAKE_BINARY_DIR}/espeak_ng-install/share/espeak-ng-data)
set(DATA_DST ${CMAKE_CURRENT_SOURCE_DIR}/src/piper/espeak-ng-data)
endif()

add_custom_target(copy_espeak_ng_data ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DATA_SRC} ${DATA_DST}
DEPENDS espeak_ng_external
COMMENT "Copying espeak-ng-data after espeak-ng external project builds"
)
# Projects using this repository as submodule need to deal with 'espeak-ng-data' directory themself.
if (PROJECT_IS_TOP_LEVEL)

# Copy espeak-ng-data
set(DATA_SRC ${CMAKE_BINARY_DIR}/espeak_ng-install/share/espeak-ng-data)
set(DATA_DST ${CMAKE_CURRENT_SOURCE_DIR}/src/piper/espeak-ng-data)

# The native compiled should have done the copy first.
if (NOT CMAKE_CROSSCOMPILING)
add_custom_target(copy_espeak_ng_data ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory "${DATA_SRC}" "${DATA_DST}"
DEPENDS espeak_ng_external
COMMENT "Copying espeak-ng-data after espeak-ng external project builds"
)
else ()
if (NOT EXISTS "${DATA_DST}")
message(FATAL_ERROR "Compile native first to create directory: ${DATA_DST}")
else ()
message(VERBOSE "Found required directory: ${DATA_DST}")
endif ()
endif ()

endif ()

message(STATUS "Compiling from ${CMAKE_HOST_SYSTEM_PROCESSOR} for ${CMAKE_SYSTEM_PROCESSOR}")

add_subdirectory(libpiper)
Loading