Skip to content
Merged
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
1 change: 0 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Build-Depends: debhelper-compat (= 13),
libswscale-dev,
libxrt-dev,
ninja-build,
patchelf,
pkg-config,
rustc,
uuid-dev
Expand Down
24 changes: 4 additions & 20 deletions debian/rules
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,10 @@ override_dh_auto_build:
cmake --build build

override_dh_auto_install:
install -d debian/fastflowlm/opt/fastflowlm debian/fastflowlm/usr/bin
DESTDIR=$(CURDIR)/debian/fastflowlm cmake --install build --prefix=/opt/fastflowlm
mv debian/fastflowlm/opt/fastflowlm/bin/flm debian/fastflowlm/opt/fastflowlm/flm
rmdir --ignore-fail-on-non-empty debian/fastflowlm/opt/fastflowlm/bin
ln -sf /opt/fastflowlm/flm debian/fastflowlm/usr/bin/flm

# Install model list
install -m 644 src/model_list.json debian/fastflowlm/opt/fastflowlm/model_list.json

# Install xclbins
cp -r src/xclbins debian/fastflowlm/opt/fastflowlm/

# Remove include and lib directories
rm -rf debian/fastflowlm/opt/fastflowlm/include debian/fastflowlm/opt/fastflowlm/lib
install -d debian/fastflowlm/opt/fastflowlm debian/fastflowlm/usr/bin
ln -sf /opt/fastflowlm/bin/flm debian/fastflowlm/usr/bin/flm

