cmake_minimum_required(VERSION 3.16) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(APPLE) option(BUILD_UNIVERSAL "Build a Universal binary on macOS" OFF) if(BUILD_UNIVERSAL) # Build a Universal binary on macOS # This requires that the found Qt library is compiled as Universal binaries. set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) else() # Build for the host architecture on macOS set(CMAKE_OSX_ARCHITECTURES "${CMAKE_HOST_SYSTEM_PROCESSOR}" CACHE STRING "" FORCE) endif() endif() set(APP_VERSION_MAJOR 3) set(APP_VERSION_MINOR 2) set(APP_VERSION_PATCH 2) set(APP_VERSION_BASE "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_PATCH}") set(APP_VERSION "${APP_VERSION_BASE}-web_search_beta_3") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") # Include the binary directory for the generated header file include_directories("${CMAKE_CURRENT_BINARY_DIR}") project(gpt4all VERSION ${APP_VERSION_BASE} LANGUAGES CXX C) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) option(GPT4ALL_LOCALHOST "Build installer for localhost repo" OFF) option(GPT4ALL_OFFLINE_INSTALLER "Build an offline installer" OFF) option(GPT4ALL_SIGN_INSTALL "Sign installed binaries and installers (requires signing identities)" OFF) # Generate a header file with the version number configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" ) if(LINUX) find_package(Qt6 6.4 COMPONENTS Core Quick WaylandCompositor QuickDialogs2 Svg HttpServer Sql Pdf LinguistTools REQUIRED) else() find_package(Qt6 6.4 COMPONENTS Core Quick QuickDialogs2 Svg HttpServer Sql Pdf LinguistTools REQUIRED) endif() # Get the Qt6Core target properties get_target_property(Qt6Core_INCLUDE_DIRS Qt6::Core INTERFACE_INCLUDE_DIRECTORIES) get_target_property(Qt6Core_LIBRARY_RELEASE Qt6::Core LOCATION_RELEASE) # Find the qmake binary find_program(QMAKE_EXECUTABLE NAMES qmake qmake6 PATHS ${Qt6Core_INCLUDE_DIRS}/../.. NO_DEFAULT_PATH) # Get the Qt 6 root directory get_filename_component(Qt6_ROOT_DIR "${Qt6Core_LIBRARY_RELEASE}" DIRECTORY) get_filename_component(Qt6_ROOT_DIR "${Qt6_ROOT_DIR}/.." ABSOLUTE) message(STATUS "qmake binary: ${QMAKE_EXECUTABLE}") message(STATUS "Qt 6 root directory: ${Qt6_ROOT_DIR}") set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_subdirectory(../gpt4all-backend llmodel) set(CHAT_EXE_RESOURCES) # Metal shader library if (APPLE) list(APPEND CHAT_EXE_RESOURCES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/default.metallib") endif() # App icon if (WIN32) list(APPEND CHAT_EXE_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/resources/gpt4all.rc") elseif (APPLE) # The MACOSX_BUNDLE_ICON_FILE variable is added to the Info.plist # generated by CMake. This variable contains the .icns file name, # without the path. set(MACOSX_BUNDLE_ICON_FILE gpt4all.icns) # And the following tells CMake where to find and install the file itself. set(APP_ICON_RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/resources/gpt4all.icns") set_source_files_properties(${APP_ICON_RESOURCE} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") list(APPEND CHAT_EXE_RESOURCES "${APP_ICON_RESOURCE}") endif() # Embedding model set(LOCAL_EMBEDDING_MODEL "nomic-embed-text-v1.5.f16.gguf") set(LOCAL_EMBEDDING_MODEL_MD5 "a5401e7f7e46ed9fcaed5b60a281d547") set(LOCAL_EMBEDDING_MODEL_PATH "${CMAKE_BINARY_DIR}/resources/${LOCAL_EMBEDDING_MODEL}") set(LOCAL_EMBEDDING_MODEL_URL "https://gpt4all.io/models/gguf/${LOCAL_EMBEDDING_MODEL}") message(STATUS "Downloading embedding model from ${LOCAL_EMBEDDING_MODEL_URL} ...") file(DOWNLOAD "${LOCAL_EMBEDDING_MODEL_URL}" "${LOCAL_EMBEDDING_MODEL_PATH}" EXPECTED_HASH "MD5=${LOCAL_EMBEDDING_MODEL_MD5}" ) message(STATUS "Embedding model downloaded to ${LOCAL_EMBEDDING_MODEL_PATH}") if (APPLE) list(APPEND CHAT_EXE_RESOURCES "${LOCAL_EMBEDDING_MODEL_PATH}") endif() qt_add_executable(chat main.cpp bravesearch.h bravesearch.cpp chat.h chat.cpp chatllm.h chatllm.cpp chatmodel.h chatlistmodel.h chatlistmodel.cpp chatapi.h chatapi.cpp chatviewtextprocessor.h chatviewtextprocessor.cpp database.h database.cpp download.h download.cpp embllm.cpp embllm.h localdocs.h localdocs.cpp localdocsmodel.h localdocsmodel.cpp localdocssearch.h localdocssearch.cpp llm.h llm.cpp modellist.h modellist.cpp mysettings.h mysettings.cpp network.h network.cpp sourceexcerpt.h sourceexcerpt.cpp server.h server.cpp logger.h logger.cpp tool.h tool.cpp ${APP_ICON_RESOURCE} ${CHAT_EXE_RESOURCES} ) qt_add_qml_module(chat URI gpt4all VERSION 1.0 NO_CACHEGEN QML_FILES main.qml qml/AddCollectionView.qml qml/AddModelView.qml qml/ApplicationSettings.qml qml/ChatDrawer.qml qml/ChatView.qml qml/CollectionsDrawer.qml qml/HomeView.qml qml/LocalDocsSettings.qml qml/LocalDocsView.qml qml/ModelSettings.qml qml/ModelsView.qml qml/NetworkDialog.qml qml/NewVersionDialog.qml qml/PopupDialog.qml qml/SettingsView.qml qml/StartupDialog.qml qml/SwitchModelDialog.qml qml/Theme.qml qml/ThumbsDownDialog.qml qml/Toast.qml qml/ToastManager.qml qml/ToolSettings.qml qml/MyBusyIndicator.qml qml/MyButton.qml qml/MyCheckBox.qml qml/MyComboBox.qml qml/MyDialog.qml qml/MyDirectoryField.qml qml/MyFancyLink.qml qml/MyMenu.qml qml/MyMenuItem.qml qml/MyMiniButton.qml qml/MySettingsButton.qml qml/MySettingsDestructiveButton.qml qml/MySettingsLabel.qml qml/MySettingsStack.qml qml/MySettingsTab.qml qml/MySlug.qml qml/MyTextArea.qml qml/MyTextButton.qml qml/MyTextField.qml qml/MyToolButton.qml qml/MyWelcomeButton.qml RESOURCES icons/antenna_1.svg icons/antenna_2.svg icons/antenna_3.svg icons/caret_down.svg icons/caret_right.svg icons/changelog.svg icons/chat.svg icons/check.svg icons/close.svg icons/copy.svg icons/db.svg icons/discord.svg icons/download.svg icons/edit.svg icons/eject.svg icons/email.svg icons/file-md.svg icons/file-pdf.svg icons/file-txt.svg icons/file.svg icons/github.svg icons/globe.svg icons/gpt4all-32.png icons/gpt4all-48.png icons/gpt4all.svg icons/gpt4all_transparent.svg icons/home.svg icons/image.svg icons/info.svg icons/left_panel_closed.svg icons/left_panel_open.svg icons/local-docs.svg icons/models.svg icons/network.svg icons/nomic_logo.svg icons/notes.svg icons/plus.svg icons/recycle.svg icons/regenerate.svg icons/search.svg icons/send_message.svg icons/settings.svg icons/stack.svg icons/stop_generating.svg icons/thumbs_down.svg icons/thumbs_up.svg icons/trash.svg icons/twitter.svg icons/up_down.svg icons/you.svg ) qt_add_translations(chat TS_FILES ${CMAKE_SOURCE_DIR}/translations/gpt4all_en_US.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_es_MX.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_zh_CN.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_zh_TW.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_ro_RO.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_it_IT.ts ${CMAKE_SOURCE_DIR}/translations/gpt4all_pt_BR.ts ) set_target_properties(chat PROPERTIES WIN32_EXECUTABLE TRUE ) macro(REPORT_MISSING_SIGNING_CONTEXT) message(FATAL_ERROR [=[ Signing requested but no identity configured. Please set the correct env variable or provide the MAC_SIGNING_IDENTITY argument on the command line ]=]) endmacro() if (APPLE) set_target_properties(chat PROPERTIES MACOSX_BUNDLE TRUE MACOSX_BUNDLE_GUI_IDENTIFIER gpt4all MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} RESOURCE "${CHAT_EXE_RESOURCES}" OUTPUT_NAME gpt4all ) add_dependencies(chat ggml-metal) if(NOT MAC_SIGNING_IDENTITY) if(NOT DEFINED ENV{MAC_SIGNING_CERT_NAME} AND GPT4ALL_SIGN_INSTALL) REPORT_MISSING_SIGNING_CONTEXT() endif() set(MAC_SIGNING_IDENTITY $ENV{MAC_SIGNING_CERT_NAME}) endif() if(NOT MAC_SIGNING_TID) if(NOT DEFINED ENV{MAC_NOTARIZATION_TID} AND GPT4ALL_SIGN_INSTALL) REPORT_MISSING_SIGNING_CONTEXT() endif() set(MAC_SIGNING_TID $ENV{MAC_NOTARIZATION_TID}) endif() # Setup MacOS signing for individual binaries set_target_properties(chat PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Manual" XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${MAC_SIGNING_TID} XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${MAC_SIGNING_IDENTITY} XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED True XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--timestamp=http://timestamp.apple.com/ts01 --options=runtime,library" ) endif() target_compile_definitions(chat PRIVATE $<$,$>:QT_QML_DEBUG>) # usearch uses the identifier 'slots' which conflicts with Qt's 'slots' keyword target_compile_definitions(chat PRIVATE QT_NO_SIGNALS_SLOTS_KEYWORDS) target_include_directories(chat PRIVATE usearch/include usearch/fp16/include) if(LINUX) target_link_libraries(chat PRIVATE Qt6::Quick Qt6::Svg Qt6::HttpServer Qt6::Sql Qt6::Pdf Qt6::WaylandCompositor) else() target_link_libraries(chat PRIVATE Qt6::Quick Qt6::Svg Qt6::HttpServer Qt6::Sql Qt6::Pdf) endif() target_link_libraries(chat PRIVATE llmodel) # -- install -- set(COMPONENT_NAME_MAIN ${PROJECT_NAME}) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "..." FORCE) endif() install(TARGETS chat DESTINATION bin COMPONENT ${COMPONENT_NAME_MAIN}) install( TARGETS llmodel LIBRARY DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} # .so/.dylib RUNTIME DESTINATION bin COMPONENT ${COMPONENT_NAME_MAIN} # .dll ) # We should probably iterate through the list of the cmake for backend, but these need to be installed # to the this component's dir for the finicky qt installer to work if (LLMODEL_KOMPUTE) set(MODEL_IMPL_TARGETS llamamodel-mainline-kompute llamamodel-mainline-kompute-avxonly ) else() set(MODEL_IMPL_TARGETS llamamodel-mainline-cpu llamamodel-mainline-cpu-avxonly ) endif() if (APPLE) list(APPEND MODEL_IMPL_TARGETS llamamodel-mainline-metal) endif() install( TARGETS ${MODEL_IMPL_TARGETS} LIBRARY DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} # .so/.dylib RUNTIME DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} # .dll ) if(APPLE AND GPT4ALL_SIGN_INSTALL) include(SignMacOSBinaries) install_sign_osx(chat) install_sign_osx(llmodel) foreach(tgt ${MODEL_IMPL_TARGETS}) install_sign_osx(${tgt}) endforeach() endif() if(WIN32 AND GPT4ALL_SIGN_INSTALL) include(SignWindowsBinaries) sign_target_windows(chat) sign_target_windows(llmodel) foreach(tgt ${MODEL_IMPL_TARGETS}) sign_target_windows(${tgt}) endforeach() endif() if (LLMODEL_CUDA) set_property(TARGET llamamodel-mainline-cuda llamamodel-mainline-cuda-avxonly APPEND PROPERTY INSTALL_RPATH "$ORIGIN") install( TARGETS llamamodel-mainline-cuda llamamodel-mainline-cuda-avxonly RUNTIME_DEPENDENCY_SET llama-cuda-deps LIBRARY DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} # .so/.dylib RUNTIME DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} # .dll ) if (WIN32) install( RUNTIME_DEPENDENCY_SET llama-cuda-deps PRE_EXCLUDE_REGEXES "^(nvcuda|api-ms-.*)\\.dll$" POST_INCLUDE_REGEXES "(^|[/\\\\])(lib)?(cuda|cublas)" POST_EXCLUDE_REGEXES . DIRECTORIES "${CUDAToolkit_BIN_DIR}" DESTINATION lib COMPONENT ${COMPONENT_NAME_MAIN} ) endif() endif() if (NOT APPLE) install(FILES "${CMAKE_BINARY_DIR}/resources/${LOCAL_EMBEDDING_MODEL}" DESTINATION resources COMPONENT ${COMPONENT_NAME_MAIN}) endif() set(CPACK_GENERATOR "IFW") set(CPACK_VERBATIM_VARIABLES YES) set(CPACK_IFW_VERBOSE ON) if(${CMAKE_SYSTEM_NAME} MATCHES Linux) find_program(LINUXDEPLOYQT linuxdeployqt HINTS "$ENV{HOME}/dev/linuxdeployqt/build/tools/linuxdeployqt" "$ENV{HOME}/project/linuxdeployqt/bin") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/deploy-qt-linux.cmake.in" "${CMAKE_BINARY_DIR}/cmake/deploy-qt-linux.cmake" @ONLY) set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_BINARY_DIR}/cmake/deploy-qt-linux.cmake) set(CPACK_IFW_ROOT "~/Qt/Tools/QtInstallerFramework/4.6") set(CPACK_PACKAGE_FILE_NAME "${COMPONENT_NAME_MAIN}-installer-linux") set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${COMPONENT_NAME_MAIN}") elseif(${CMAKE_SYSTEM_NAME} MATCHES Windows) find_program(WINDEPLOYQT windeployqt HINTS ${_qt_bin_dir}) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/deploy-qt-windows.cmake.in" "${CMAKE_BINARY_DIR}/cmake/deploy-qt-windows.cmake" @ONLY) set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_BINARY_DIR}/cmake/deploy-qt-windows.cmake) set(CPACK_IFW_ROOT "C:/Qt/Tools/QtInstallerFramework/4.6") set(CPACK_IFW_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/gpt4all.ico") set(CPACK_PACKAGE_FILE_NAME "${COMPONENT_NAME_MAIN}-installer-win64") set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@\\${COMPONENT_NAME_MAIN}") elseif(${CMAKE_SYSTEM_NAME} MATCHES Darwin) find_program(MACDEPLOYQT macdeployqt HINTS ${_qt_bin_dir}) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/deploy-qt-mac.cmake.in" "${CMAKE_BINARY_DIR}/cmake/deploy-qt-mac.cmake" @ONLY) set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_BINARY_DIR}/cmake/deploy-qt-mac.cmake) set(CPACK_IFW_ROOT "~/Qt/Tools/QtInstallerFramework/4.6") set(CPACK_IFW_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/gpt4all.icns") set(CPACK_PACKAGE_FILE_NAME "${COMPONENT_NAME_MAIN}-installer-darwin") set(CPACK_IFW_TARGET_DIRECTORY "@ApplicationsDir@/${COMPONENT_NAME_MAIN}") set(CPACK_BUNDLE_NAME ${COMPONENT_NAME_MAIN}) set(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/gpt4all.icns") endif() set(CPACK_PACKAGE_INSTALL_DIRECTORY ${COMPONENT_NAME_MAIN}) set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) SET(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGE_HOMEPAGE_URL "https://gpt4all.io") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/gpt4all-48.png") set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_EXECUTABLES "GPT4All") set(CPACK_CREATE_DESKTOP_LINKS "GPT4All") set(CPACK_IFW_PACKAGE_NAME "GPT4All") set(CPACK_IFW_PACKAGE_TITLE "GPT4All Installer") set(CPACK_IFW_PACKAGE_PUBLISHER "Nomic, Inc.") set(CPACK_IFW_PRODUCT_URL "https://gpt4all.io") set(CPACK_IFW_PACKAGE_WIZARD_STYLE "Aero") set(CPACK_IFW_PACKAGE_LOGO "${CMAKE_CURRENT_SOURCE_DIR}/icons/gpt4all-48.png") set(CPACK_IFW_PACKAGE_WINDOW_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/gpt4all-32.png") set(CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST OFF) include(InstallRequiredSystemLibraries) include(CPack) include(CPackIFW) if(GPT4ALL_OFFLINE_INSTALLER) cpack_add_component(${COMPONENT_NAME_MAIN}) else() cpack_add_component(${COMPONENT_NAME_MAIN} DOWNLOADED) endif() cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} ESSENTIAL FORCED_INSTALLATION) cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} VERSION ${APP_VERSION}) cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} LICENSES "MIT LICENSE" ${CPACK_RESOURCE_FILE_LICENSE}) cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/installerscript.qs") cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} REPLACES "gpt4all-chat") #Was used in very earliest prototypes if (GPT4ALL_LOCALHOST) cpack_ifw_add_repository("GPT4AllRepository" URL "http://localhost/repository") elseif(GPT4ALL_OFFLINE_INSTALLER) add_compile_definitions(GPT4ALL_OFFLINE_INSTALLER) else() if(${CMAKE_SYSTEM_NAME} MATCHES Linux) cpack_ifw_add_repository("GPT4AllRepository" URL "https://gpt4all.io/installer_repos/linux/repository") elseif(${CMAKE_SYSTEM_NAME} MATCHES Windows) #To sign the target on windows have to create a batch script add use it as a custom target and then use CPACK_IFW_EXTRA_TARGETS to set this extra target cpack_ifw_add_repository("GPT4AllRepository" URL "https://gpt4all.io/installer_repos/windows/repository") elseif(${CMAKE_SYSTEM_NAME} MATCHES Darwin) cpack_ifw_add_repository("GPT4AllRepository" URL "https://gpt4all.io/installer_repos/mac/repository") endif() endif()