From e0299fa3da2257548e01cb872a625a7f25d3ec0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Gallou=C3=ABt?= Date: Mon, 18 May 2026 15:50:11 +0000 Subject: [PATCH] app : introduce the llama unified executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adrien Gallouët --- CMakeLists.txt | 22 ++++++++------ app/CMakeLists.txt | 11 +++++++ app/llama.cpp | 48 +++++++++++++++++++++++++++++++ tools/cli/CMakeLists.txt | 20 +++++++++---- tools/cli/cli.cpp | 5 +++- tools/cli/main.cpp | 5 ++++ tools/completion/CMakeLists.txt | 16 +++++++++-- tools/completion/completion.cpp | 5 +++- tools/completion/main.cpp | 5 ++++ tools/llama-bench/CMakeLists.txt | 16 +++++++++-- tools/llama-bench/llama-bench.cpp | 5 +++- tools/llama-bench/main.cpp | 5 ++++ tools/server/CMakeLists.txt | 22 ++++++++------ tools/server/main.cpp | 5 ++++ tools/server/server.cpp | 5 +++- 15 files changed, 165 insertions(+), 30 deletions(-) create mode 100644 app/CMakeLists.txt create mode 100644 app/llama.cpp create mode 100644 tools/cli/main.cpp create mode 100644 tools/completion/main.cpp create mode 100644 tools/llama-bench/main.cpp create mode 100644 tools/server/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d6d6bb0e70..7ed6432b2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,12 +104,13 @@ option(LLAMA_SANITIZE_UNDEFINED "llama: enable undefined sanitizer" OFF) option(LLAMA_BUILD_COMMON "llama: build common utils library" ${LLAMA_STANDALONE}) # extra artifacts -option(LLAMA_BUILD_TESTS "llama: build tests" ${LLAMA_STANDALONE}) -option(LLAMA_BUILD_TOOLS "llama: build tools" ${LLAMA_STANDALONE}) -option(LLAMA_BUILD_EXAMPLES "llama: build examples" ${LLAMA_STANDALONE}) -option(LLAMA_BUILD_SERVER "llama: build server example" ${LLAMA_STANDALONE}) -option(LLAMA_BUILD_UI "llama: build the embedded Web UI for server" ON) -option(LLAMA_USE_PREBUILT_UI "llama: use prebuilt UI from HF Bucket when available (requires LLAMA_BUILD_UI=ON)" ON) +option(LLAMA_BUILD_TESTS "llama: build tests" ${LLAMA_STANDALONE}) +option(LLAMA_BUILD_TOOLS "llama: build tools" ${LLAMA_STANDALONE}) +option(LLAMA_BUILD_EXAMPLES "llama: build examples" ${LLAMA_STANDALONE}) +option(LLAMA_BUILD_SERVER "llama: build server example" ${LLAMA_STANDALONE}) +option(LLAMA_BUILD_APP "llama: build the unified binary" OFF) +option(LLAMA_BUILD_UI "llama: build the embedded Web UI for server" ON) +option(LLAMA_USE_PREBUILT_UI "llama: use prebuilt UI from HF Bucket when available (requires LLAMA_BUILD_UI=ON)" ON) # Backward compat: when old var is set but new one isn't, forward the value if(DEFINED LLAMA_BUILD_WEBUI) @@ -120,8 +121,9 @@ if(DEFINED LLAMA_USE_PREBUILT_WEBUI) set(LLAMA_USE_PREBUILT_UI ${LLAMA_USE_PREBUILT_WEBUI}) message(DEPRECATION "LLAMA_USE_PREBUILT_WEBUI is deprecated, use LLAMA_USE_PREBUILT_UI instead") endif() -option(LLAMA_TOOLS_INSTALL "llama: install tools" ${LLAMA_TOOLS_INSTALL_DEFAULT}) -option(LLAMA_TESTS_INSTALL "llama: install tests" ON) + +option(LLAMA_TOOLS_INSTALL "llama: install tools" ${LLAMA_TOOLS_INSTALL_DEFAULT}) +option(LLAMA_TESTS_INSTALL "llama: install tests" ON) # 3rd party libs option(LLAMA_OPENSSL "llama: use openssl to support HTTPS" ON) @@ -226,6 +228,10 @@ if (LLAMA_BUILD_COMMON AND LLAMA_BUILD_TOOLS) add_subdirectory(tools) endif() +if (LLAMA_BUILD_APP) + add_subdirectory(app) +endif() + # Automatically add all files from the 'licenses' directory file(GLOB EXTRA_LICENSES "${CMAKE_SOURCE_DIR}/licenses/LICENSE-*") diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000000..1b46c79481 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,11 @@ +set(TARGET llama-app) + +add_executable(${TARGET} llama.cpp) +set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME llama) + +target_link_libraries(${TARGET} PRIVATE server-lib cli-lib completion-lib bench-lib) +target_compile_features(${TARGET} PRIVATE cxx_std_17) + +if(LLAMA_TOOLS_INSTALL) + install(TARGETS ${TARGET} RUNTIME) +endif() diff --git a/app/llama.cpp b/app/llama.cpp new file mode 100644 index 0000000000..a70063433f --- /dev/null +++ b/app/llama.cpp @@ -0,0 +1,48 @@ +#include +#include + +int llama_server(int argc, char ** argv); +int llama_completion(int argc, char ** argv); +int llama_cli(int argc, char ** argv); +int llama_bench(int argc, char ** argv); + +struct command { + std::string name; + std::string desc; + int (*func)(int, char **); +}; + +static struct command cmds[] = { + {"server", "HTTP API server", llama_server }, + {"cli", "Command-line interactive interface", llama_cli }, + {"completion", "Text completion", llama_completion}, + {"bench", "Benchmarking tool", llama_bench }, +}; + +static void print_usage(const char * prog) { + printf("Usage: %s [options]\n\n", prog); + printf("Available commands:\n"); + + for (const auto & cmd : cmds) { + printf(" %-15s %s\n", cmd.name.data(), cmd.desc.data()); + } + printf("\nRun '%s --help' for command-specific usage.\n", prog); +} + +int main(int argc, char ** argv) { + if (argc < 2) { + print_usage(argv[0]); + return 1; + } + + const std::string arg = argv[1]; + + for (const auto & cmd : cmds) { + if (arg == cmd.name) { + return cmd.func(argc - 1, argv + 1); + } + } + + fprintf(stderr, "error: unknown command '%s'\n\n", argv[1]); + return 1; +} diff --git a/tools/cli/CMakeLists.txt b/tools/cli/CMakeLists.txt index 7e01abb81b..5e2b37bf9c 100644 --- a/tools/cli/CMakeLists.txt +++ b/tools/cli/CMakeLists.txt @@ -1,9 +1,19 @@ -set(TARGET llama-cli) -add_executable(${TARGET} cli.cpp) -target_link_libraries(${TARGET} PRIVATE server-context PUBLIC llama-common ${CMAKE_THREAD_LIBS_INIT}) -target_compile_features(${TARGET} PRIVATE cxx_std_17) +# cli-lib: CLI logic, reusable by app -include_directories(../server) +set(TARGET cli-lib) + +add_library(${TARGET} STATIC cli.cpp) + +target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ../server) +target_link_libraries(${TARGET} PUBLIC server-context llama-common ${CMAKE_THREAD_LIBS_INIT}) + +# llama-cli executable + +set(TARGET llama-cli) + +add_executable(${TARGET} main.cpp) +target_link_libraries(${TARGET} PRIVATE cli-lib) +target_compile_features(${TARGET} PRIVATE cxx_std_17) if(LLAMA_TOOLS_INSTALL) install(TARGETS ${TARGET} RUNTIME) diff --git a/tools/cli/cli.cpp b/tools/cli/cli.cpp index 369c24216b..af40adbb4c 100644 --- a/tools/cli/cli.cpp +++ b/tools/cli/cli.cpp @@ -342,7 +342,10 @@ static std::vector> auto_completion_callback(std: static constexpr size_t FILE_GLOB_MAX_RESULTS = 100; -int main(int argc, char ** argv) { +// satisfies -Wmissing-declarations +int llama_cli(int argc, char ** argv); + +int llama_cli(int argc, char ** argv) { common_params params; params.verbosity = LOG_LEVEL_ERROR; // by default, less verbose logs diff --git a/tools/cli/main.cpp b/tools/cli/main.cpp new file mode 100644 index 0000000000..cb7d795b66 --- /dev/null +++ b/tools/cli/main.cpp @@ -0,0 +1,5 @@ +int llama_cli(int argc, char ** argv); + +int main(int argc, char ** argv) { + return llama_cli(argc, argv); +} diff --git a/tools/completion/CMakeLists.txt b/tools/completion/CMakeLists.txt index 2c7df80652..27c88220eb 100644 --- a/tools/completion/CMakeLists.txt +++ b/tools/completion/CMakeLists.txt @@ -1,6 +1,18 @@ +# completion-lib: completion logic, reusable by app + +set(TARGET completion-lib) + +add_library(${TARGET} STATIC completion.cpp) + +target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(${TARGET} PUBLIC llama-common llama ${CMAKE_THREAD_LIBS_INIT}) + +# llama-completion executable + set(TARGET llama-completion) -add_executable(${TARGET} completion.cpp) -target_link_libraries(${TARGET} PRIVATE llama-common llama ${CMAKE_THREAD_LIBS_INIT}) + +add_executable(${TARGET} main.cpp) +target_link_libraries(${TARGET} PRIVATE completion-lib) target_compile_features(${TARGET} PRIVATE cxx_std_17) if(LLAMA_TOOLS_INSTALL) diff --git a/tools/completion/completion.cpp b/tools/completion/completion.cpp index 1dc5df1afa..dffcadd413 100644 --- a/tools/completion/completion.cpp +++ b/tools/completion/completion.cpp @@ -84,7 +84,10 @@ static void sigint_handler(int signo) { } #endif -int main(int argc, char ** argv) { +// satisfies -Wmissing-declarations +int llama_completion(int argc, char ** argv); + +int llama_completion(int argc, char ** argv) { std::setlocale(LC_NUMERIC, "C"); common_params params; diff --git a/tools/completion/main.cpp b/tools/completion/main.cpp new file mode 100644 index 0000000000..bea9a0ec9a --- /dev/null +++ b/tools/completion/main.cpp @@ -0,0 +1,5 @@ +int llama_completion(int argc, char ** argv); + +int main(int argc, char ** argv) { + return llama_completion(argc, argv); +} diff --git a/tools/llama-bench/CMakeLists.txt b/tools/llama-bench/CMakeLists.txt index 93d6a3aa2e..0c73b7d045 100644 --- a/tools/llama-bench/CMakeLists.txt +++ b/tools/llama-bench/CMakeLists.txt @@ -1,6 +1,18 @@ +# bench-lib: benchmark logic, reusable by app + +set(TARGET bench-lib) + +add_library(${TARGET} STATIC llama-bench.cpp) + +target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(${TARGET} PUBLIC llama-common llama ${CMAKE_THREAD_LIBS_INIT}) + +# llama-bench executable + set(TARGET llama-bench) -add_executable(${TARGET} llama-bench.cpp) -target_link_libraries(${TARGET} PRIVATE llama-common llama ${CMAKE_THREAD_LIBS_INIT}) + +add_executable(${TARGET} main.cpp) +target_link_libraries(${TARGET} PRIVATE bench-lib) target_compile_features(${TARGET} PRIVATE cxx_std_17) if(LLAMA_TOOLS_INSTALL) diff --git a/tools/llama-bench/llama-bench.cpp b/tools/llama-bench/llama-bench.cpp index 07198fb164..d973209686 100644 --- a/tools/llama-bench/llama-bench.cpp +++ b/tools/llama-bench/llama-bench.cpp @@ -2136,7 +2136,10 @@ static std::unique_ptr create_printer(output_formats format) { GGML_ABORT("fatal error"); } -int main(int argc, char ** argv) { +// satisfies -Wmissing-declarations +int llama_bench(int argc, char ** argv); + +int llama_bench(int argc, char ** argv) { std::setlocale(LC_NUMERIC, "C"); // try to set locale for unicode characters in markdown std::setlocale(LC_CTYPE, ".UTF-8"); diff --git a/tools/llama-bench/main.cpp b/tools/llama-bench/main.cpp new file mode 100644 index 0000000000..0c18bb0c9d --- /dev/null +++ b/tools/llama-bench/main.cpp @@ -0,0 +1,5 @@ +int llama_bench(int argc, char ** argv); + +int main(int argc, char ** argv) { + return llama_bench(argc, argv); +} diff --git a/tools/server/CMakeLists.txt b/tools/server/CMakeLists.txt index 57d3e871d9..574b662685 100644 --- a/tools/server/CMakeLists.txt +++ b/tools/server/CMakeLists.txt @@ -27,12 +27,11 @@ target_include_directories(${TARGET} PRIVATE ../mtmd) target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}) target_link_libraries(${TARGET} PUBLIC llama-common mtmd ${CMAKE_THREAD_LIBS_INIT}) +# server-lib: server logic, reusable by app -# llama-server executable +set(TARGET server-lib) -set(TARGET llama-server) - -set(TARGET_SRCS +add_library(${TARGET} STATIC server.cpp server-http.cpp server-http.h @@ -40,11 +39,16 @@ set(TARGET_SRCS server-models.h ) -add_executable(${TARGET} ${TARGET_SRCS}) +target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${TARGET} PRIVATE ../mtmd ${CMAKE_SOURCE_DIR}) +target_link_libraries(${TARGET} PUBLIC server-context llama-ui cpp-httplib ${CMAKE_THREAD_LIBS_INIT}) + +# llama-server executable + +set(TARGET llama-server) + +add_executable(${TARGET} main.cpp) install(TARGETS ${TARGET} RUNTIME) -target_include_directories(${TARGET} PRIVATE ../mtmd) -target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}) -target_link_libraries(${TARGET} PRIVATE server-context llama-ui PUBLIC llama-common cpp-httplib ${CMAKE_THREAD_LIBS_INIT}) - +target_link_libraries(${TARGET} PRIVATE server-lib) target_compile_features(${TARGET} PRIVATE cxx_std_17) diff --git a/tools/server/main.cpp b/tools/server/main.cpp new file mode 100644 index 0000000000..7f17c56a8c --- /dev/null +++ b/tools/server/main.cpp @@ -0,0 +1,5 @@ +int llama_server(int argc, char ** argv); + +int main(int argc, char ** argv) { + return llama_server(argc, argv); +} diff --git a/tools/server/server.cpp b/tools/server/server.cpp index c82f117943..4d56d45e83 100644 --- a/tools/server/server.cpp +++ b/tools/server/server.cpp @@ -71,7 +71,10 @@ static server_http_context::handler_t ex_wrapper(server_http_context::handler_t }; } -int main(int argc, char ** argv) { +// satisfies -Wmissing-declarations +int llama_server(int argc, char ** argv); + +int llama_server(int argc, char ** argv) { std::setlocale(LC_NUMERIC, "C"); // own arguments required by this example