# Install custom libraries and update their RPATH
install -m 644 src/lib/*.so debian/fastflowlm/opt/fastflowlm/
patchelf --set-rpath '/opt/fastflowlm' debian/fastflowlm/opt/fastflowlm/flm
for lib in debian/fastflowlm/opt/fastflowlm/*.so; do \
if [ -f "$$lib" ]; then \
patchelf --set-rpath '/opt/fastflowlm' "$$lib"; \
fi; \
done
# Remove include directories
rm -rf debian/fastflowlm/opt/fastflowlm/include
28 changes: 23 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ endif()

target_compile_definitions(flm PUBLIC
DISABLE_ABI_CHECK=1
CMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
)

if(WIN32)
Expand Down Expand Up @@ -306,12 +307,29 @@ if(WIN32)
COMMENT "Checking for remaining DLL dependencies"
DEPENDS flm
)
else()
file(GLOB so_libs "${CMAKE_SOURCE_DIR}/lib/*.so")
install(FILES ${so_libs} DESTINATION lib)
set_target_properties(flm PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib")
endif()

# ———————————————————————————————————————————————
# Install the flm binary (for proper deployment)
# ———————————————————————————————————————————————
install(TARGETS flm
RUNTIME DESTINATION bin
BUNDLE DESTINATION .
)
)

install(FILES model_list.json DESTINATION share/flm)

# xclbins, which are loaded by shared libraries need to be in location
# relative to the executable, so we install them to bin/xclbins
install(DIRECTORY xclbins DESTINATION bin)

if(NOT WIN32 AND NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr" AND NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr/local")
install(CODE "
message(STATUS \"Creating symlink for flm\")
file(MAKE_DIRECTORY \"$ENV{DESTDIR}/usr/local/bin\")
execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink
\"${CMAKE_INSTALL_PREFIX}/bin/flm\"
\"$ENV{DESTDIR}/usr/local/bin/flm\")"
)
endif()
22 changes: 15 additions & 7 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ OUT_DIR := out
PWSH := powershell.exe


.PHONY: all clean run serve
.PHONY: all clean run serve install

ifeq ($(OS),Windows_NT)

Expand All @@ -29,26 +29,34 @@ clean:
@$(PWSH) "Remove-Item -Recurse -Force '$(BUILD_DIR)'"
@$(PWSH) "Remove-Item -Recurse -Force '$(OUT_DIR)'"

install:
@echo "Installing using CMake..."
@cd $(BUILD_DIR) && cmake --install . --prefix $(PREFIX)

else

all:
@mkdir -p $(BUILD_DIR)
@mkdir -p $(OUT_DIR)
@cd $(BUILD_DIR) && ${PWSH} -Command "cmake .."
@cd $(BUILD_DIR) && ${PWSH} -Command "cmake --build . --config Release"
@cd $(BUILD_DIR) && cmake ..
@cd $(BUILD_DIR) && cmake --build . --config Release

run:
@cp lib/*.dll $(OUT_DIR)
@cp lib/*.so $(OUT_DIR)
@cp model_list.json $(OUT_DIR)
@cd $(OUT_DIR) && ${PWSH} -Command "./flm.exe run gpt-oss -a 0"
@cd $(OUT_DIR) && ./flm run gpt-oss -a 0

serve:
@cp lib/*.dll $(OUT_DIR)
@cp lib/*.so $(OUT_DIR)
@cp model_list.json $(OUT_DIR)
@cd $(OUT_DIR) && ${PWSH} -Command "./flm.exe serve -a 1 -e 1"
@cd $(OUT_DIR) && ./flm serve -a 1 -e 1

clean:
@rm -rf $(BUILD_DIR)
@rm -rf $(OUT_DIR)

install:
@echo "Installing using CMake..."
@cd $(BUILD_DIR) && cmake --install . --prefix $(PREFIX)

endif
163 changes: 163 additions & 0 deletions src/common/utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/// \file utils.cpp
/// \brief utils class
/// \author FastFlowLM Team
/// \date 2025-06-24
/// \version 0.9.24
///
/// \note This file contains some utility functions for the FastFlowLM project.
#include "utils/utils.hpp"
#include <filesystem>
#include <cstdlib>

#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
#else
#include <unistd.h>
#include <limits.h>
#endif

namespace utils {

std::string find_model_list() {
std::string install_prefix = CMAKE_INSTALL_PREFIX;

// 1. Check FLM_CONFIG_PATH environment variable
const char* env_path = std::getenv("FLM_CONFIG_PATH");
if (env_path && *env_path) {
if (std::filesystem::exists(env_path)) {
return env_path;
}
}

// 2. Check for install prefix
std::string installed_path = install_prefix + "/share/flm/model_list.json";
if (std::filesystem::exists(installed_path)) {
return installed_path;
}

// 3. Check relative to executable
std::string exe_dir = get_executable_directory();
std::string exe_relative_path = exe_dir + "/model_list.json";
if (std::filesystem::exists(exe_relative_path)) {
return exe_relative_path;
}

// 4. Check current working directory
if (std::filesystem::exists("model_list.json")) {
return "model_list.json";
}

// If not found, throw an error
throw std::runtime_error("model_list.json not found. Please set FLM_CONFIG_PATH or place it next to the executable.");
}

std::string get_executable_directory() {
#ifdef _WIN32
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
std::string exe_path(buffer);
size_t last_slash = exe_path.find_last_of("/");
if (last_slash != std::string::npos) {
return exe_path.substr(0, last_slash);
}
return ".";
#else
char buffer[PATH_MAX] = {0};
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
if (len > 0) {
buffer[len] = '\0';
std::string exe_path(buffer);
size_t last_slash = exe_path.find_last_of("/");
if (last_slash != std::string::npos) {
return exe_path.substr(0, last_slash);
}
}
return ".";
#endif
}

std::string get_user_documents_directory() {
#ifdef _WIN32
char buffer[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, 0, buffer))) {
return std::string(buffer);
}
// Fallback to current directory if Documents folder cannot be found
return ".";
#else
const char* home = std::getenv("HOME");
if (home && *home) {
return std::string(home) + "/.config";
}
return ".";
#endif
}

int get_server_port(int user_port) {
if (user_port > 0 && user_port <= 65535) {
return user_port;
}
else {
#ifdef _WIN32
char* port_env = nullptr;
size_t len = 0;
if (_dupenv_s(&port_env, &len, "FLM_SERVE_PORT") == 0 && port_env != nullptr) {
try {
int port = std::stoi(port_env);
free(port_env);
if (port > 0 && port <= 65535) {
return port;
}
}
catch (const std::exception&) {
free(port_env);
// Invalid port number, use default
}
}
#else
const char* port_env = std::getenv("FLM_SERVE_PORT");
if (port_env && *port_env) {
try {
int port = std::stoi(port_env);
if (port > 0 && port <= 65535) {
return port;
}
}
catch (const std::exception&) {
// Invalid port number, use default
}
}
#endif
}

return 52625; // Default port
}

std::string get_models_directory() {
#ifdef _WIN32
char* model_path_env = nullptr;
size_t len = 0;
if (_dupenv_s(&model_path_env, &len, "FLM_MODEL_PATH") == 0 && model_path_env != nullptr) {
std::string custom_path(model_path_env);
free(model_path_env);
if (!custom_path.empty()) {
return custom_path;
}
}
#else
const char* model_path_env = std::getenv("FLM_MODEL_PATH");
if (model_path_env && *model_path_env) {
return std::string(model_path_env);
}
#endif
// Fallback to Documents/flm/models on Windows or ~/.config/flm on Linux if environment variable is not set
std::string documents_dir = get_user_documents_directory();
#ifdef _WIN32
return documents_dir + "/flm/models";
#else
return documents_dir + "/flm";
#endif
}

} // end of namespace utils
Loading