Skip to content

Build: add compatibility with OpenFST 1.8.x and modern macOS (Apple Silicon)#65

Open
migueljette wants to merge 1 commit into
revdotcom:developfrom
migueljette:openfst-1.8.4-compat
Open

Build: add compatibility with OpenFST 1.8.x and modern macOS (Apple Silicon)#65
migueljette wants to merge 1 commit into
revdotcom:developfrom
migueljette:openfst-1.8.4-compat

Conversation

@migueljette

Copy link
Copy Markdown

OpenFST 1.8.x requires C++17 and dropped its own int64/uint32/uint64 typedef aliases in favour of the standard names. This commit updates the build system and source code to support both the new library version and Apple Silicon Macs running Homebrew under /opt/homebrew.

Changes:

  • CMakeLists.txt: bump C++ standard to 17; use CMAKE_SHARED_LIBRARY_SUFFIX so -DDYNAMIC_OPENFST=ON works on macOS (.dylib) as well as Linux (.so); add /opt/homebrew ICU paths for Apple Silicon; embed RPATH so the binary finds libfst at runtime without DYLD_LIBRARY_PATH; guard the Clang-only -Wno-implicit-int-float-conversion suppression on jsoncpp
  • test/CMakeLists.txt: replace hardcoded WORKING_DIRECTORY build/ with CMAKE_BINARY_DIR so tests work from any build directory name
  • src/AdaptedComposition.h: uint32 -> uint32_t; remove std::unary_function base (removed in C++17)
  • src/AdaptedComposition.cpp, src/StandardComposition.cpp: int64 -> int64_t
  • src/fstalign.cpp: uint64 -> uint64_t
  • third-party/strtk: mark pointer_ mutable so output iterator can advance inside a const operator() under C++17
  • README.md: add macOS / OpenFST 1.8.x build instructions

…ilicon)

OpenFST 1.8.x requires C++17 and dropped its own int64/uint32/uint64
typedef aliases in favour of the standard <cstdint> names. This commit
updates the build system and source code to support both the new library
version and Apple Silicon Macs running Homebrew under /opt/homebrew.

Changes:
- CMakeLists.txt: bump C++ standard to 17; use CMAKE_SHARED_LIBRARY_SUFFIX
  so -DDYNAMIC_OPENFST=ON works on macOS (.dylib) as well as Linux (.so);
  add /opt/homebrew ICU paths for Apple Silicon; embed RPATH so the binary
  finds libfst at runtime without DYLD_LIBRARY_PATH; guard the Clang-only
  -Wno-implicit-int-float-conversion suppression on jsoncpp
- test/CMakeLists.txt: replace hardcoded WORKING_DIRECTORY build/ with
  CMAKE_BINARY_DIR so tests work from any build directory name
- src/AdaptedComposition.h: uint32 -> uint32_t; remove std::unary_function
  base (removed in C++17)
- src/AdaptedComposition.cpp, src/StandardComposition.cpp: int64 -> int64_t
- src/fstalign.cpp: uint64 -> uint64_t
- third-party/strtk: mark pointer_ mutable so output iterator can advance
  inside a const operator() under C++17
- README.md: add macOS / OpenFST 1.8.x build instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@migueljette migueljette force-pushed the openfst-1.8.4-compat branch from 726bf8c to b1cc9a9 Compare July 3, 2026 21:35
@migueljette

Copy link
Copy Markdown
Author

@jprobichaud would it help if I paste the diff in here? Somehow I can't make my fork public ...

Summary

The codebase currently only builds against OpenFST 1.7.x. These changes add support for OpenFST 1.8.x and fix several build issues on modern Macs (Apple Silicon, Homebrew under /opt/homebrew, Clang 21+). All existing tests pass.

OpenFST 1.8.x made two breaking changes relevant here:

  • Dropped its own int64/uint32/uint64 typedef aliases — use int64_t etc. from <cstdint> instead
  • Requires C++17 (was C++14)

Changes

CMakeLists.txt

  • Bump C++ standard from 14 → 17 (required by OpenFST 1.8.x on all platforms)
  • Use ${CMAKE_SHARED_LIBRARY_SUFFIX} instead of hardcoded .so so -DDYNAMIC_OPENFST=ON works on macOS (.dylib) as well as Linux (.so)
  • Add /opt/homebrew ICU search paths for Apple Silicon Macs
  • Embed RPATH when using DYNAMIC_OPENFST so the binary finds libfst at runtime without needing DYLD_LIBRARY_PATH
  • Guard -Wno-implicit-int-float-conversion (jsoncpp) to Clang only — GCC doesn't have this warning

test/CMakeLists.txt

  • Replace hardcoded WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build with ${CMAKE_BINARY_DIR} so tests work from any build directory name

src/AdaptedComposition.h

  • uint32uint32_t
  • Remove std::unary_function base class (removed in C++17)

src/AdaptedComposition.cpp

  • int64int64_t

src/fstalign.cpp

  • uint64uint64_t
    ### third-party/strtk
  • Mark pointer_ as mutable in range_to_ptr_type_iterator so the output iterator can advance inside a const operator() under C++17. Note: since we don't own this submodule, you may prefer to apply this one-line patch directly or vendor strtk.hpp into the tree instead of updating the submodule pointer.

README.md

  • Add macOS / OpenFST 1.8.x build instructions

macOS build instructions (added to README)

