From b6e74c1bd382d15d0073e7ac516cb10aa8b9e3dc Mon Sep 17 00:00:00 2001 From: Diego Saraiva Date: Sun, 6 Apr 2025 12:20:25 -0300 Subject: [PATCH 1/4] modernize-cmake-project --- CMakeLists.txt | 256 ++++++++++++++++++--------------- cmake/AddUninstallTarget.cmake | 101 +++++++++++++ cmake/Config.cmake.in | 10 ++ cmake/PackageProject.cmake | 243 +++++++++++++++++++++++++++++++ cmake/Utils.cmake | 39 +++++ cmake/version.h.in | 8 ++ src/CMakeLists.txt | 94 ------------ standalone/CMakeLists.txt | 44 ------ test/CMakeLists.txt | 67 ++++----- 9 files changed, 565 insertions(+), 297 deletions(-) create mode 100644 cmake/AddUninstallTarget.cmake create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/PackageProject.cmake create mode 100644 cmake/version.h.in delete mode 100644 src/CMakeLists.txt delete mode 100644 standalone/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 0001507..d38b77d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,7 @@ -cmake_minimum_required(VERSION 3.22) - -# ###################################################################################################################### -# Include guards: Prevent building in the source directory -# ###################################################################################################################### -if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) - message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n") -endif() - -# Make sure that custom modules are found -list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - -# ###################################################################################################################### +cmake_minimum_required(VERSION 3.24...3.31) +# ############################################################################## # Define the Project Name and Description -# ###################################################################################################################### +# ############################################################################## project( modern_cpp_project VERSION 1.0.0 @@ -20,12 +9,28 @@ project( DESCRIPTION "ModernCppProject is a project template for Modern C++" ) +# ############################################################################## +# Include guards: Prevent building in the source directory +# ############################################################################## +if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + message(FATAL_ERROR + "In-source builds not allowed. " + "Please make a new directory (called a build directory) and " + "run CMake from there.\n" + ) +endif() +message(STATUS "Started CMake for ${PROJECT_NAME} v${PROJECT_VERSION}...\n") + include(CMakeDependentOption) include(CheckCXXCompilerFlag) include(CheckTypeSize) include(CMakePrintHelpers) -option(${PROJECT_NAME}_USE_ALT_NAMES "Use alternative names for the project, such as naming the include directory all lowercase." ON) +option(${PROJECT_NAME}_USE_ALT_NAMES + "Use alternative names for the project, such as naming the include directory all lowercase." + ON +) + if(${PROJECT_NAME}_USE_ALT_NAMES) string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE) string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE) @@ -34,54 +39,58 @@ else() set(PROJECT_NAME_UPPERCASE ${PROJECT_NAME}) endif() -# ###################################################################################################################### +# ############################################################################## # Setup project -# ###################################################################################################################### +# ############################################################################## include(cmake/StandardSettings.cmake) include(cmake/Utils.cmake) -include(cmake/CompilerWarnings.cmake) +include(cmake/CompilerWarnings.cmake) +############################################################################## +# Global Project Settings +# only activate for top level project +############################################################################## ############################################################################## # Global Project Settings # only activate for top level project ############################################################################## if(PROJECT_IS_TOP_LEVEL) - # Put the libraries and binaries that get built into directories at the top of - # the build tree rather than in hard-to-find leaf directories. This simplifies - # manual testing and the use of the build tre. + # Put the libraries and binaries that get built into directories at the + # top of the build tree rather than in hard-to-find leaf directories. + # This simplifies manual testing and the use of the build tre. set(MAINFOLDER ${PROJECT_SOURCE_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) - # Windows DLLs are "runtime" for CMake. + # Windows DLLs are "runtime" for CMake. # Output them to "bin" like the Visual Studio projects do. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - + # Let's nicely support folders in IDE's set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json") - execute_process( - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json + execute_process(COMMAND ${CMAKE_COMMAND} -E + copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json ) - endif() + endif() include(cmake/StaticAnalyzers.cmake) + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") + endif() endif() -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Debug") -endif() - -message(STATUS "Started CMake for ${PROJECT_NAME} v${PROJECT_VERSION}...\n") - -# ###################################################################################################################### +############################################################################## # Add dependencies -# ###################################################################################################################### +############################################################################## + +# ---- Add dependencies via CPM ---- +# see https://github.com/TheLartians/CPM.cmake for more info include(cmake/CPM.cmake) -CPMAddPackage("gh:TheLartians/Format.cmake@1.8.1") +CPMAddPackage("gh:TheLartians/Format.cmake@1.8.1") # PackageProject.cmake will be used to make our target installable -CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.12.0") +include(cmake/PackageProject.cmake) # Collect the built libraries and include directories # A semicolon separated list of the project's dependencies @@ -99,114 +108,123 @@ CPMAddPackage( NAME spdlog GITHUB_REPOSITORY gabime/spdlog VERSION 1.15.0 - OPTIONS "SPDLOG_INSTALL YES" "SPDLOG_FMT_EXTERNAL YES" # create an installable target and force uses a external fmt + OPTIONS "SPDLOG_INSTALL YES" "SPDLOG_FMT_EXTERNAL YES" ) list(APPEND ${PROJECT_NAME}_DEPENDENCIES "spdlog 1.12.0") -# ###################################################################################################################### -# Source tree -# ###################################################################################################################### -#add_subdirectory(extern) -add_subdirectory(src) +set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL}) -# ###################################################################################################################### -# Add version header: the location where the project's version header will be placed should match the project's -# regular header paths -# ###################################################################################################################### -set(VERSION_HEADER_LOCATION "${PROJECT_NAME_LOWERCASE}/version.hpp") -configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/version.hpp.in include/${VERSION_HEADER_LOCATION} @ONLY) +# ---- Add source files ---- +# Note: globbing sources is considered bad practice as CMake's generators may +# not detect new files automatically. Keep that in mind when changing files, +# or explicitly mention them here. +file( + GLOB_RECURSE headers + CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp" +) +file( + GLOB_RECURSE sources + CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" +) +# IDEs should put the headers in a nice place +source_group( + TREE "${CMAKE_CURRENT_SOURCE_DIR}/include" + PREFIX "Header Files" + FILES ${HEADER_LIST} +) + +############################################################################## +# ---- Create library ---- +############################################################################## +if(${PROJECT_NAME_UPPERCASE}_BUILD_HEADERS_ONLY) + add_library(${PORJECT_NAME_LOWERCASE} INTERFACE) + target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_23) +else() + add_library(${PROJECT_NAME_LOWERCASE} ${headers} ${sources}) + target_compile_features(${PROJECT_NAME_LOWERCASE} PUBLIC cxx_std_23) + verbose_message("Added all header and implementation files.\n") +endif() + +# ############################################################################# +# Add version header: the location where the project's version header will be +# placed should match the project's regular header paths +# ############################################################################# +set(VERSION_HEADER_LOCATION "${PROJECT_NAME_LOWERCASE}/version.hpp") +configure_file( + ${CMAKE_CURRENT_LIST_DIR}/cmake/version.hpp.in + ${VERSION_HEADER_LOCATION} + @ONLY +) string(TOLOWER ${PROJECT_NAME}/version.hpp VERSION_HEADER_LOCATION) -# ###################################################################################################################### -# Create an installable target -# ###################################################################################################################### + +target_sources( + ${PROJECT_NAME_LOWERCASE} + PRIVATE ${sources} + PUBLIC FILE_SET public_headers + TYPE HEADERS BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR} + FILES + ${headers} + ${CMAKE_CURRENT_BINARY_DIR}/${VERSION_HEADER_LOCATION} +) + +target_compile_options( + ${PROJECT_NAME_LOWERCASE} + PUBLIC "$<$:/permissive->" +) + +# Link dependencies +find_package(Threads) +# Identify and link with the specific "packages" the project uses +target_link_libraries( + ${PROJECT_NAME_LOWERCASE} + PRIVATE + Threads::Threads fmt::fmt spdlog::spdlog +) + +if(CMAKE_SKIP_INSTALL_RULES) + add_library( + ${PROJECT_NAME_LOWERCASE}::${PROJECT_NAME_LOWERCASE} + ALIAS ${PROJECT_NAME_LOWERCASE} + ) + return() +endif() + + +############################################################################## +# Add uninstall target +############################################################################## +include(cmake/AddUninstallTarget.cmake) + packageProject( - # the name of the target to export NAME ${PROJECT_NAME} - # the version of the target to export VERSION ${PROJECT_VERSION} - # (optional) install your library with a namespace (Note: do NOT add extra '::') NAMESPACE ${PROJECT_NAME} - # a temporary directory to create the config files BINARY_DIR ${PROJECT_BINARY_DIR} - # location of the target's public headers - # A.K.A Install the `include` directory - INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include # Install the `include` directory. # NOTE: should match the target's INSTALL_INTERFACE include directory INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION} # (optional) create a header containing the version info # Note: that the path to headers should be lowercase VERSION_HEADER "${VERSION_HEADER_LOCATION}" - - # (optional) create a export header using GenerateExportHeader module - #EXPORT_HEADER "${PROJECT_NAME}/export.hpp" - - # (optional) define the project's version compatibility, defaults to `AnyNewerVersion` - # supported values: `AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion` + # (optional) define the project's version compatibility, + # defaults to `AnyNewerVersion` supported values: + # `AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion` COMPATIBILITY SameMajorVersion + RUNTIME_DESTINATION / # semicolon separated list of the project's dependencies DEPENDENCIES "${${PROJECT_NAME}_DEPENDENCIES}" - # (optional) option to disable the versioning of install destinations - DISABLE_VERSION_SUFFIX YES - # (optional) option to ignore target architecture for package resolution - # defaults to YES for header only (i.e. INTERFACE) libraries - ARCH_INDEPENDENT YES -) - - -# ###################################################################################################################### -# Add uninstall target -# ###################################################################################################################### -CONFIGURE_FILE( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - -ADD_CUSTOM_TARGET(${PROJECT_NAME_LOWERCASE}_uninstall - "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" + HEADER_SETS public_headers ) -# ###################################################################################################################### -# Unit testing setup: Testing only available if this is the main app -# ###################################################################################################################### - -if (PROJECT_IS_TOP_LEVEL AND ${PROJECT_NAME_UPPERCASE}_ENABLE_TESTING) - message(STATUS "Build unit tests for the project. Tests should always be found in the test folder\n") - enable_testing() - add_subdirectory(test) -endif() - -if (PROJECT_IS_TOP_LEVEL AND ${PROJECT_NAME_UPPERCASE}_ENABLE_STANDALONE) - add_subdirectory(standalone) -endif() - -# ###################################################################################################################### +# ############################################################################ # INFO -# ###################################################################################################################### +# ############################################################################ if(PROJECT_IS_TOP_LEVEL) - message(STATUS "CMake ${CMAKE_VERSION} successfully configured ${PROJECT_NAME} using ${CMAKE_GENERATOR} generator") - message(STATUS "${PROJECT_NAME} package version: ${CMAKE_PROJECT_VERSION}") - message(STATUS "${PROJECT_NAME} package dependencies: ${${PROJECT_NAME}_DEPENDENCIES}") - message(STATUS "${PROJECT_NAME} shared libraries: ${${PROJECT_NAME_UPPERCASE}_BUILD_SHARED_LIBS}") - if(${BUILD_SHARED_LIBS}) - message(STATUS "Building dynamic libraries") - else() - message(STATUS "Building static libraries") - endif() - message(STATUS "[cmake] Installation target path: ${CMAKE_INSTALL_PREFIX}") - if(CMAKE_TOOLCHAIN_FILE) - message(STATUS "[cmake] Use toolchain file: ${CMAKE_TOOLCHAIN_FILE}") - endif() - string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE) - message(STATUS "[cmake] Build for OS type: ${CMAKE_SYSTEM_NAME}") - message(STATUS "[cmake] Build for OS version: ${CMAKE_SYSTEM_VERSION}") - message(STATUS "[cmake] Build for CPU type: ${CMAKE_SYSTEM_PROCESSOR}") - message(STATUS "[cmake] Build type: ${CMAKE_BUILD_TYPE}") - message(STATUS "[cmake] Build with cxx flags: ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}") - message(STATUS "[cmake] Build with c flags: ${CMAKE_C_FLAGS_${BUILD_TYPE}} ${CMAKE_C_FLAGS}") - message(STATUS "[cmake] Source Directory: ${CMAKE_SOURCE_DIR}") + print_project_configuration() endif() diff --git a/cmake/AddUninstallTarget.cmake b/cmake/AddUninstallTarget.cmake new file mode 100644 index 0000000..c539c0d --- /dev/null +++ b/cmake/AddUninstallTarget.cmake @@ -0,0 +1,101 @@ +# SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT) SPDX-FileCopyrightText: +# 2008-2013 Kitware Inc. SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +AddUninstallTarget +------------------ + +Add the "uninstall" target for your project:: + + include(AddUninstallTarget) + + +will create a file ``cmake_uninstall.cmake`` in the build directory and add a +custom target ``uninstall`` (or ``UNINSTALL`` on Visual Studio and Xcode) that +will remove the files installed by your package (using +``install_manifest.txt``). +See also +https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake + +The :module:`AddUninstallTarget` module must be included in your main +``CMakeLists.txt``. If included in a subdirectory it does nothing. +This allows you to use it safely in your main ``CMakeLists.txt`` and include +your project using ``add_subdirectory`` (for example when using it with +:cmake:module:`FetchContent`). + +If the ``uninstall`` target already exists, the module does nothing. +#]=======================================================================] + +# AddUninstallTarget works only when included in the main CMakeLists.txt +if(NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + return() +endif() + +# The name of the target is uppercase in MSVC and Xcode (for coherence with the other standard +# targets) +if("${CMAKE_GENERATOR}" MATCHES "^(Visual Studio|Xcode)") + set(_uninstall "UNINSTALL") +else() + set(_uninstall "uninstall") +endif() + +# If target is already defined don't do anything +if(TARGET ${_uninstall}) + return() +endif() + +set(_filename cmake_uninstall.cmake) + +file( + WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_filename}" + "if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\") + message(WARNING \"Cannot find install manifest: \\\"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\\\"\") + return() +endif() + +file(READ \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\" files) +string(STRIP \"\${files}\" files) +string(REGEX REPLACE \"\\n\" \";\" files \"\${files}\") +list(REVERSE files) +foreach(file \${files}) + if(IS_SYMLINK \"\$ENV{DESTDIR}\${file}\" OR EXISTS \"\$ENV{DESTDIR}\${file}\") + message(STATUS \"Uninstalling: \$ENV{DESTDIR}\${file}\") + execute_process( + COMMAND \${CMAKE_COMMAND} -E remove \"\$ENV{DESTDIR}\${file}\" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval) + if(NOT \"\${rm_retval}\" EQUAL 0) + message(FATAL_ERROR \"Problem when removing \\\"\$ENV{DESTDIR}\${file}\\\"\") + endif() + else() + message(STATUS \"Not-found: \$ENV{DESTDIR}\${file}\") + endif() +endforeach(file) +" +) + +set(_desc "Uninstall the project...") +if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") + set(_comment + COMMAND + \$\(CMAKE_COMMAND\) + -E + cmake_echo_color + --switch=$\(COLOR\) + --cyan + "${_desc}" + ) +else() + set(_comment COMMENT "${_desc}") +endif() +add_custom_target( + ${_uninstall} + ${_comment} + COMMAND ${CMAKE_COMMAND} -P ${_filename} + USES_TERMINAL + BYPRODUCTS uninstall_byproduct + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) +set_property(SOURCE uninstall_byproduct PROPERTY SYMBOLIC 1) + +set_property(TARGET ${_uninstall} PROPERTY FOLDER "CMakePredefinedTargets") diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 0000000..15f626a --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,10 @@ +include(CMakeFindDependencyMacro) + +string(REGEX MATCHALL "[^;]+" SEPARATE_DEPENDENCIES "@PROJECT_DEPENDENCIES@") + +foreach(dependency ${SEPARATE_DEPENDENCIES}) + string(REPLACE " " ";" args "${dependency}") + find_dependency(${args}) +endforeach() + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/cmake/PackageProject.cmake b/cmake/PackageProject.cmake new file mode 100644 index 0000000..7dada1c --- /dev/null +++ b/cmake/PackageProject.cmake @@ -0,0 +1,243 @@ +cmake_minimum_required(VERSION 3.14...3.31) + +set(PACKAGE_PROJECT_ROOT_PATH + "${CMAKE_CURRENT_LIST_DIR}" + CACHE INTERNAL "The path to the PackageProject directory" +) + +# if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.31.0") cmake_policy(SET CMP0177 NEW) endif() + +function(packageProject) + include(CMakePackageConfigHelpers) + include(GNUInstallDirs) + + cmake_parse_arguments( + PROJECT + "" + "NAME;VERSION;INCLUDE_DIR;INCLUDE_DESTINATION;BINARY_DIR;COMPATIBILITY;EXPORT_HEADER;VERSION_HEADER;NAMESPACE;DISABLE_VERSION_SUFFIX;ARCH_INDEPENDENT;INCLUDE_HEADER_PATTERN;CPACK;RUNTIME_DESTINATION" + "DEPENDENCIES;HEADER_SETS" + ${ARGN} + ) + + # optional feature: TRUE or FALSE or UNDEFINED! These variables will then hold the respective + # value from the argument list or be undefined if the associated one_value_keyword could not be + # found. + if(PROJECT_DISABLE_VERSION_SUFFIX) + unset(PROJECT_VERSION_SUFFIX) + else() + set(PROJECT_VERSION_SUFFIX -${PROJECT_VERSION}) + endif() + + if(NOT DEFINED PROJECT_COMPATIBILITY) + set(PROJECT_COMPATIBILITY AnyNewerVersion) + endif() + + # we want to automatically add :: to our namespace, so only append if a namespace was given in the + # first place we also provide an alias to ensure that local and installed versions have the same + # name + if(DEFINED PROJECT_NAMESPACE) + if(PROJECT_CPACK) + set(CPACK_PACKAGE_NAMESPACE ${PROJECT_NAMESPACE}) + endif() + set(PROJECT_NAMESPACE ${PROJECT_NAMESPACE}::) + add_library(${PROJECT_NAMESPACE}${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + message(STATUS "creating library ${PROJECT_NAMESPACE}${PROJECT_NAME} with alias ${PROJECT_NAME}") + endif() + + if(DEFINED PROJECT_VERSION_HEADER OR DEFINED PROJECT_EXPORT_HEADER) + set(PROJECT_VERSION_INCLUDE_DIR ${PROJECT_BINARY_DIR}/PackageProjectInclude) + + if(DEFINED PROJECT_EXPORT_HEADER) + include(GenerateExportHeader) + generate_export_header( + ${PROJECT_NAME} + EXPORT_FILE_NAME + ${PROJECT_VERSION_INCLUDE_DIR}/${PROJECT_EXPORT_HEADER} + ) + endif() + + if(DEFINED PROJECT_VERSION_HEADER) + # clear previous matches + unset(CMAKE_MATCH_1) + unset(CMAKE_MATCH_3) + unset(CMAKE_MATCH_5) + unset(CMAKE_MATCH_7) + + string(REGEX MATCH "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$" _ + "${PROJECT_VERSION}" + ) + + set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_3}) + set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_5}) + set(PROJECT_VERSION_TWEAK ${CMAKE_MATCH_7}) + + if(NOT DEFINED PROJECT_VERSION_MAJOR) + set(PROJECT_VERSION_MAJOR "0") + endif() + if(NOT DEFINED PROJECT_VERSION_MINOR) + set(PROJECT_VERSION_MINOR "0") + endif() + if(NOT DEFINED PROJECT_VERSION_PATCH) + set(PROJECT_VERSION_PATCH "0") + endif() + if(NOT DEFINED PROJECT_VERSION_TWEAK) + set(PROJECT_VERSION_TWEAK "0") + endif() + + string(TOUPPER ${PROJECT_NAME} UPPERCASE_PROJECT_NAME) + # ensure that the generated macro does not include invalid characters + string(REGEX REPLACE [^a-zA-Z0-9] _ UPPERCASE_PROJECT_NAME ${UPPERCASE_PROJECT_NAME}) + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/version.h.in + ${PROJECT_VERSION_INCLUDE_DIR}/${PROJECT_VERSION_HEADER} @ONLY + ) + endif() + + get_target_property(target_type ${PROJECT_NAME} TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(VISIBILITY INTERFACE) + else() + set(VISIBILITY PUBLIC) + endif() + target_include_directories( + ${PROJECT_NAME} ${VISIBILITY} "$" + ) + install( + DIRECTORY ${PROJECT_VERSION_INCLUDE_DIR}/ + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + ) + endif() + + set(wbpvf_extra_args "") + if(NOT DEFINED PROJECT_ARCH_INDEPENDENT) + get_target_property(target_type "${PROJECT_NAME}" TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(PROJECT_ARCH_INDEPENDENT YES) + endif() + endif() + + if(PROJECT_ARCH_INDEPENDENT) + set(wbpvf_extra_args ARCH_INDEPENDENT) + # install to architecture independent (share) directory + set(INSTALL_DIR_FOR_CMAKE_CONFIGS ${CMAKE_INSTALL_DATADIR}) + else() + # if x32 or multilib->x32 , install to (lib) directory. if x64, install to (lib64) directory + set(INSTALL_DIR_FOR_CMAKE_CONFIGS ${CMAKE_INSTALL_LIBDIR}) + endif() + + write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY ${PROJECT_COMPATIBILITY} ${wbpvf_extra_args} + ) + + # set default runtime install subdirectory (RUNTIME_DESTINATION) + if(NOT DEFINED PROJECT_RUNTIME_DESTINATION) + set(PROJECT_RUNTIME_DESTINATION ${PROJECT_NAME}${PROJECT_VERSION_SUFFIX}) + endif() + + if(PROJECT_HEADER_SETS) + # required to install if use in project target since CMake 3.23 + set(FILE_SET_ARGS "FILE_SET" "${PROJECT_HEADER_SETS}") + endif() + + install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + NAMELINK_COMPONENT "${PROJECT_NAME}_Development" + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + PUBLIC_HEADER + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + ${FILE_SET_ARGS} + INCLUDES + DESTINATION "${PROJECT_INCLUDE_DESTINATION}" + ) + + set("${PROJECT_NAME}_INSTALL_CMAKEDIR" + "${INSTALL_DIR_FOR_CMAKE_CONFIGS}/cmake/${PROJECT_NAME}${PROJECT_VERSION_SUFFIX}" + CACHE PATH "CMake package config location relative to the install prefix" + ) + + mark_as_advanced("${PROJECT_NAME}_INSTALL_CMAKEDIR") + + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/Config.cmake.in + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY + ) + + install( + EXPORT ${PROJECT_NAME}Targets + DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" + NAMESPACE ${PROJECT_NAMESPACE} + COMPONENT "${PROJECT_NAME}_Development" + ) + + install( + FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" + COMPONENT "${PROJECT_NAME}_Development" + ) + + if(NOT DEFINED PROJECT_INCLUDE_HEADER_PATTERN) + set(PROJECT_INCLUDE_HEADER_PATTERN "*") + endif() + + if(PROJECT_INCLUDE_DESTINATION AND PROJECT_INCLUDE_DIR) + install( + DIRECTORY ${PROJECT_INCLUDE_DIR}/ + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + FILES_MATCHING + PATTERN "${PROJECT_INCLUDE_HEADER_PATTERN}" + ) + endif() + + set(${PROJECT_NAME}_VERSION ${PROJECT_VERSION} CACHE INTERNAL "") + + if(PROJECT_CPACK) + if(CPACK_PACKAGE_NAMESPACE) + set(CPACK_PACKAGE_NAME ${CPACK_PACKAGE_NAMESPACE}-${PROJECT_NAME}) + else() + set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) + endif() + if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}") + endif() + if(NOT CPACK_PACKAGE_HOMEPAGE_URL) + set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}") + endif() + set(CPACK_VERBATIM_VARIABLES YES) + set(CPACK_THREADS 0) + set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + endif() + + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) + + include(CPack) + endif() +endfunction() diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index d67cf76..fbcb738 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -6,3 +6,42 @@ function(verbose_message content) message(STATUS ${content}) endif() endfunction() + +function(print_project_configuration) + message( + STATUS + "CMake ${CMAKE_VERSION} successfully configured ${PROJECT_NAME} using ${CMAKE_GENERATOR} generator" + ) + message(STATUS "${PROJECT_NAME} package version: ${CMAKE_PROJECT_VERSION}") + message( + STATUS + "${PROJECT_NAME} package dependencies: ${${PROJECT_NAME}_DEPENDENCIES}" + ) + message( + STATUS + "${PROJECT_NAME} shared libraries: ${${PROJECT_NAME_UPPERCASE}_BUILD_SHARED_LIBS}" + ) + if(${BUILD_SHARED_LIBS}) + message(STATUS "Building dynamic libraries") + else() + message(STATUS "Building static libraries") + endif() + message(STATUS "[cmake] Installation target path: ${CMAKE_INSTALL_PREFIX}") + if(CMAKE_TOOLCHAIN_FILE) + message(STATUS "[cmake] Use toolchain file: ${CMAKE_TOOLCHAIN_FILE}") + endif() + string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE) + message(STATUS "[cmake] Build for OS type: ${CMAKE_SYSTEM_NAME}") + message(STATUS "[cmake] Build for OS version: ${CMAKE_SYSTEM_VERSION}") + message(STATUS "[cmake] Build for CPU type: ${CMAKE_SYSTEM_PROCESSOR}") + message(STATUS "[cmake] Build type: ${CMAKE_BUILD_TYPE}") + message( + STATUS + "[cmake] Build with cxx flags: ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}" + ) + message( + STATUS + "[cmake] Build with c flags: ${CMAKE_C_FLAGS_${BUILD_TYPE}} ${CMAKE_C_FLAGS}" + ) + message(STATUS "[cmake] Source Directory: ${CMAKE_SOURCE_DIR}") +endfunction() \ No newline at end of file diff --git a/cmake/version.h.in b/cmake/version.h.in new file mode 100644 index 0000000..e74e3eb --- /dev/null +++ b/cmake/version.h.in @@ -0,0 +1,8 @@ +#pragma once + +#define @UPPERCASE_PROJECT_NAME@_VERSION "@PROJECT_VERSION@" + +#define @UPPERCASE_PROJECT_NAME@_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_TWEAK @PROJECT_VERSION_TWEAK@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 8b867ef..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,94 +0,0 @@ - -# ############################################################################## -# Create library, setup header and source files -# ############################################################################## - -# ---- Add source files ---- -set(LIBNAME ${PROJECT_NAME_LOWERCASE}) - -# ############################################################################## -# Define Options -# ############################################################################## -option(${LIBNAME}_BUILD_HEADERS_ONLY FALSE) - -# CMAKE_SOURCE_DIR does indeed refer to the folder where the top-level -# CMakeLists.txt is defined. However, PROJECT_SOURCE_DIR refers to the folder of -# the CMakeLists.txt containing the most recent project() command. - -# Note: globbing sources is considered bad practice as CMake's generators may -# not detect new files automatically. Keep that in mind when changing files, or -# explicitly mention them here. -file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/include/*.hpp") -file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/src/*.cpp") - -# IDEs should put the headers in a nice place -source_group( - TREE "${CMAKE_SOURCE_DIR}/include" - PREFIX "Header Files" - FILES ${HEADER_LIST}) - -if(${LIBNAME}_BUILD_HEADERS_ONLY) - add_library(${LIBNAME} INTERFACE) -else() - add_library(${LIBNAME} ${headers} ${sources}) -endif() - -set_target_properties(${LIBNAME} - PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}" -) -verbose_message("Added all header and implementation files.\n") - -# -# Set the project standard and warnings -# -if(${LIBNAME}_BUILD_HEADERS_ONLY) - target_compile_features(${LIBNAME} INTERFACE cxx_std_20) -else() - target_compile_features(${LIBNAME} PUBLIC cxx_std_20) -endif() - -# -set_project_warnings(${LIBNAME}) -verbose_message("Applied compiler warnings. Using standard ${CMAKE_CXX_STANDARD}.\n") - -# being a cross-platform target, we enforce standards conformance on MSVC -target_compile_options(${LIBNAME} PRIVATE "$<$:/permissive->") - - -# Link dependencies -find_package(Threads) -# Identify and link with the specific "packages" the project uses -target_link_libraries(${LIBNAME} PRIVATE Threads::Threads fmt::fmt spdlog::spdlog) - -# Set the build/user include directories Allow usage of header files in the -# `src` directory, but only for utilities -if(${LIBNAME}_BUILD_HEADERS_ONLY) - target_include_directories(${LIBNAME} - INTERFACE - $ - $ - ) -else() - target_include_directories( - ${LIBNAME} - PUBLIC - $ - $ - PRIVATE - ${CMAKE_SOURCE_DIR}/src - ) -endif() - -verbose_message("Finished setting up include directories.") - -# Provide alias to library for -add_library(${LIBNAME}::${LIBNAME} ALIAS ${LIBNAME}) - -# Exporting -#set_target_properties(${LIBNAME} PROPERTIES EXPORT_NAME ${LIBNAME}) -# So that another folders could refer to it without finding the package. -#export(PACKAGE ${LIBNAME}) - -verbose_message("Project is now aliased as ${LIBNAME}::${LIBNAME}.\n") diff --git a/standalone/CMakeLists.txt b/standalone/CMakeLists.txt deleted file mode 100644 index 72fd7ca..0000000 --- a/standalone/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -cmake_minimum_required(VERSION 3.22) - -if (${CMAKE_PROJECT_NAME}) - set(MODULE_NAME ${CMAKE_PROJECT_NAME}) -else() - set(MODULE_NAME modern_cpp_project) -endif() - -project(Standalone LANGUAGES CXX) - -# --- Import tools ---- - -include(../cmake/Utils.cmake) - -# ###################################################################################################################### -# Options -# ###################################################################################################################### -option(STANDALONE_USE_INSTALLED_VERSION "Test the version found by find_package" OFF) -option(CPM_USE_LOCAL_PACKAGES "Always try to use `find_package` to get dependencies" TRUE) -# ---- Dependencies ---- - -include(../cmake/CPM.cmake) - -CPMAddPackage( - GITHUB_REPOSITORY jarro2783/cxxopts - VERSION 3.0.0 - OPTIONS "CXXOPTS_BUILD_EXAMPLES NO" "CXXOPTS_BUILD_TESTS NO" "CXXOPTS_ENABLE_INSTALL YES" -) - -if(STANDALONE_USE_INSTALLED_VERSION) - find_package(${MODULE_NAME} REQUIRED) -elseif(PROJECT_IS_TOP_LEVEL) - CPMAddPackage(NAME ${MODULE_NAME} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) -endif() - -# ---- Create standalone executable ---- - -file(GLOB sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) - -add_executable(${PROJECT_NAME} ${sources}) - -set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 23 OUTPUT_NAME ${MODULE_NAME}) - -target_link_libraries(${PROJECT_NAME} ${MODULE_NAME} cxxopts) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f02e4e3..f882c79 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,25 +1,19 @@ -cmake_minimum_required(VERSION 3.22) +cmake_minimum_required(VERSION 3.24...3.31) -if (${CMAKE_PROJECT_NAME}) - set(MODULE_NAME ${CMAKE_PROJECT_NAME}) -else() - set(MODULE_NAME modern_cpp_project) -endif() +set(MODULE_NAME modern_cpp_project) +set(TEST_SUITE ModernCppProjectTestRunner) -set(TEST_SUITE ${MODULE_NAME}TestRunner) project(${TEST_SUITE} LANGUAGES CXX) -message(STATUS "Started ${TEST_SUITE} Test Suite for ${CMAKE_PROJECT_NAME}...\n") -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - - -include(../cmake/Utils.cmake) # ###################################################################################################################### # Options # ###################################################################################################################### option(TEST_USE_INSTALLED_VERSION "Test the version found by find_package" OFF) option(CPM_USE_LOCAL_PACKAGES "Always try to use `find_package` to get dependencies" TRUE) + +include(../cmake/Utils.cmake) +include(../cmake/PackageProject.cmake) # ###################################################################################################################### # Dependencies # ###################################################################################################################### @@ -28,17 +22,15 @@ include(../cmake/CPM.cmake) CPMAddPackage( NAME ut GITHUB_REPOSITORY boost-ext/ut - VERSION 2.1.1 + VERSION 2.3.0 ) CPMAddPackage("gh:TheLartians/Format.cmake@1.8.1") if(TEST_USE_INSTALLED_VERSION) find_package(${MODULE_NAME} REQUIRED) -elseif(PROJECT_IS_TOP_LEVEL) - CPMAddPackage(NAME ${MODULE_NAME} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) - # needed to generate test target - enable_testing() +else() + CPMAddPackage(NAME ${MODULE_NAME} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. FORCE ON) endif() # ###################################################################################################################### @@ -48,11 +40,18 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) verbose_message("Adding ${TEST_SOURCES} to ${TEST_SUITE} test suite.") # ###################################################################################################################### -# Create binary +# Create binary # ###################################################################################################################### add_executable(${TEST_SUITE} ${TEST_SOURCES}) +#add_dependencies(${TEST_SUITE} ${MODULE_NAME}) + + +get_target_property(ut_include_dirs Boost::ut INTERFACE_INCLUDE_DIRECTORIES) +target_include_directories(${TEST_SUITE} PRIVATE ${ut_SOURCE_DIR}/include) +target_link_libraries(${TEST_SUITE} PRIVATE Boost::ut ${MODULE_NAME}::${MODULE_NAME}) + target_compile_features(${TEST_SUITE} PRIVATE cxx_std_23) -target_link_libraries(${TEST_SUITE} PRIVATE Boost::ut ${MODULE_NAME}) + # ###################################################################################################################### # Enable compiler warnings # ###################################################################################################################### @@ -61,37 +60,25 @@ if(NOT TEST_USE_INSTALLED_VERSION) target_compile_options(${MODULE_NAME} PUBLIC -Wall -Wpedantic -Wextra -Werror) elseif(MSVC) target_compile_options(${MODULE_NAME} PUBLIC /W4 /WX) - target_compile_definitions(${TEST_SUITE} PUBLIC DOCTEST_CONFIG_USE_STD_HEADERS) endif() - - target_compile_definitions(${TEST_SUITE} PUBLIC DOCTEST_CONFIG_USE_STD_HEADERS) endif() - # ###################################################################################################################### -# ---- Add Tests ---- +# ---- Enabling Tests ---- # ###################################################################################################################### -# Note: doctest and similar testing frameworks can automatically configure CMake tests. -# For other testing frameworks add the tests target instead: +enable_testing() +# Note: doctest and similar testing frameworks can automatically configure CMake tests. +# For other testing frameworks add the tests target instead: # add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) - -# testing frameworks add the tests target instead: -if(NOT doctest_SOURCE_DIR) - add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) -else() - include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) - doctest_discover_tests(${TEST_SUITE}) -endif() - - +add_test(NAME ${TEST_SUITE} COMMAND ${TEST_SUITE}) # ###################################################################################################################### # Setup code coverage if enabled # ###################################################################################################################### if (${MODULE_NAME}_ENABLE_CODE_COVERAGE OR ENABLE_CODE_COVERAGE) - # ---- code coverage ---- - target_compile_options(${MODULE_NAME} PUBLIC -O0 -g -fprofile-arcs -ftest-coverage) - target_link_options(${MODULE_NAME} PUBLIC -fprofile-arcs -ftest-coverage) + # ---- code coverage ---- + target_compile_options(${MODULE_NAME} PUBLIC -O0 -g -fprofile-arcs -ftest-coverage) + target_link_options(${MODULE_NAME} PUBLIC -fprofile-arcs -ftest-coverage) endif() -verbose_message("Finished adding unit tests for ${MODULE_NAME}.") +message(STATUS "Finished adding unit tests for ${TEST_SUITE}.") From 9b28e51d7a536b79d180d8e38c0bbcb08d5b15a2 Mon Sep 17 00:00:00 2001 From: Diego Saraiva Date: Sun, 6 Apr 2025 16:36:30 -0300 Subject: [PATCH 2/4] all target added --- all/CMakeLists.txt | 13 +++++++++++++ standalone/CMakeLists.txt | 29 +++++++++++++++++++++++++++++ standalone/src/main.cpp | 38 ++------------------------------------ 3 files changed, 44 insertions(+), 36 deletions(-) create mode 100644 all/CMakeLists.txt create mode 100644 standalone/CMakeLists.txt diff --git a/all/CMakeLists.txt b/all/CMakeLists.txt new file mode 100644 index 0000000..b1af969 --- /dev/null +++ b/all/CMakeLists.txt @@ -0,0 +1,13 @@ +# this script adds all subprojects to a single build to allow IDEs understand the full project +# structure. +cmake_minimum_required(VERSION 3.24...3.31) + +project(BuildAll LANGUAGES CXX) + +include(../cmake/Utils.cmake) + +# needed to generate test target +enable_testing() + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../standalone ${CMAKE_BINARY_DIR}/standalone) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../test ${CMAKE_BINARY_DIR}/test) \ No newline at end of file diff --git a/standalone/CMakeLists.txt b/standalone/CMakeLists.txt new file mode 100644 index 0000000..00024e4 --- /dev/null +++ b/standalone/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.24...3.31) + +project(Standalone LANGUAGES CXX) + +set(APP_EXECUTABLE_NAME "modern_cpp_app") +set(LIBRARY_TARGET_NAME "modern_cpp_project") + +# ---- Include Custom CMake Modules ---- +include(../cmake/Utils.cmake) + +# ---- Dependency Management ---- +include(../cmake/CPM.cmake) +include(../cmake/PackageProject.cmake) + +CPMAddPackage(NAME ${LIBRARY_TARGET_NAME} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. FORCE ON) + +# ---- Build Executable ---- +file(GLOB sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +add_executable(${APP_EXECUTABLE_NAME} ${sources}) + +set_target_properties(${APP_EXECUTABLE_NAME} PROPERTIES + CXX_STANDARD 23 + OUTPUT_NAME ${APP_EXECUTABLE_NAME} +) + +target_link_libraries(${APP_EXECUTABLE_NAME} + PRIVATE + ${LIBRARY_TARGET_NAME}::${LIBRARY_TARGET_NAME} +) \ No newline at end of file diff --git a/standalone/src/main.cpp b/standalone/src/main.cpp index d734b71..017a82d 100644 --- a/standalone/src/main.cpp +++ b/standalone/src/main.cpp @@ -1,12 +1,11 @@ #include "modern_cpp_project/greeter.hpp" #include "modern_cpp_project/version.hpp" -#include #include #include #include -auto main(int argc, char** argv) -> int { +auto main(void) -> int { const std::unordered_map languages{ {"en", greeter::LanguageCode::EN}, {"de", greeter::LanguageCode::DE}, @@ -14,40 +13,7 @@ auto main(int argc, char** argv) -> int { {"fr", greeter::LanguageCode::FR}, }; - cxxopts::Options options(*argv, "A program to welcome the world!"); - - std::string language; - std::string name; - - // clang-format off - options.add_options() - ("h,help", "Show help") - ("v,version", "Print the current version number") - ("n,name", "Name to greet", cxxopts::value(name)->default_value("World")) - ("l,lang", "Language code to use", cxxopts::value(language)->default_value("en")) - ; - // clang-format on - - auto result = options.parse(argc, argv); - - if (result["help"].as()) { - std::cout << options.help() << std::endl; - return 0; - } - - if (result["version"].as()) { - std::cout << "Greeter, version " << MODERN_CPP_PROJECT_VERSION << std::endl; - return 0; - } - - auto langIt = languages.find(language); - if (langIt == languages.end()) { - std::cerr << "unknown language code: " << language << std::endl; - return 1; - } - - greeter::Greeter greeter(name); - std::cout << greeter.greet(langIt->second) << std::endl; + greeter::Greeter greeter("Hello World"); return 0; } \ No newline at end of file From e42e394da7e485fbb9ff36171e03be1c78444c61 Mon Sep 17 00:00:00 2001 From: Diego Saraiva Date: Sun, 22 Jun 2025 13:27:36 -0300 Subject: [PATCH 3/4] excluding macosX files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2f54554..32a5110 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,6 @@ compile_commands.json # Check files cppcheck.txt + +# MAC FILES +.DS_Store From fa59fe8bd349c5a59d7ed78eb1ac65e17d24070c Mon Sep 17 00:00:00 2001 From: Diego Saraiva Date: Sun, 22 Jun 2025 13:28:12 -0300 Subject: [PATCH 4/4] excluding macosX files --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 32a5110..0e1f28c 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,8 @@ compile_commands.json # Check files cppcheck.txt -# MAC FILES +# macOS system files .DS_Store + +# macOS folder settings +__MACOSX/