curl -L -O https://www.openfst.org/twiki/pub/FST/FstDownload/openfst-1.8.4.tar.gz
tar xzf openfst-1.8.4.tar.gz && cd openfst-1.8.4
./configure --prefix="$HOME/opt/openfst-1.8.4" --disable-dependency-tracking
make -j$(sysctl -n hw.logicalcpu) install

mkdir build && cd build
cmake .. -DOPENFST_ROOT="$HOME/opt/openfst-1.8.4" -DDYNAMIC_OPENFST=ON
make -j$(sysctl -n hw.logicalcpu) && make test

Diff

Full diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 14438ba..f3cdc3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

 enable_testing()

-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)

 if(DEFINED ENV{OPENFST_ROOT})
@@ -41,7 +41,7 @@ set(OPENFST_INCLUDES

 if(DYNAMIC_OPENFST)
   set(OPENFST_LIBRARIES
-    ${OPENFST_ROOT}/lib/libfst.so
+    ${OPENFST_ROOT}/lib/libfst${CMAKE_SHARED_LIBRARY_SUFFIX}
   )
 else()
   set(OPENFST_LIBRARIES
@@ -69,7 +69,7 @@ add_library(fstaligner-common
   third-party/inih/cpp/INIReader.cpp
 )

-list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/icu4c") # for Mac users
+list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/icu4c" "/opt/homebrew/opt/icu4c@78" "/opt/homebrew/opt/icu4c") # for Mac users
 find_package(ICU REQUIRED COMPONENTS uc)

 target_link_libraries(fstaligner-common
@@ -80,8 +80,16 @@ target_link_libraries(fstaligner-common
 )

 add_subdirectory(third-party/jsoncpp)
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  target_compile_options(jsoncpp_lib_static PRIVATE -Wno-implicit-int-float-conversion)
+endif()
 add_subdirectory(third-party/catch2)

+if(DYNAMIC_OPENFST)
+  set(CMAKE_BUILD_RPATH "${OPENFST_ROOT}/lib")
+  set(CMAKE_INSTALL_RPATH "${OPENFST_ROOT}/lib")
+endif()
+
 add_executable(fstalign src/main.cpp)

 include_directories(fstalign
diff --git a/src/AdaptedComposition.cpp b/src/AdaptedComposition.cpp
index 0d715a7..5cadf94 100644
--- a/src/AdaptedComposition.cpp
+++ b/src/AdaptedComposition.cpp
@@ -475,7 +475,7 @@ void AdaptedCompositionFst::SetSymbols(const fst::SymbolTable *symbols) {
   logger_->debug("{}:{} we created 2 vector<bool> of {} items", __FILE__, __LINE__, symbols->NumSymbols());

   for (SymbolTableIterator siter(*symbols); !siter.Done(); siter.Next()) {
-    int64 sid = siter.Value();
+    int64_t sid = siter.Value();
     auto sym_tk = symbols->Find(sid);

     if (isSynonymLabel(sym_tk)) {
diff --git a/src/AdaptedComposition.h b/src/AdaptedComposition.h
index 7cc808a..c1297a1 100644
--- a/src/AdaptedComposition.h
+++ b/src/AdaptedComposition.h
@@ -19,8 +19,8 @@ using namespace std;

 typedef fst::Fst<fst::StdArc>::StateId StateId;

-typedef pair<uint32, uint32> StatePair;
-struct key_hash : public std::unary_function<StatePair, std::size_t> {
+typedef pair<uint32_t, uint32_t> StatePair;
+struct key_hash {
   std::size_t operator()(const StatePair &k) const { return std::get<0>(k) ^ std::get<1>(k); }
 };

diff --git a/src/fstalign.cpp b/src/fstalign.cpp
index 6c57fd1..b35d78b 100644
--- a/src/fstalign.cpp
+++ b/src/fstalign.cpp
@@ -35,7 +35,7 @@ class ReverseOLabelCompare {
     return std::forward_as_tuple(lhs.olabel, lhs.ilabel) > std::forward_as_tuple(rhs.olabel, rhs.ilabel);
   }

-  constexpr uint64 Properties(uint64 props) const {
+  constexpr uint64_t Properties(uint64_t props) const {
     return (props & kArcSortProperties) | kOLabelSorted | (props & kAcceptor ? kILabelSorted : 0);
   }
 };
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index fe7964a..b20f244 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -21,18 +21,18 @@ target_link_libraries(fstalign_Test Threads::Threads)

 add_test(NAME fstalign_Test
   COMMAND $<TARGET_FILE:fstalign_Test>
-  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build)
+  WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

 add_executable(compose-tests compose-tests.cc)
 target_link_libraries(compose-tests Threads::Threads)

 add_test(NAME compose-tests
   COMMAND $<TARGET_FILE:compose-tests>
-  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build)
+  WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

 add_executable(fast-d-tests fast-d-tests.cc)
 target_link_libraries(fast-d-tests Threads::Threads)

 add_test(NAME fast-d-tests
   COMMAND $<TARGET_FILE:fast-d-tests>
-  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build)
+  WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
diff --git a/third-party/strtk b/third-party/strtk
index b887974..3718839 160000
--- a/third-party/strtk
+++ b/third-party/strtk
@@ -1 +1 @@
-Subproject commit b88797408e614ff5a127df12cc520bf41769ada6
+Subproject commit 3718839494679e223e796ff4f9be695394a87402

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant