diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..33df4d5 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,71 @@ +name: Tests + +on: + push: + branches: + - master + pull_request: + branches: + - '*' + workflow_dispatch: + +env: + CMLIB_VERSION: 1.0.0 + +jobs: + test_linux: + strategy: + matrix: + image: [ + "test_debian:bullseye", + "test_debian:trixie", + "test_debian:bookworm", + "test_ubuntu:2004", + "test_ubuntu:2204", + "test_ubuntu:2404", + "test_fedora:41", + "test_fedora:42" + ] + + runs-on: ubuntu-latest + container: + image: ghcr.io/cmakelib/${{ matrix.image }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run tests + run: | + git config --global --add safe.directory "$(pwd)" + git remote set-url origin "${{ github.server_url }}/${{ github.repository }}" + git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git + export CMLIB_DIR=$(pwd)/cmakelib + cd test/ && cmake . + + test_macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run tests + run: | + git config --global --add safe.directory "$(pwd)" + git remote set-url origin "${{ github.server_url }}/${{ github.repository }}" + git clone --branch "v${CMLIB_VERSION}" https://github.com/cmakelib/cmakelib.git + export CMLIB_DIR=$(pwd)/cmakelib + cd test/ && cmake . + + test_windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run tests + run: | + git config --global --add safe.directory "$(pwd)" + git remote set-url origin "${{ github.server_url }}/${{ github.repository }}" + git clone --branch "v$Env:CMLIB_VERSION" https://github.com/cmakelib/cmakelib.git + $Env:CMLIB_DIR=$(Join-Path -Path $(Get-Location).Path -ChildPath "cmakelib") + cd test/ && cmake . \ No newline at end of file diff --git a/CMDEFConfig.cmake b/CMDEFConfig.cmake index f2a18d8..ff208c2 100644 --- a/CMDEFConfig.cmake +++ b/CMDEFConfig.cmake @@ -1,2 +1,2 @@ -INCLUDE("${CMAKE_CURRENT_LIST_DIR}/FinDBASEDEF.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/FindCMDEF.cmake") diff --git a/FindCMDEF.cmake b/FindCMDEF.cmake index 725e02e..78e280a 100644 --- a/FindCMDEF.cmake +++ b/FindCMDEF.cmake @@ -9,7 +9,7 @@ # - include all CMDEF modules # -CMAKE_MINIMUM_REQUIRED(VERSION 3.21 FATAL_ERROR) +CMAKE_MINIMUM_REQUIRED(VERSION 3.22 FATAL_ERROR) SET(CMDEF_PACKAGE_NAME "CMDEF") @@ -30,5 +30,7 @@ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/system_modules/CMDEF_LINK_OPTION.cmake) INCLUDE(${CMAKE_CURRENT_LIST_DIR}/system_modules/CMDEF_INSTALL.cmake) INCLUDE(${CMAKE_CURRENT_LIST_DIR}/system_modules/CMDEF_PACKAGE.cmake) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/system_modules/CMDEF_CLEANUP.cmake) + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/system_modules/CMDEF_HELPER.cmake) diff --git a/README.md b/README.md index 0bbec32..cf53c53 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,59 @@ -# CMake-lib Basedef component +# CMake-lib Definition Framework Component -CMake-lib provides consistent setting for built environment. +Linux: ![buildbadge_github], Windows: ![buildbadge_github], Mac OS: ![buildbadge_github] + +CMDEF aka **CMake-lib Definition Framework** + +CMake-lib provides consistent settings for build environment. It simplifies and maintains built option, libraries and executables. ## Requirements -- [CMLIB] library installed +CMDEF is intended to be used thru [CMLIB]. + +CMDEF is not supposed to be used separately. + +To use the library install [CMLIB] and call `FIND_PACKAGE(CMLIB COMPONENTS CMDEF)` ## General The library is not mainly intended for extending CMake functionality. It's set of wrappers and helpers which enables easily use of existing CMake -features. +features in a more standardised manner across multiple projects. ### Definition of Main target Each CMake project has one main target - the target for which the project is created, compiled, ... -For example we have CMake project for building chrome browser. -Browser is represented by one executable called `chrome`. That executable +For example - CMake project for building chrome browser. +Browser is represented by the executable called `chrome`. The executable must have own target in CMake project. By that target other project properties are referenced - installer name, application name, documentation etc. -We call this type of target as 'main target' (the 'object' for which we -create the CMake project) +This type of target is called 'main target' (the 'object' for which the CMake project is created). -In the library the 'main target' is represented by MAIN_TARGET variable/parameter for macros/functions +The library 'main target' is represented by LIBRARY_GROUP argument with suffix added according to a library type created. ## Usage -Let GIT_URI be a GIT URI of this repository. - +```cmake FIND_PACKAGE(CMLIB COMPONENTS CMDEF) +``` ### Set build defaults -CMake-lib sets and maintains build/link flags and global wide definitions +CMake-lib sets and maintains build and link flags and global wide definitions. Component workflow - reset CMake default build flags by `CMDEF_CLEANUP` - set default build and link options by `CMDEF_COMPILE_OPTIONS`, `CMDEF_LINK_OPTIONS` -- set compile definitions by `CMDEF_COMPIE_DEFINITIONS` +- set compile definitions by `CMDEF_COMPILE_DEFINITIONS` -examples can be found at [example] directory +examples can be found at [example] directory. ## Function list @@ -55,7 +62,7 @@ Each entry in list represents one feature for CMake. Most of the functions are just wrappers which enclosures base feature of CMake. -Detailed documentation for each function can be found at appropriate module. +Detailed documentation for each function can be found at the appropriate module. - [CMDEF_ADD_LIBRARY.cmake] - [CMDEF_ADD_EXECUTABLE.cmake] @@ -67,13 +74,15 @@ Detailed documentation for each function can be found at appropriate module. - [CMDEF_LINK_OPTION.cmake] - [CMDEF_PACKAGE.cmake] -## Config Variables +## Documentation + +Every function has a comprehensive documentation written as part of the function definition. -Configuration variables detailed desc. for the library is located at [doc/CacheVariables.md] +Context documentation is located at [doc/README.md] ## Coding standards -- We use Uppercase for all keywords and global variables +- The uppercase letters are used for all keywords and global variables - Each helper function must begin with '_' [CMLIB]: https://github.com/cmakelib/cmakelib @@ -88,4 +97,7 @@ Configuration variables detailed desc. for the library is located at [doc/CacheV [CMDEF_LINK_OPTION.cmake]: system_modules/CMDEF_LINK_OPTION.cmake [CMDEF_PACKAGE.cmake]: system_modules/CMDEF_PACKAGE.cmake [doc/CacheVariables.md]: doc/CacheVariables.md +[doc/README.md]: doc/README.md [example]: example/ + +[buildbadge_github]: https://github.com/cmakelib/cmakelib-component-cmdef/actions/workflows/tests.yml/badge.svg \ No newline at end of file diff --git a/doc/CacheVariables.md b/doc/CacheVariables.md index 77a5b10..ca16446 100644 --- a/doc/CacheVariables.md +++ b/doc/CacheVariables.md @@ -1,5 +1,5 @@ -# CMDEf cache variables +# CMDEF cache variables Each section represent one Cache variable used in CMDEF. @@ -31,10 +31,10 @@ It tries to set the variable in the following order ## CMDEF_BUILD_TYPE_CMAKE_BUILD_TYPE_OVERRIDE:BOOL=\ -Indicate if the CMAKE_BUILD_TYPE is overriden by CMDEF library. +Indicate if the CMAKE_BUILD_TYPE is overridden by CMDEF library. - If the CMAKE_BUILD_TYPE is not set the CMDEF try to set the CMAKE_BUILD_TYPE variable - to the predefined value stored in CMDEF_BUILD_TYPE_DEFAULT variable. In this case the vairable is set to ON. + to the predefined value stored in CMDEF_BUILD_TYPE_DEFAULT variable. In this case the variable is set to ON. - If the CMAKE_BUILD_TYPE is set explicitly the variable is set to OFF. ## CMDEF_BUILD_TYPE_DEFAULT:STRING=Debug @@ -43,7 +43,7 @@ Default build type if CMAKE_BUILD_TYPE is not specified. ## CMDEF_BUILD_TYPE_LIST:STRING,LIST=\ -List of the suported byuld types. CMAKE_BUILD_TYPE must hold exactly one value from this list. +List of the supported build types. CMAKE_BUILD_TYPE must hold exactly one value from this list. Type: String, List @@ -67,7 +67,7 @@ It tries to set the variable in the following order 1. filled from ENV variable CMDEF_DISTRO_ID if defined 1. auto filled by CMDEF library (by `lsb_release` utility) -## CMDEF_DISTRO_VERSION_ID:STRING=\ +## CMDEF_DISTRO_VERSION_ID:STRING=\ Distribution version ID (eg for debian bullseye: 11, ...). It always holds lowercase value... diff --git a/doc/PackageChain.md b/doc/PackageChain.md index 630de2a..4e49397 100644 --- a/doc/PackageChain.md +++ b/doc/PackageChain.md @@ -50,7 +50,7 @@ CMDEF_ADD_EXECUTABLE( Configure installation of a target, that will export it and create the target's `.cmake` file. -`NAMESPACE` is **required** when using the whole chain and it must be **equal** to the name of the **main target**. +`NAMESPACE` is **optional** but **recommended** when using the whole chain. When specified, it must be **equal** to the name of the **main target** and end with `::`. If using `CMDEF_PACKAGE`, the namespace consistency is validated automatically. > **main target** - the 'object' for which we create the CMake project. It relates to CMDEF_PACKAGE #### Example @@ -106,7 +106,7 @@ make install # Install cmake files, mylib-shared.so and myexecutable to .zip ``` -> Note that when `CMAKE_BUILD_TYPE=Debug`, the libraries and executables **OUTPUT_NAME** will have a suffix `d` added to them. +> Note that when `CMAKE_BUILD_TYPE=Debug`, the libraries and executables **OUTPUT_NAME** will have a debug suffix added to them (controlled by `CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX`, typically `d`). The created package has the following structure: diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..798424e --- /dev/null +++ b/doc/README.md @@ -0,0 +1,9 @@ + +# Detailed Documentation for CMDEF Component + +This directory contains detailed documentation for the CMDEF component of the CMake-lib library. + +## Documentation Files + +- [CacheVariables.md](CacheVariables.md): Describes all cache variables used by the CMDEF component. +- [PackageChain.md](PackageChain.md): Explains the package chain workflow and functions provided by CMDEF. diff --git a/example/executable/CMakeLists.txt b/example/executable/CMakeLists.txt index 2ddcb38..f0f5c4c 100644 --- a/example/executable/CMakeLists.txt +++ b/example/executable/CMakeLists.txt @@ -14,6 +14,7 @@ PROJECT(${CMAKE_PROJECT_NAME}) FIND_PACKAGE(CMLIB COMPONENTS CMDEF) +CMDEF_CLEANUP() # # Add Definitions for each build type globally @@ -36,7 +37,7 @@ IF(CMDEF_OS_LINUX) ) ELSEIF(CMDEF_OS_WINDOWS) CMDEF_COMPILE_OPTIONS( - ALL /wd4996 # Disable deprectation warning on Windows OS + ALL /wd4996 # Disable deprecation warning on Windows OS ) ENDIF() @@ -53,7 +54,7 @@ CMDEF_ADD_EXECUTABLE( CMDEF_COMPILE_DEFINITIONS_TARGET( TARGET executable - VISIBLITY PUBLIC + VISIBILITY PUBLIC ALL RETURN_CODE=245 DEBUG RETURN_CODE_DEBUG=1000 RELEASE RETURN_CODE_RELEASE=2020 @@ -66,7 +67,7 @@ CMDEF_COMPILE_DEFINITIONS_TARGET( ADD_EXECUTABLE(cmake_executable main.c) CMDEF_COMPILE_DEFINITIONS_TARGET( TARGET cmake_executable - VISIBLITY PRIVATE + VISIBILITY PRIVATE ALL RETURN_CODE=255 DEBUG RETURN_CODE_DEBUG=10000 RELEASE RETURN_CODE_RELEASE=20200 @@ -93,4 +94,4 @@ CMDEF_PACKAGE( # Just choose generator and include CPack # SET(CPACK_GENERATOR ZIP) -INCLUDE(CPack) +INCLUDE(CPack) \ No newline at end of file diff --git a/example/library-interface/CMakeLists.txt b/example/library-interface/CMakeLists.txt index 85b436f..e4bf1f4 100644 --- a/example/library-interface/CMakeLists.txt +++ b/example/library-interface/CMakeLists.txt @@ -104,7 +104,7 @@ CMDEF_INSTALL(TARGET testlink-executable NAMESPACE testlib-shared::) # CMDEF_COMPILE_OPTIONS_TARGET( TARGET testlib-shared - VISIBLITY PUBLIC + VISIBILITY PUBLIC DEBUG -Wall ) diff --git a/example/library-interface/main.cpp b/example/library-interface/main.cpp index 5d6b697..fd6eeee 100644 --- a/example/library-interface/main.cpp +++ b/example/library-interface/main.cpp @@ -1,5 +1,5 @@ /** - * @brief Test exacutable to test all defined symbols are linked correctly + * @brief Test executable to test all defined symbols are linked correctly */ #include diff --git a/example/library/CMakeLists.txt b/example/library/CMakeLists.txt index 64de75e..54b8f11 100644 --- a/example/library/CMakeLists.txt +++ b/example/library/CMakeLists.txt @@ -49,7 +49,7 @@ CMDEF_ADD_LIBRARY( # CMDEF_COMPILE_OPTIONS_TARGET( TARGET testlib-shared - VISIBLITY PUBLIC + VISIBILITY PUBLIC DEBUG -Wall ) diff --git a/system_modules/CMDEF_ADD_EXECUTABLE.cmake b/system_modules/CMDEF_ADD_EXECUTABLE.cmake index e30db26..4443494 100644 --- a/system_modules/CMDEF_ADD_EXECUTABLE.cmake +++ b/system_modules/CMDEF_ADD_EXECUTABLE.cmake @@ -64,7 +64,7 @@ FUNCTION(CMDEF_ADD_EXECUTABLE) IF(CMDEF_OS_WINDOWS AND __WIN32) SET(exec_flag WIN32) ELSEIF(CMDEF_OS_MACOS AND __MACOS_BUNDLE) - SET(exec_flag MACOS_BUNDLE) + SET(exec_flag MACOSX_BUNDLE) ENDIF() SET(output_name ${__TARGET}) diff --git a/system_modules/CMDEF_ADD_LIBRARY.cmake b/system_modules/CMDEF_ADD_LIBRARY.cmake index 34c7d89..cbf1c22 100644 --- a/system_modules/CMDEF_ADD_LIBRARY.cmake +++ b/system_modules/CMDEF_ADD_LIBRARY.cmake @@ -35,9 +35,9 @@ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMDEF_RESOURCE.cmake) # SOURCES - all c/cpp/h/hpp files will be added as source to given target. # # SOURCE_BASE_DIRECTORY - INTERFACE library only. Only for installation. -# It is base directory for all source files. -# If defined, source files will be installed with relative path from this directory. -# Else, source files will be installed directly in CMDEF_SOURCE_INSTALL_DIR +# It is base directory for all source files. +# If defined, source files specified by SOURCES will be installed with relative path respective to SOURCE_BASE_DIRECTORY. +# Else, source files specified by SOURCES will be installed directly into CMDEF_SOURCE_INSTALL_DIR. # # [Custom properties] # CMDEF_LIBRARY - property which mark library as "created by CMDEF_ADD_LIBRARY" diff --git a/system_modules/CMDEF_BUILD_TYPE.cmake b/system_modules/CMDEF_BUILD_TYPE.cmake index 9514499..29c17c7 100644 --- a/system_modules/CMDEF_BUILD_TYPE.cmake +++ b/system_modules/CMDEF_BUILD_TYPE.cmake @@ -28,7 +28,7 @@ SET(CMDEF_BUILD_TYPE_DEFAULT "Debug" MACRO(_CMDEF_BUILD_TYPE_SET_CMAKE_BUILD_TYPE_OVERRIDE opt ${ARGN}) SET(CMDEF_BUILD_TYPE_CMAKE_BUILD_TYPE_OVERRIDE ${opt} CACHE BOOL - "ON if the CMAKE_BUILD_TYPE is overriden by CMDEF, OFF otherwise" + "ON if the CMAKE_BUILD_TYPE is overridden by CMDEF, OFF otherwise" ${ARGN} ) ENDMACRO() @@ -65,7 +65,7 @@ UNSET(all_find) ## -# Initialize CMake veriables according to CMDEF definitions +# Initialize CMake variables according to CMDEF definitions # # ( # ) diff --git a/system_modules/CMDEF_COMPILE_DEFINITION.cmake b/system_modules/CMDEF_COMPILE_DEFINITION.cmake index 24499b6..6195e26 100644 --- a/system_modules/CMDEF_COMPILE_DEFINITION.cmake +++ b/system_modules/CMDEF_COMPILE_DEFINITION.cmake @@ -22,7 +22,7 @@ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMDEF_ADD_LIBRARY.cmake) # from BUILD_TYPE list. # # LANG -array, if specified must be one of CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to ADD_COMPILE_DEFINITION # by generator_expression $<:${definitnion}> @@ -78,20 +78,20 @@ ENDFUNCTION() # from BUILD_TYPE list. # # LANG - array, if specified must be one of CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to TARGET_COMPILE_DEFINITION # by generator_expression $<:${definitnion}> # -# VISIBLITY is passed to visiblity section of TARGET_LINK_OPTIONS. -# If no visiblity specified than visiblity is omitted +# VISIBILITY is passed to visibility section of TARGET_LINK_OPTIONS. +# If no visibility specified than visibility is omitted # # ( # TARGET # [LANG M] # [ALL ] # [ ]{1,} -# [VISIBLITY ] +# [VISIBILITY ] # ) # FUNCTION(CMDEF_COMPILE_DEFINITIONS_TARGET) @@ -101,9 +101,9 @@ FUNCTION(CMDEF_COMPILE_DEFINITIONS_TARGET) ${CMDEF_BUILD_TYPE_LIST_UPPERCASE} ONE_VALUE TARGET - VISIBLITY + VISIBILITY REQUIRED - TARGET VISIBLITY + TARGET VISIBILITY P_ARGN ${ARGN} ) @@ -125,9 +125,9 @@ FUNCTION(CMDEF_COMPILE_DEFINITIONS_TARGET) IF(DEFINED __LANG) SET(condition $,$>) SET(compile_definitions $<${condition}:${${build_type_var}}>) - TARGET_COMPILE_DEFINITIONS(${original_target_name} ${__VISIBLITY} ${compile_definitions}) + TARGET_COMPILE_DEFINITIONS(${original_target_name} ${__VISIBILITY} ${compile_definitions}) ELSE() - TARGET_COMPILE_DEFINITIONS(${original_target_name} ${__VISIBLITY} $<$:${${build_type_var}}>) + TARGET_COMPILE_DEFINITIONS(${original_target_name} ${__VISIBILITY} $<$:${${build_type_var}}>) ENDIF() ENDFOREACH() ENDFUNCTION() diff --git a/system_modules/CMDEF_COMPILE_OPTION.cmake b/system_modules/CMDEF_COMPILE_OPTION.cmake index 8851234..463b778 100644 --- a/system_modules/CMDEF_COMPILE_OPTION.cmake +++ b/system_modules/CMDEF_COMPILE_OPTION.cmake @@ -23,7 +23,7 @@ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMDEF_ADD_LIBRARY.cmake) # from BUILD_TYPE list. # # LANG - array, If specified must be on CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to ADD_COMPILE_OPTIONS # by generator_expression $<:${option}> @@ -79,20 +79,20 @@ ENDMACRO() # to each BUILD_TYPE # # LANG - array, if specified must be one of CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to ADD_COMPILE_OPTIONS # by generator_expression $<:${option}> # -# VISIBLITY is passed to visiblity section of TARGET_LINK_OPTIONS. -# If no visiblity specified than visiblity is omitted +# VISIBILITY is passed to visibility section of TARGET_LINK_OPTIONS. +# If no visibility specified than visibility is omitted # # ( # TARGET # [LANG ] # [ALL ] # [ ]{1,} -# [VISIBLITY ] +# [VISIBILITY ] # ) # FUNCTION(CMDEF_COMPILE_OPTIONS_TARGET) @@ -102,10 +102,10 @@ FUNCTION(CMDEF_COMPILE_OPTIONS_TARGET) ${CMDEF_BUILD_TYPE_LIST_UPPERCASE} ONE_VALUE TARGET - VISIBLITY + VISIBILITY REQUIRED TARGET - VISIBLITY + VISIBILITY P_ARGN ${ARGN} ) @@ -128,9 +128,9 @@ FUNCTION(CMDEF_COMPILE_OPTIONS_TARGET) SET(option ${${build_type_var}}) SET(condition $,$>) SET(compile_options $<${condition}:${option}>) - TARGET_COMPILE_OPTIONS(${original_target_name} ${__VISIBLITY} ${compile_options}) + TARGET_COMPILE_OPTIONS(${original_target_name} ${__VISIBILITY} ${compile_options}) ELSE() - TARGET_COMPILE_OPTIONS(${original_target_name} ${__VISIBLITY} $<$:${${build_type_var}}>) + TARGET_COMPILE_OPTIONS(${original_target_name} ${__VISIBILITY} $<$:${${build_type_var}}>) ENDIF() ENDFOREACH() ENDFUNCTION() diff --git a/system_modules/CMDEF_ENV.cmake b/system_modules/CMDEF_ENV.cmake index 51f9825..d23ff1b 100644 --- a/system_modules/CMDEF_ENV.cmake +++ b/system_modules/CMDEF_ENV.cmake @@ -3,7 +3,6 @@ # initialize base CMDEF CMake variables. # # Module relay on some CMake variables like -# - CMAKE_SIZEOF_VOID_P (not defined for Script mode) # - CMAKE_CURRENT_BINARY_DIR (defined as "${CMAKE_CURRENT_LIST_DIR}" for script mode) # @@ -17,7 +16,7 @@ FIND_PACKAGE(CMLIB REQUIRED) # # It holds list of supported/well_tested architectures # -# aplsil architecture referes to Apple silicon +# aplsil architecture refers to Apple silicon # SET(_CMDEF_ENV_SUPPORTED_ARCH_LIST "x86-64" "x86" "aarch64" "aplsil") @@ -40,6 +39,7 @@ FUNCTION(CMDEF_ENV_INIT) _CMDEF_ENV_SET_SUPPORTED_LANG() IF(CMDEF_OS_WINDOWS) + _CMDEF_ENV_SET_WINDOWS_FLAGS() IF(NOT CMDEF_WINDOWS_EXECUTABLE_MT) FIND_PROGRAM(CMDEF_WINDOWS_EXECUTABLE_MT "mt.exe") IF(${CMDEF_WINDOWS_EXECUTABLE_MT} STREQUAL "${prefix}WINDOWS_EXECUTABLE_MT-NOTFOUND") @@ -122,7 +122,7 @@ MACRO(_CMDEF_ENV_SET_PACKAGE os_name) ) IF(NOT DEFINED CMDEF_OS_NAME_UPPER) - MESSAGE(FATAL_ERROR "") + MESSAGE(FATAL_ERROR "CMDEF_OS_NAME_UPPER is not defined") ENDIF() SET(shared_var_name CMDEF_LIBRARY_NAME_SUFFIX_SHARED_${CMDEF_OS_NAME_UPPER}) @@ -204,7 +204,11 @@ ENDFUNCTION() # ) # MACRO(_CMDEF_ENV_SET_OS) - CMAKE_HOST_SYSTEM_INFORMATION(RESULT _os_name QUERY OS_NAME) + IF(NOT DEFINED CMAKE_SYSTEM_NAME) + MESSAGE(FATAL_ERROR "CMAKE_SYSTEM_NAME is not defined!") + ENDIF() + + SET(_os_name "${CMAKE_SYSTEM_NAME}") MESSAGE(STATUS "System name: ${_os_name}") SET(os_name "") IF("${_os_name}" STREQUAL "Darwin" OR @@ -281,7 +285,7 @@ MACRO(_CMDEF_ENV_SET_OS) ENDIF() SET(CMDEF_ARCHITECTURE ${arch} CACHE STRING - "Achitecture for which we will compile" + "Architecture for which we will compile" ) ENDIF() MESSAGE(STATUS "Architecture: ${CMDEF_ARCHITECTURE}") @@ -377,7 +381,7 @@ ENDMACRO() # FUNCTION(_CMDEF_ENV_SET_WINDOWS_FLAGS) IF(NOT DEFINED CMDEF_OS_WINDOWS) - MESSAGE(FATAL_ERROR "Canot determine target OS. Not defined.") + MESSAGE(FATAL_ERROR "Cannot determine target OS. Not defined.") ENDIF() IF(NOT CMDEF_OS_WINDOWS) RETURN() @@ -404,7 +408,7 @@ FUNCTION(_CMDEF_ENV_SET_DESCRIPTION) ) SET(CMDEF_ENV_DESCRIPTION_COPYRIGHT "${CMDEF_ENV_DESCRIPTION_COMPANY_NAME}" CACHE STRING - "Copyrigth which will be added to binaries" + "Copyright which will be added to binaries" ) ENDFUNCTION() @@ -429,17 +433,15 @@ FUNCTION(_CMDEF_ENV_GET_ARCH arch) RETURN() ENDIF() IF(CMDEF_OS_LINUX) - FIND_PROGRAM(CMDEF_UNAME uname REQUIRED) - EXECUTE_PROCESS(COMMAND "${CMDEF_UNAME}" -m - OUTPUT_VARIABLE _arch - RESULT_VARIABLE result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF(NOT (result EQUAL 0)) - MESSAGE(FATAL_ERROR "Cannot determine architecture! Set up CMDEF_ARCHITECTURE manually or repair uname") - ENDIF() + SET(_arch "${CMAKE_SYSTEM_PROCESSOR}") STRING(REGEX REPLACE "[^a-zA-Z0-9.]" "-" _arch_mapped "${_arch}") STRING(TOLOWER "${_arch_mapped}" _arch_normalized) + IF(NOT _arch_normalized) + MESSAGE(FATAL_ERROR "Cannot determine system architecture." + " It seems the system has system arch set to empty or invalid string." + " Consult os-release file." + ) + ENDIF() SET(${arch} "${_arch_normalized}" PARENT_SCOPE) RETURN() ENDIF() @@ -447,6 +449,7 @@ FUNCTION(_CMDEF_ENV_GET_ARCH arch) ENDFUNCTION() + ## Helper # # Determine distribution ID @@ -465,17 +468,15 @@ FUNCTION(_CMDEF_ENV_GET_DISTRO_ID distro_id) RETURN() ENDIF() IF(CMDEF_OS_LINUX) - FIND_PROGRAM(CMDEF_LSB_RELEASE lsb_release REQUIRED) - EXECUTE_PROCESS(COMMAND "${CMDEF_LSB_RELEASE}" -i -s - OUTPUT_VARIABLE _distro_id - RESULT_VARIABLE result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF(NOT (result EQUAL 0)) - MESSAGE(FATAL_ERROR "Cannot determine distro ID! Set up CMDEF_DISTRO_ID manually or repair lsb_release") - ENDIF() + CMAKE_HOST_SYSTEM_INFORMATION(RESULT _distro_id QUERY DISTRIB_ID) STRING(REGEX REPLACE "[^a-zA-Z0-9.]" "-" _distro_id_mapped "${_distro_id}") STRING(TOLOWER "${_distro_id_mapped}" _distro_id_normalized) + IF(NOT _distro_id_normalized) + MESSAGE(FATAL_ERROR "Cannot determine Distro ID." + " It seems the system has Distro ID set to empty or invalid string." + " Consult os-release file." + ) + ENDIF() SET(${distro_id} "${_distro_id_normalized}" PARENT_SCOPE) RETURN() ENDIF() @@ -502,17 +503,15 @@ FUNCTION(_CMDEF_ENV_GET_DISTRO_VERSION_ID version_id) RETURN() ENDIF() IF(CMDEF_OS_LINUX) - FIND_PROGRAM(CMDEF_LSB_RELEASE lsb_release REQUIRED) - EXECUTE_PROCESS(COMMAND "${CMDEF_LSB_RELEASE}" -r -s - OUTPUT_VARIABLE _version_id - RESULT_VARIABLE result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF(NOT (result EQUAL 0)) - MESSAGE(FATAL_ERROR "Cannot determine version ID! Set up CMDEF_DISTRO_VERSION_ID manually or repair lsb_release") - ENDIF() + CMAKE_HOST_SYSTEM_INFORMATION(RESULT _version_id QUERY DISTRIB_VERSION_ID) STRING(REGEX REPLACE "[^a-zA-Z0-9.]" "-" _version_id_mapped "${_version_id}") STRING(TOLOWER "${_version_id_mapped}" _version_id_normalized) + IF(NOT _version_id_normalized) + MESSAGE(FATAL_ERROR "Cannot determine Distro Version ID." + " It seems the system has Distro Version ID set to empty or invalid string." + " Consult os-release file." + ) + ENDIF() SET(${version_id} "${_version_id_normalized}" PARENT_SCOPE) RETURN() ENDIF() diff --git a/system_modules/CMDEF_LINK_OPTION.cmake b/system_modules/CMDEF_LINK_OPTION.cmake index 20e4b91..7f51cfa 100644 --- a/system_modules/CMDEF_LINK_OPTION.cmake +++ b/system_modules/CMDEF_LINK_OPTION.cmake @@ -21,7 +21,7 @@ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMDEF_ADD_LIBRARY.cmake) # to each BUILD_TYPE # # LANG - array, if specified must be one of CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to ADD_LINK_OPTIONS # by generator_expression $<:${option}> @@ -78,20 +78,19 @@ ENDFUNCTION() # to each BUILD_TYPE # # LANG - array, if specified must be one of CMDEF_SUPPORTED_LANG_LIST. -# If not specified no exact languege is select +# If not specified no exact language is select # # Each definition is passed to ADD_LINK_OPTIONS # by generator_expression $<:${option}> # -# VISIBLITY is passed to visiblity section of TARGET_LINK_OPTIONS. -# If no visiblity specified than visiblity is omitted +# VISIBILITY is passed to visibility section of TARGET_LINK_OPTIONS. # # ( # TARGET # [LANG M] # [ALL ] # [ ]{1,} -# [VISIBLITY ] +# [VISIBILITY ] # ) # FUNCTION(CMDEF_LINK_OPTIONS_TARGET) @@ -101,9 +100,10 @@ FUNCTION(CMDEF_LINK_OPTIONS_TARGET) ${CMDEF_BUILD_TYPE_LIST_UPPERCASE} ONE_VALUE TARGET - VISIBLITY + VISIBILITY REQUIRED TARGET + VISIBILITY P_ARGN ${ARGN} ) @@ -126,9 +126,9 @@ FUNCTION(CMDEF_LINK_OPTIONS_TARGET) SET(option ${${build_type_var}}) SET(condition $,$>) SET(link_options $<${condition}:${option}>) - TARGET_LINK_OPTIONS(${original_target_name} ${__VISIBLITY} ${link_options}) + TARGET_LINK_OPTIONS(${original_target_name} ${__VISIBILITY} ${link_options}) ELSE() - TARGET_LINK_OPTIONS(${original_target_name} ${__VISIBLITY} $<$:${${build_type_var}}>) + TARGET_LINK_OPTIONS(${original_target_name} ${__VISIBILITY} $<$:${${build_type_var}}>) ENDIF() ENDFOREACH() ENDFUNCTION() diff --git a/system_modules/CMDEF_PACKAGE.cmake b/system_modules/CMDEF_PACKAGE.cmake index 3857fea..c2107d2 100644 --- a/system_modules/CMDEF_PACKAGE.cmake +++ b/system_modules/CMDEF_PACKAGE.cmake @@ -81,6 +81,7 @@ FUNCTION(CMDEF_PACKAGE) CMDEF_ADD_LIBRARY_CHECK(${__MAIN_TARGET} cmdef_library) CMDEF_ADD_EXECUTABLE_CHECK(${__MAIN_TARGET} cmdef_executable) + CMUTIL_VERSION_CHECK(${__VERSION}) SET(CMDEF_PACKAGE_TARGETS_TO_INCLUDE) IF(DEFINED cmdef_library OR DEFINED cmdef_executable) @@ -193,7 +194,7 @@ FUNCTION(_CMDEF_PACKAGE_FIND_AND_CHECK_DEPENDENCIES) FOREACH (dependency IN LISTS dependencies) _CMDEF_PACKAGE_CHECK_DEPENDENCIES( LIBRARY ${dependency} - __ALREADY_LINKED_LIBS ${dependencies} + ALREADY_LINKED_LIBS ${dependencies} ) ENDFOREACH () _CMDEF_PACKAGE_CHECK_IF_DEPENDENCIES_INSTALLED_BY_CMDEF( @@ -251,11 +252,11 @@ ENDFUNCTION() # HELPER # Used for checking transitive dependencies of the main target. # All those dependencies should be IMPORTED or linked directly to the main target. -# Warns if the LIBRARY is not IMPORTED and is not in __ALREADY_LINKED_LIBS. +# Warns if the LIBRARY is not IMPORTED and is not in ALREADY_LINKED_LIBS. # # ( # LIBRARY -# __ALREADY_LINKED_LIBS M +# ALREADY_LINKED_LIBS M # ) # FUNCTION(_CMDEF_PACKAGE_CHECK_DEPENDENCIES) @@ -263,10 +264,10 @@ FUNCTION(_CMDEF_PACKAGE_CHECK_DEPENDENCIES) ONE_VALUE LIBRARY MULTI_VALUE - __ALREADY_LINKED_LIBS + ALREADY_LINKED_LIBS REQUIRED LIBRARY - __ALREADY_LINKED_LIBS + ALREADY_LINKED_LIBS P_ARGN ${ARGN} ) GET_TARGET_PROPERTY(linked_interfaces ${__LIBRARY} INTERFACE_LINK_LIBRARIES) @@ -283,7 +284,7 @@ FUNCTION(_CMDEF_PACKAGE_CHECK_DEPENDENCIES) CONTINUE() ENDIF () IF (NOT "${linked_lib}" IN_LIST ____ALREADY_LINKED_LIBS) - MESSAGE(WARNING "Library ${linked_lib} is a dependency of ${__LIBRARY}, but is a NOT IMPORTED target and it is not direct dependency of ${__MAIN_TARGET}") + MESSAGE(WARNING "Library ${linked_lib} is a dependency of ${__LIBRARY}, but is NOT an IMPORTED target and it is not direct dependency of ${__MAIN_TARGET}. Dependency ${__LIBRARY} should be linked directly to ${__MAIN_TARGET} instead if it is intended to be exported with the package.") ENDIF () ENDFOREACH () ENDFUNCTION() diff --git a/system_modules/CMDEF_RESOURCE.cmake b/system_modules/CMDEF_RESOURCE.cmake index 9fd0aca..ef9f0d8 100644 --- a/system_modules/CMDEF_RESOURCE.cmake +++ b/system_modules/CMDEF_RESOURCE.cmake @@ -1,6 +1,6 @@ ## Main # -# Manage resources for binaries. Specialy for Windows. +# Manage resources for binaries. Specially for Windows. # INCLUDE_GUARD(GLOBAL) @@ -17,7 +17,7 @@ FIND_PACKAGE(CMLIB REQUIRED) # RESOURCE_FILE is absolute path to Resource file # # DEFINITIONS is list of key-value pairs which is treated as -# definitons for cmd line command which process RESOURCE_FILE +# definitions for cmd line command which process RESOURCE_FILE # # ( # RESOURCE_TARGET diff --git a/test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt new file mode 100644 index 0000000..5e40a4f --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt @@ -0,0 +1,53 @@ +## Main +# +# Test CMDEF_ADD_EXECUTABLE function +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../CMDEFConfig.cmake") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/minimal_executable") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/executable_with_includes") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/custom_output_name") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/check_function") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/debug_suffix_build_type") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/generator_expression_suffix") + +IF(CMDEF_OS_WINDOWS) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/win32_flag") + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/windows_msvc_runtime") + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/windows_resource_generation") +ENDIF() + +IF(CMDEF_OS_MACOS) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/macos_bundle") +ENDIF() + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/multiple_sources") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/all_parameters") + +TEST_RUN_AND_CHECK_OUTPUT("test_cases/missing_target_error" + FATAL_ERROR_MESSAGE "Key 'TARGET' is not defined" +) + +TEST_RUN_AND_CHECK_OUTPUT("test_cases/missing_sources_error" + FATAL_ERROR_MESSAGE "Key 'SOURCES' is not defined" +) + +TEST_RUN_AND_CHECK_OUTPUT("test_cases/missing_version_error" + FATAL_ERROR_MESSAGE "Key 'VERSION' is not defined" +) + +TEST_RUN_AND_CHECK_OUTPUT("test_cases/invalid_target_name_warning" + WARNING_MESSAGE "Target name contains separator:" +) + +TEST_RUN_AND_CHECK_OUTPUT("test_cases/invalid_version_error" + FATAL_ERROR_MESSAGE "not in valid format" +) diff --git a/test/CMDEF_ADD_EXECUTABLE/README.md b/test/CMDEF_ADD_EXECUTABLE/README.md new file mode 100644 index 0000000..58f386e --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/README.md @@ -0,0 +1,27 @@ +# CMDEF_ADD_EXECUTABLE Tests + +Unit tests for the `CMDEF_ADD_EXECUTABLE` function. + +## Directory Structure + +### `shared_sources/` + +Contains reusable test resources: +- C++ source files and headers +- Windows resource files +- Test helper macros and configuration + +### `test_cases/` + +Individual test cases covering: +- Basic executable creation and parameters +- Multiconfig generator support (Debug/Release/Multiconfig variants) +- Platform-specific features (WIN32, MACOS_BUNDLE, MSVC runtime, resources) +- Error conditions and parameter validation + +## Usage + +Run all CMDEF_ADD_EXECUTABLE tests: +```bash +cmake . +``` \ No newline at end of file diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h b/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h new file mode 100644 index 0000000..fcbfdcd --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +std::string get_platform_name(); +bool is_debug_build(); diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h b/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h new file mode 100644 index 0000000..a07c1de --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +std::string get_version_string(); +bool run_tests(); diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake b/test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake new file mode 100644 index 0000000..f71305b --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake @@ -0,0 +1,14 @@ +## Shared Sources Configuration +# +# Defines common paths for CMDEF_ADD_EXECUTABLE test resources +# +# This file provides standardized variables for accessing shared test resources +# across all CMDEF_ADD_EXECUTABLE test cases. +# + +# Define shared test resource paths +SET(TEST_RESOURCES_DIR "${CMAKE_CURRENT_LIST_DIR}") +SET(MAIN_SOURCE_FILE "${TEST_RESOURCES_DIR}/src/main.cpp") +SET(UTILS_SOURCE_FILE "${TEST_RESOURCES_DIR}/src/utils.cpp") +SET(PLATFORM_UTILS_SOURCE_FILE "${TEST_RESOURCES_DIR}/src/platform_utils.cpp") +SET(EXECUTABLE_INCLUDE_DIR "${TEST_RESOURCES_DIR}/include") diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp new file mode 100644 index 0000000..bb96e9e --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp @@ -0,0 +1,17 @@ +#include "utils.h" +#include "platform_utils.h" +#include + +int main() { + std::cout << "CMDEF Test Executable" << std::endl; + std::cout << "Version: " << get_version_string() << std::endl; + std::cout << "Platform: " << get_platform_name() << std::endl; + + if (run_tests()) { + std::cout << "All tests passed" << std::endl; + return 0; + } else { + std::cout << "Some tests failed" << std::endl; + return 1; + } +} diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp new file mode 100644 index 0000000..07d0f94 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp @@ -0,0 +1,22 @@ +#include "platform_utils.h" +#include + +std::string get_platform_name() { +#ifdef _WIN32 + return "Windows"; +#elif __APPLE__ + return "macOS"; +#elif __linux__ + return "Linux"; +#else + return "Unknown"; +#endif +} + +bool is_debug_build() { +#ifdef _DEBUG + return true; +#else + return false; +#endif +} diff --git a/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp new file mode 100644 index 0000000..91942e3 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp @@ -0,0 +1,10 @@ +#include "utils.h" +#include + +std::string get_version_string() { + return "1.0.0"; +} + +bool run_tests() { + return true; +} diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt new file mode 100644 index 0000000..291c36f --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt @@ -0,0 +1,182 @@ +## Main +# +# Test executable creation with all optional parameters +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_ALL_PARAMS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test executable creation with all optional parameters in Debug build type. +# +# Creates an executable with all possible parameters and CMAKE_BUILD_TYPE set to Debug +# and verifies debug suffix is applied to custom output name. +# +# () +# +FUNCTION(TEST_ALL_PARAMETERS_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testallparamsexedebug + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 3.2.1 + OUTPUT_NAME "comprehensive-test-executable" + INCLUDE_DIRECTORIES + "${EXECUTABLE_INCLUDE_DIR}" + WIN32 ON + MACOS_BUNDLE ON + ) + + IF(NOT TARGET testallparamsexedebug) + MESSAGE(FATAL_ERROR "Target 'testallparamsexedebug' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testallparamsexedebug CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testallparamsexedebug OUTPUT_NAME) + SET(expected_output_name "comprehensive-test-executable${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testallparamsexedebug INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(target_type testallparamsexedebug TYPE) + IF(NOT target_type STREQUAL "EXECUTABLE") + MESSAGE(FATAL_ERROR "Target type should be EXECUTABLE, got: ${target_type}") + ENDIF() + + GET_TARGET_PROPERTY(target_sources testallparamsexedebug SOURCES) + LIST(LENGTH target_sources source_count) + IF(source_count LESS 3) + MESSAGE(FATAL_ERROR "Expected at least 3 source files, got: ${source_count}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with all optional parameters in Release build type. +# +# Creates an executable with all possible parameters and CMAKE_BUILD_TYPE set to Release +# and verifies no debug suffix is applied to custom output name. +# +# () +# +FUNCTION(TEST_ALL_PARAMETERS_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testallparamsexerelease + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 3.2.1 + OUTPUT_NAME "comprehensive-test-executable" + INCLUDE_DIRECTORIES + "${EXECUTABLE_INCLUDE_DIR}" + WIN32 ON + MACOS_BUNDLE ON + ) + + IF(NOT TARGET testallparamsexerelease) + MESSAGE(FATAL_ERROR "Target 'testallparamsexerelease' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testallparamsexerelease CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testallparamsexerelease OUTPUT_NAME) + SET(expected_output_name "comprehensive-test-executable") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testallparamsexerelease INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(target_type testallparamsexerelease TYPE) + IF(NOT target_type STREQUAL "EXECUTABLE") + MESSAGE(FATAL_ERROR "Target type should be EXECUTABLE, got: ${target_type}") + ENDIF() + + GET_TARGET_PROPERTY(target_sources testallparamsexerelease SOURCES) + LIST(LENGTH target_sources source_count) + IF(source_count LESS 3) + MESSAGE(FATAL_ERROR "Expected at least 3 source files, got: ${source_count}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with all optional parameters for multiconfig generators. +# +# Creates an executable with all possible parameters and CMAKE_BUILD_TYPE unset +# and verifies generator expressions are used with custom output name. +# +# () +# +FUNCTION(TEST_ALL_PARAMETERS_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testallparamsexemulti + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 3.2.1 + OUTPUT_NAME "comprehensive-test-executable" + INCLUDE_DIRECTORIES + "${EXECUTABLE_INCLUDE_DIR}" + WIN32 ON + MACOS_BUNDLE ON + ) + + IF(NOT TARGET testallparamsexemulti) + MESSAGE(FATAL_ERROR "Target 'testallparamsexemulti' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testallparamsexemulti CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testallparamsexemulti OUTPUT_NAME) + SET(expected_pattern "^comprehensive-test-executable\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testallparamsexemulti INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(target_type testallparamsexemulti TYPE) + IF(NOT target_type STREQUAL "EXECUTABLE") + MESSAGE(FATAL_ERROR "Target type should be EXECUTABLE, got: ${target_type}") + ENDIF() + + GET_TARGET_PROPERTY(target_sources testallparamsexemulti SOURCES) + LIST(LENGTH target_sources source_count) + IF(source_count LESS 3) + MESSAGE(FATAL_ERROR "Expected at least 3 source files, got: ${source_count}") + ENDIF() + + MESSAGE(STATUS "All parameters test passed successfully") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_ALL_PARAMETERS_DEBUG() +TEST_ALL_PARAMETERS_RELEASE() +TEST_ALL_PARAMETERS_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt new file mode 100644 index 0000000..03bdba0 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt @@ -0,0 +1,46 @@ +## Main +# +# Test CMDEF_ADD_EXECUTABLE_CHECK function +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_CHECK_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test CMDEF_ADD_EXECUTABLE_CHECK function. +# +# Creates executables and verifies the check function +# correctly identifies CMDEF-created targets. +# +# () +# +FUNCTION(TEST_EXECUTABLE_CHECK_FUNCTION) + CMDEF_ADD_EXECUTABLE( + TARGET testcheckexe + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + ADD_EXECUTABLE(regularcmakeexe "${MAIN_SOURCE_FILE}") + + CMDEF_ADD_EXECUTABLE_CHECK(testcheckexe cmdef_result) + IF(NOT DEFINED cmdef_result) + MESSAGE(FATAL_ERROR "CMDEF_ADD_EXECUTABLE_CHECK failed to identify CMDEF target") + ENDIF() + IF(NOT cmdef_result STREQUAL "testcheckexe") + MESSAGE(FATAL_ERROR "CMDEF_ADD_EXECUTABLE_CHECK returned wrong target name: ${cmdef_result}") + ENDIF() + + CMDEF_ADD_EXECUTABLE_CHECK(regularcmakeexe regular_result) + IF(DEFINED regular_result) + MESSAGE(FATAL_ERROR "CMDEF_ADD_EXECUTABLE_CHECK incorrectly identified regular CMake target") + ENDIF() +ENDFUNCTION() + +TEST_EXECUTABLE_CHECK_FUNCTION() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt new file mode 100644 index 0000000..348a183 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt @@ -0,0 +1,120 @@ +## Main +# +# Test executable creation with custom output name +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_OUTPUT_NAME_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test executable creation with custom output name in Debug build type. +# +# Creates an executable with OUTPUT_NAME parameter and CMAKE_BUILD_TYPE set to Debug +# and verifies debug suffix is applied to custom output name. +# +# () +# +FUNCTION(TEST_CUSTOM_OUTPUT_NAME_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testoutputexedebug + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.5.0 + OUTPUT_NAME "custom-executable-name" + ) + + IF(NOT TARGET testoutputexedebug) + MESSAGE(FATAL_ERROR "Target 'testoutputexedebug' was not created") + ENDIF() + + GET_TARGET_PROPERTY(output_name testoutputexedebug OUTPUT_NAME) + SET(expected_output_name "custom-executable-name${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testoutputexedebug CMDEF_EXECUTABLE TRUE) + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with custom output name in Release build type. +# +# Creates an executable with OUTPUT_NAME parameter and CMAKE_BUILD_TYPE set to Release +# and verifies no debug suffix is applied to custom output name. +# +# () +# +FUNCTION(TEST_CUSTOM_OUTPUT_NAME_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testoutputexerelease + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.5.0 + OUTPUT_NAME "custom-executable-name" + ) + + IF(NOT TARGET testoutputexerelease) + MESSAGE(FATAL_ERROR "Target 'testoutputexerelease' was not created") + ENDIF() + + GET_TARGET_PROPERTY(output_name testoutputexerelease OUTPUT_NAME) + SET(expected_output_name "custom-executable-name") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testoutputexerelease CMDEF_EXECUTABLE TRUE) + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with custom output name for multiconfig generators. +# +# Creates an executable with OUTPUT_NAME parameter and CMAKE_BUILD_TYPE unset +# and verifies generator expressions are used with custom output name. +# +# () +# +FUNCTION(TEST_CUSTOM_OUTPUT_NAME_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testoutputexemulti + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.5.0 + OUTPUT_NAME "custom-executable-name" + ) + + IF(NOT TARGET testoutputexemulti) + MESSAGE(FATAL_ERROR "Target 'testoutputexemulti' was not created") + ENDIF() + + GET_TARGET_PROPERTY(output_name testoutputexemulti OUTPUT_NAME) + SET(expected_pattern "^custom-executable-name\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testoutputexemulti CMDEF_EXECUTABLE TRUE) + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_CUSTOM_OUTPUT_NAME_DEBUG() +TEST_CUSTOM_OUTPUT_NAME_RELEASE() +TEST_CUSTOM_OUTPUT_NAME_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt new file mode 100644 index 0000000..05e810d --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt @@ -0,0 +1,99 @@ +## Main +# +# Test debug suffix with CMAKE_BUILD_TYPE +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_DEBUG_SUFFIX_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test debug suffix application with Debug build type. +# +# Creates executable with CMAKE_BUILD_TYPE set to Debug and verifies +# debug suffix is applied correctly. +# +# () +# +FUNCTION(TEST_DEBUG_SUFFIX_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testdebugsuffixdebug + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testdebugsuffixdebug OUTPUT_NAME) + SET(expected_output_name "testdebugsuffixdebug${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test debug suffix application with Release build type. +# +# Creates executable with CMAKE_BUILD_TYPE set to Release and verifies +# no debug suffix is applied. +# +# () +# +FUNCTION(TEST_DEBUG_SUFFIX_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testdebugsuffixrelease + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testdebugsuffixrelease OUTPUT_NAME) + SET(expected_output_name "testdebugsuffixrelease") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test debug suffix application for multiconfig generators. +# +# Creates executable with CMAKE_BUILD_TYPE unset and verifies +# generator expressions are used for debug suffix. +# +# () +# +FUNCTION(TEST_DEBUG_SUFFIX_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testdebugsuffixmulti + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testdebugsuffixmulti OUTPUT_NAME) + SET(expected_pattern "^testdebugsuffixmulti\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_DEBUG_SUFFIX_DEBUG() +TEST_DEBUG_SUFFIX_RELEASE() +TEST_DEBUG_SUFFIX_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt new file mode 100644 index 0000000..e598eb4 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt @@ -0,0 +1,129 @@ +## Main +# +# Test executable creation with include directories +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_INCLUDES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test executable creation with include directories in Debug build type. +# +# Creates an executable with INCLUDE_DIRECTORIES parameter and CMAKE_BUILD_TYPE set to Debug +# and verifies include directories and debug suffix are set correctly. +# +# () +# +FUNCTION(TEST_EXECUTABLE_WITH_INCLUDES_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testincludesexedebug + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + VERSION 2.1.0 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testincludesexedebug) + MESSAGE(FATAL_ERROR "Target 'testincludesexedebug' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testincludesexedebug CMDEF_EXECUTABLE TRUE) + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testincludesexedebug INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(output_name testincludesexedebug OUTPUT_NAME) + SET(expected_output_name "testincludesexedebug${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with include directories in Release build type. +# +# Creates an executable with INCLUDE_DIRECTORIES parameter and CMAKE_BUILD_TYPE set to Release +# and verifies include directories are set correctly and no debug suffix is applied. +# +# () +# +FUNCTION(TEST_EXECUTABLE_WITH_INCLUDES_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testincludesexerelease + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + VERSION 2.1.0 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testincludesexerelease) + MESSAGE(FATAL_ERROR "Target 'testincludesexerelease' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testincludesexerelease CMDEF_EXECUTABLE TRUE) + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testincludesexerelease INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(output_name testincludesexerelease OUTPUT_NAME) + SET(expected_output_name "testincludesexerelease") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with include directories for multiconfig generators. +# +# Creates an executable with INCLUDE_DIRECTORIES parameter and CMAKE_BUILD_TYPE unset +# and verifies include directories are set correctly and generator expressions are used. +# +# () +# +FUNCTION(TEST_EXECUTABLE_WITH_INCLUDES_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testincludesexemulti + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + VERSION 2.1.0 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testincludesexemulti) + MESSAGE(FATAL_ERROR "Target 'testincludesexemulti' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testincludesexemulti CMDEF_EXECUTABLE TRUE) + TEST_CHECK_TARGET_PROPERTY_CONTAINS(testincludesexemulti INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(output_name testincludesexemulti OUTPUT_NAME) + SET(expected_pattern "^testincludesexemulti\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_EXECUTABLE_WITH_INCLUDES_DEBUG() +TEST_EXECUTABLE_WITH_INCLUDES_RELEASE() +TEST_EXECUTABLE_WITH_INCLUDES_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt new file mode 100644 index 0000000..ba7b1bf --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt @@ -0,0 +1,105 @@ +## Main +# +# Test generator expression debug suffix for multi-config generators +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_GENEX_SUFFIX_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test generator expression debug suffix with Debug build type. +# +# Creates executable with CMAKE_BUILD_TYPE set to Debug and verifies +# direct debug suffix is applied. +# +# () +# +FUNCTION(TEST_GENERATOR_EXPRESSION_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testgenexdebug + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testgenexdebug OUTPUT_NAME) + SET(expected_output_name "testgenexdebug${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "Generator expression Debug test passed with output name: ${output_name}") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test generator expression debug suffix with Release build type. +# +# Creates executable with CMAKE_BUILD_TYPE set to Release and verifies +# no debug suffix is applied. +# +# () +# +FUNCTION(TEST_GENERATOR_EXPRESSION_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testgenexrelease + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testgenexrelease OUTPUT_NAME) + SET(expected_output_name "testgenexrelease") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "Generator expression Release test passed with output name: ${output_name}") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test generator expression debug suffix for multiconfig generators. +# +# Creates executable with CMAKE_BUILD_TYPE unset and verifies +# generator expressions are used for debug suffix. +# +# () +# +FUNCTION(TEST_GENERATOR_EXPRESSION_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testgenexmulti + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testgenexmulti OUTPUT_NAME) + SET(expected_pattern "^testgenexmulti\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "Generator expression multiconfig test passed with output name: ${output_name}") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_GENERATOR_EXPRESSION_DEBUG() +TEST_GENERATOR_EXPRESSION_RELEASE() +TEST_GENERATOR_EXPRESSION_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt new file mode 100644 index 0000000..53b10ef --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt @@ -0,0 +1,18 @@ +## Main +# +# Test warning when target name contains separator +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_INVALID_NAME_WARNING_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_EXECUTABLE( + TARGET "test${CMDEF_ENV_NAME_SEPARATOR}invalid" + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt new file mode 100644 index 0000000..826e3d3 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt @@ -0,0 +1,18 @@ +## Main +# +# Test error when VERSION parameter has invalid format +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_INVALID_VERSION_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_EXECUTABLE( + TARGET test_invalid_version + SOURCES "${MAIN_SOURCE_FILE}" + VERSION "invalid.version.format" +) diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt new file mode 100644 index 0000000..bc09c7d --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt @@ -0,0 +1,48 @@ +## Main +# +# Test MACOS_BUNDLE flag behavior +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MACOS_BUNDLE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test MACOS_BUNDLE flag behavior on different platforms. +# +# Creates executable with MACOS_BUNDLE flag and verifies it's only +# applied when running on macOS platform. +# +# () +# +FUNCTION(TEST_MACOS_BUNDLE_BEHAVIOR) + CMDEF_ADD_EXECUTABLE( + TARGET testbundleexe + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + MACOS_BUNDLE ON + ) + + IF(NOT TARGET testbundleexe) + MESSAGE(FATAL_ERROR "Target 'testbundleexe' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testbundleexe CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(target_type testbundleexe TYPE) + IF(CMDEF_OS_MACOS) + MESSAGE(STATUS "macOS bundle test - target type: ${target_type}") + ELSE() + IF(NOT target_type STREQUAL "EXECUTABLE") + MESSAGE(FATAL_ERROR "Target type should be EXECUTABLE on non-macOS, got: ${target_type}") + ENDIF() + MESSAGE(STATUS "MACOS_BUNDLE flag correctly ignored on non-macOS platform") + ENDIF() +ENDFUNCTION() + +TEST_MACOS_BUNDLE_BEHAVIOR() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt new file mode 100644 index 0000000..4947b03 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt @@ -0,0 +1,117 @@ +## Main +# +# Test minimal executable creation with required parameters only +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MINIMAL_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test minimal executable creation with Debug build type. +# +# Creates an executable with CMAKE_BUILD_TYPE set to Debug +# and verifies debug suffix is applied correctly. +# +# () +# +FUNCTION(TEST_MINIMAL_EXECUTABLE_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testminimalexedebug + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + IF(NOT TARGET testminimalexedebug) + MESSAGE(FATAL_ERROR "Target 'testminimalexedebug' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testminimalexedebug CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testminimalexedebug OUTPUT_NAME) + SET(expected_output_name "testminimalexedebug${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test minimal executable creation with Release build type. +# +# Creates an executable with CMAKE_BUILD_TYPE set to Release +# and verifies no debug suffix is applied. +# +# () +# +FUNCTION(TEST_MINIMAL_EXECUTABLE_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testminimalexerelease + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + IF(NOT TARGET testminimalexerelease) + MESSAGE(FATAL_ERROR "Target 'testminimalexerelease' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testminimalexerelease CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testminimalexerelease OUTPUT_NAME) + SET(expected_output_name "testminimalexerelease") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test minimal executable creation with multiconfig generator support. +# +# Creates an executable with CMAKE_BUILD_TYPE unset to simulate +# multiconfig generators and verifies generator expressions are used. +# +# () +# +FUNCTION(TEST_MINIMAL_EXECUTABLE_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testminimalexemulti + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + IF(NOT TARGET testminimalexemulti) + MESSAGE(FATAL_ERROR "Target 'testminimalexemulti' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testminimalexemulti CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(output_name testminimalexemulti OUTPUT_NAME) + SET(expected_pattern "^testminimalexemulti\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_MINIMAL_EXECUTABLE_DEBUG() +TEST_MINIMAL_EXECUTABLE_RELEASE() +TEST_MINIMAL_EXECUTABLE_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt new file mode 100644 index 0000000..1eeb75e --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt @@ -0,0 +1,17 @@ +## Main +# +# Test error when SOURCES parameter is missing +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MISSING_SOURCES_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_EXECUTABLE( + TARGET test_no_sources + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt new file mode 100644 index 0000000..cb2ac24 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt @@ -0,0 +1,17 @@ +## Main +# +# Test error when TARGET parameter is missing +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MISSING_TARGET_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_EXECUTABLE( + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt new file mode 100644 index 0000000..2596123 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt @@ -0,0 +1,17 @@ +## Main +# +# Test error when VERSION parameter is missing +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MISSING_VERSION_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_EXECUTABLE( + TARGET test_no_version + SOURCES "${MAIN_SOURCE_FILE}" +) diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt new file mode 100644 index 0000000..2156d5c --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt @@ -0,0 +1,180 @@ +## Main +# +# Test executable creation with multiple source files +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MULTIPLE_SOURCES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test executable creation with multiple source files in Debug build type. +# +# Creates an executable with multiple C++ source files and CMAKE_BUILD_TYPE set to Debug +# and verifies all sources are added correctly and debug suffix is applied. +# +# () +# +FUNCTION(TEST_MULTIPLE_SOURCES_DEBUG) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET testmultisourcesexedebug + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 1.2.3 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testmultisourcesexedebug) + MESSAGE(FATAL_ERROR "Target 'testmultisourcesexedebug' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testmultisourcesexedebug CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(target_sources testmultisourcesexedebug SOURCES) + + SET(expected_sources + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + ) + + FOREACH(expected_source IN LISTS expected_sources) + LIST(FIND target_sources "${expected_source}" source_index) + IF(source_index EQUAL -1) + MESSAGE(FATAL_ERROR "Expected source file not found: ${expected_source}") + ENDIF() + ENDFOREACH() + + GET_TARGET_PROPERTY(output_name testmultisourcesexedebug OUTPUT_NAME) + SET(expected_output_name "testmultisourcesexedebug${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "All expected source files found in target") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with multiple source files in Release build type. +# +# Creates an executable with multiple C++ source files and CMAKE_BUILD_TYPE set to Release +# and verifies all sources are added correctly and no debug suffix is applied. +# +# () +# +FUNCTION(TEST_MULTIPLE_SOURCES_RELEASE) + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET testmultisourcesexerelease + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 1.2.3 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testmultisourcesexerelease) + MESSAGE(FATAL_ERROR "Target 'testmultisourcesexerelease' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testmultisourcesexerelease CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(target_sources testmultisourcesexerelease SOURCES) + + SET(expected_sources + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + ) + + FOREACH(expected_source IN LISTS expected_sources) + LIST(FIND target_sources "${expected_source}" source_index) + IF(source_index EQUAL -1) + MESSAGE(FATAL_ERROR "Expected source file not found: ${expected_source}") + ENDIF() + ENDFOREACH() + + GET_TARGET_PROPERTY(output_name testmultisourcesexerelease OUTPUT_NAME) + SET(expected_output_name "testmultisourcesexerelease") + + IF(NOT output_name STREQUAL expected_output_name) + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME '${expected_output_name}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "All expected source files found in target") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable creation with multiple source files for multiconfig generators. +# +# Creates an executable with multiple C++ source files and CMAKE_BUILD_TYPE unset +# and verifies all sources are added correctly and generator expressions are used. +# +# () +# +FUNCTION(TEST_MULTIPLE_SOURCES_MULTICONFIG) + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_EXECUTABLE( + TARGET testmultisourcesexemulti + SOURCES + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + VERSION 1.2.3 + INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" + ) + + IF(NOT TARGET testmultisourcesexemulti) + MESSAGE(FATAL_ERROR "Target 'testmultisourcesexemulti' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testmultisourcesexemulti CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(target_sources testmultisourcesexemulti SOURCES) + + SET(expected_sources + "${MAIN_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + "${PLATFORM_UTILS_SOURCE_FILE}" + ) + + FOREACH(expected_source IN LISTS expected_sources) + LIST(FIND target_sources "${expected_source}" source_index) + IF(source_index EQUAL -1) + MESSAGE(FATAL_ERROR "Expected source file not found: ${expected_source}") + ENDIF() + ENDFOREACH() + + GET_TARGET_PROPERTY(output_name testmultisourcesexemulti OUTPUT_NAME) + SET(expected_pattern "^testmultisourcesexemulti\\$<\\$:${CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX}>$") + + IF(NOT output_name MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected OUTPUT_NAME to match pattern '${expected_pattern}' but got '${output_name}'") + ENDIF() + + MESSAGE(STATUS "All expected source files found in target") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_MULTIPLE_SOURCES_DEBUG() +TEST_MULTIPLE_SOURCES_RELEASE() +TEST_MULTIPLE_SOURCES_MULTICONFIG() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt new file mode 100644 index 0000000..06cad2f --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt @@ -0,0 +1,48 @@ +## Main +# +# Test WIN32 flag behavior +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_WIN32_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test WIN32 flag behavior on different platforms. +# +# Creates executable with WIN32 flag and verifies it's only +# applied when running on Windows platform. +# +# () +# +FUNCTION(TEST_WIN32_FLAG_BEHAVIOR) + CMDEF_ADD_EXECUTABLE( + TARGET testwin32exe + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + WIN32 ON + ) + + IF(NOT TARGET testwin32exe) + MESSAGE(FATAL_ERROR "Target 'testwin32exe' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testwin32exe CMDEF_EXECUTABLE TRUE) + + GET_TARGET_PROPERTY(target_type testwin32exe TYPE) + IF(NOT target_type STREQUAL "EXECUTABLE") + MESSAGE(FATAL_ERROR "Target type should be EXECUTABLE, got: ${target_type}") + ENDIF() + + GET_TARGET_PROPERTY(wintype testwin32exe WIN32_EXECUTABLE) + IF(NOT wintype) + MESSAGE(FATAL_ERROR "WIN32 property should be set, got: ${wintype}") + ENDIF() +ENDFUNCTION() + +TEST_WIN32_FLAG_BEHAVIOR() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt new file mode 100644 index 0000000..dba7115 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt @@ -0,0 +1,105 @@ +## Main +# +# Test Windows MSVC runtime library settings +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_MSVC_RUNTIME_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test MSVC runtime library property with CMDEF_WINDOWS_STATIC_RUNTIME=ON. +# +# MSVC runtime always uses generator expressions regardless of CMAKE_BUILD_TYPE +# because runtime selection must be build-time dependent for multiconfig generators. +# +# () +# +FUNCTION(TEST_WINDOWS_MSVC_RUNTIME_STATIC_ON) + + CACHE_VAR_FORCE_SET(CMDEF_WINDOWS_STATIC_RUNTIME ON) + + CMDEF_ADD_EXECUTABLE( + TARGET testmsvcruntimestaticon + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(msvc_runtime testmsvcruntimestaticon MSVC_RUNTIME_LIBRARY) + + SET(expected_pattern "^MultiThreaded\\$<\\$:Debug>$") + + IF(NOT msvc_runtime MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected MSVC runtime to match pattern '${expected_pattern}' but got '${msvc_runtime}'") + ENDIF() + + CACHE_VAR_RESTORE(CMDEF_WINDOWS_STATIC_RUNTIME) +ENDFUNCTION() + +## +# Test MSVC runtime library property with CMDEF_WINDOWS_STATIC_RUNTIME=OFF. +# +# MSVC runtime always uses generator expressions regardless of CMAKE_BUILD_TYPE +# because runtime selection must be build-time dependent for multiconfig generators. +# +# () +# +FUNCTION(TEST_WINDOWS_MSVC_RUNTIME_STATIC_OFF) + + CACHE_VAR_FORCE_SET(CMDEF_WINDOWS_STATIC_RUNTIME OFF) + + CMDEF_ADD_EXECUTABLE( + TARGET testmsvcruntimestaticoff + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(msvc_runtime testmsvcruntimestaticoff MSVC_RUNTIME_LIBRARY) + + SET(expected_pattern "^MultiThreaded\\$<\\$:Debug>DLL$") + + IF(NOT msvc_runtime MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected MSVC runtime to match pattern '${expected_pattern}' but got '${msvc_runtime}'") + ENDIF() + + CACHE_VAR_RESTORE(CMDEF_WINDOWS_STATIC_RUNTIME) +ENDFUNCTION() + +## +# Test MSVC runtime library property with undefined CMDEF_WINDOWS_STATIC_RUNTIME. +# +# Tests behavior when CMDEF_WINDOWS_STATIC_RUNTIME is not defined, +# which should default to dynamic runtime (DLL). +# +# () +# +FUNCTION(TEST_WINDOWS_MSVC_RUNTIME_UNDEFINED) + + CACHE_VAR_FORCE_UNSET(CMDEF_WINDOWS_STATIC_RUNTIME) + + CMDEF_ADD_EXECUTABLE( + TARGET testmsvcruntimeundef + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(msvc_runtime testmsvcruntimeundef MSVC_RUNTIME_LIBRARY) + + SET(expected_pattern "^MultiThreaded\\$<\\$:Debug>DLL$") + + IF(NOT msvc_runtime MATCHES "${expected_pattern}") + MESSAGE(FATAL_ERROR "Expected MSVC runtime to match pattern '${expected_pattern}' but got '${msvc_runtime}'") + ENDIF() + + CACHE_VAR_RESTORE(CMDEF_WINDOWS_STATIC_RUNTIME) +ENDFUNCTION() + +TEST_WINDOWS_MSVC_RUNTIME_STATIC_ON() +TEST_WINDOWS_MSVC_RUNTIME_STATIC_OFF() +TEST_WINDOWS_MSVC_RUNTIME_UNDEFINED() diff --git a/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt b/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt new file mode 100644 index 0000000..f5d07c7 --- /dev/null +++ b/test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt @@ -0,0 +1,50 @@ +## Main +# +# Test Windows resource file generation +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_RESOURCE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +## +# Test Windows resource file generation with auto-generated resources. +# +# Creates executable on Windows and verifies auto-generated resource file +# is created and added to target sources. +# Auto generate dreaource file contains version, author and other win32 app meta-information. +# +# () +# +FUNCTION(TEST_WINDOWS_RESOURCE_IN_SOURCES) + + CMDEF_ADD_EXECUTABLE( + TARGET testresourceautoexe + SOURCES + "${MAIN_SOURCE_FILE}" + VERSION 2.5.1 + ) + + GET_TARGET_PROPERTY(target_sources testresourceautoexe SOURCES) + + SET(resource_found FALSE) + FOREACH(source IN LISTS target_sources) + IF(source MATCHES ".*\\.rc$") + SET(resource_found TRUE) + IF(NOT EXISTS "${source}") + MESSAGE(FATAL_ERROR "Auto-generated resource file does not exist: ${source}") + ENDIF() + BREAK() + ENDIF() + ENDFOREACH() + IF(NOT resource_found) + MESSAGE(FATAL_ERROR "No auto-generated resource file found in target sources") + ENDIF() +ENDFUNCTION() + +TEST_WINDOWS_RESOURCE_IN_SOURCES() diff --git a/test/CMDEF_ADD_LIBRARY/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/CMakeLists.txt new file mode 100644 index 0000000..2dcec2e --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/CMakeLists.txt @@ -0,0 +1,31 @@ +## Main +# +# Test CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF-ADD-LIBRARY-TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../CMDEFConfig.cmake") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/interface_library") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/check_function") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/generator_expressions") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/multiple_include_directories") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/version_validation") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/parameter_validation") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/cache_variables_validation") + +IF(CMDEF_OS_WINDOWS) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/windows_specific") +ENDIF() + +IF(CMDEF_OS_POSIX) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/posix_specific") + TEST_RUN_AND_CHECK_OUTPUT("test_cases/soversion" + FATAL_ERROR_MESSAGE "SOVERSION should not be set for static libraries, got: 1.0.0" + ) +ENDIF() diff --git a/test/CMDEF_ADD_LIBRARY/README.md b/test/CMDEF_ADD_LIBRARY/README.md new file mode 100644 index 0000000..0ff8e9b --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/README.md @@ -0,0 +1,26 @@ +# CMDEF_ADD_LIBRARY Tests + +Unit tests for the `CMDEF_ADD_LIBRARY` function. + +## Directory Structure + +### `shared_sources/` + +Contains reusable test resources: +- C++ source files and headers +- Test helper macros and configuration + +### `test_cases/` + +Individual test cases covering: +- Basic library creation (interface, shared, static) +- Multiconfig generator support (Debug/Release/Multiconfig variants) +- Platform-specific features (Windows MSVC runtime, POSIX SOVERSION) +- Error conditions and parameter validation + +## Usage + +Run all CMDEF_ADD_LIBRARY tests: +```bash +cmake . +``` diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h new file mode 100644 index 0000000..093eadb --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h @@ -0,0 +1,3 @@ +#pragma once + +void library_function(); diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h new file mode 100644 index 0000000..303d74d --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h @@ -0,0 +1,3 @@ +#pragma once + +void function1(); diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h new file mode 100644 index 0000000..76f616f --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h @@ -0,0 +1,3 @@ +#pragma once + +void function2(); diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake new file mode 100644 index 0000000..3754472 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake @@ -0,0 +1,10 @@ +# Multiple include sources configuration for CMDEF_ADD_LIBRARY tests + +SET(MULTIPLE_INCLUDE_RESOURCES_DIR "${CMAKE_CURRENT_LIST_DIR}") + +SET(LIBRARY_SOURCE_FILE "${MULTIPLE_INCLUDE_RESOURCES_DIR}/src/library.cpp") +SET(UTILS_SOURCE_FILE "${MULTIPLE_INCLUDE_RESOURCES_DIR}/src/utils.cpp") + +SET(LIBRARY_INCLUDE_DIR "${MULTIPLE_INCLUDE_RESOURCES_DIR}/include") +SET(LIBRARY_INCLUDE1_DIR "${MULTIPLE_INCLUDE_RESOURCES_DIR}/include1") +SET(LIBRARY_INCLUDE2_DIR "${MULTIPLE_INCLUDE_RESOURCES_DIR}/include2") diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp new file mode 100644 index 0000000..cd22af3 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp @@ -0,0 +1,6 @@ +#include "library.h" +#include + +void library_function() { + std::cout << "Multiple include test library function called" << std::endl; +} diff --git a/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp new file mode 100644 index 0000000..9901357 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp @@ -0,0 +1,5 @@ +#include "library.h" + +int utils_function() { + return 42; +} diff --git a/test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h b/test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h new file mode 100644 index 0000000..a848acb --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h @@ -0,0 +1,12 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void library_function(); +int library_add(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h b/test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h new file mode 100644 index 0000000..0e163d9 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +std::string get_library_name(); +bool validate_input(int value); diff --git a/test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake b/test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake new file mode 100644 index 0000000..72e9740 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake @@ -0,0 +1,13 @@ +## Shared Sources Configuration +# +# Defines common paths for CMDEF_ADD_LIBRARY test resources +# +# This file provides standardized variables for accessing shared test resources +# across all CMDEF_ADD_LIBRARY test cases. +# + +# Define shared test resource paths +SET(TEST_RESOURCES_DIR "${CMAKE_CURRENT_LIST_DIR}") +SET(LIBRARY_SOURCE_FILE "${TEST_RESOURCES_DIR}/src/library.cpp") +SET(UTILS_SOURCE_FILE "${TEST_RESOURCES_DIR}/src/utils.cpp") +SET(LIBRARY_INCLUDE_DIR "${TEST_RESOURCES_DIR}/include") diff --git a/test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp b/test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp new file mode 100644 index 0000000..6363fbf --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp @@ -0,0 +1,10 @@ +#include "library.h" +#include + +void library_function() { + std::cout << "Library function called" << std::endl; +} + +int library_add(int a, int b) { + return a + b; +} diff --git a/test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp b/test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp new file mode 100644 index 0000000..db6788b --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp @@ -0,0 +1,10 @@ +#include "utils.h" +#include + +std::string get_library_name() { + return "CMDEF Test Library"; +} + +bool validate_input(int value) { + return value >= 0; +} diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt new file mode 100644 index 0000000..610f32e --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt @@ -0,0 +1,195 @@ +## Main +# +# Test CMDEF_ADD_LIBRARY integration with CMDEF cache variables +# +# This test validates that CMDEF_ADD_LIBRARY properly uses CMDEF_* cache variables +# from CMDEF_ENV when creating libraries and setting target properties. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_INTEGRATION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test CMDEF_ADD_LIBRARY integration with cache variables. +# +# Creates libraries and verifies that CMDEF cache variables are properly +# used in the library creation process and target properties. +# +# () +# +FUNCTION(TEST_CACHE_VARIABLES_INTEGRATION) + MESSAGE(STATUS "Testing CMDEF_ADD_LIBRARY integration with cache variables") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testcachevars + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testcachevars-shared) + MESSAGE(FATAL_ERROR "Library target 'testcachevars-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(output_name testcachevars-shared OUTPUT_NAME) + IF(NOT output_name MATCHES "^${CMDEF_LIBRARY_PREFIX}") + MESSAGE(FATAL_ERROR "OUTPUT_NAME should start with CMDEF_LIBRARY_PREFIX '${CMDEF_LIBRARY_PREFIX}', got: ${output_name}") + ENDIF() + + GET_TARGET_PROPERTY(suffix testcachevars-shared SUFFIX) + IF(NOT suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}") + MESSAGE(FATAL_ERROR "SUFFIX should match CMDEF_LIBRARY_NAME_SUFFIX_SHARED '${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}', got: ${suffix}") + ENDIF() + + GET_TARGET_PROPERTY(prefix testcachevars-shared PREFIX) + IF(NOT prefix STREQUAL "") + MESSAGE(FATAL_ERROR "PREFIX should be empty for CMDEF libraries, got: '${prefix}'") + ENDIF() + + GET_TARGET_PROPERTY(cmdef_lib testcachevars-shared CMDEF_LIBRARY) + IF(NOT cmdef_lib STREQUAL "SHARED") + MESSAGE(FATAL_ERROR "CMDEF_LIBRARY property should be 'SHARED', got: ${cmdef_lib}") + ENDIF() + + GET_TARGET_PROPERTY(install_dirs testcachevars-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + IF(NOT install_dirs) + MESSAGE(FATAL_ERROR "CMDEF_INSTALL_INCLUDE_DIRECTORIES should be set") + ENDIF() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testcachevars + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testcachevars-static) + MESSAGE(FATAL_ERROR "Static library target 'testcachevars-static' was not created") + ENDIF() + + GET_TARGET_PROPERTY(static_suffix testcachevars-static SUFFIX) + IF(NOT static_suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}") + MESSAGE(FATAL_ERROR "Static library SUFFIX should match CMDEF_LIBRARY_NAME_SUFFIX_STATIC '${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}', got: ${static_suffix}") + ENDIF() + + MESSAGE(STATUS "Cache variables integration test passed") +ENDFUNCTION() + +## +# Test CMDEF_ADD_LIBRARY debug suffix integration. +# +# Tests that debug suffixes from CMDEF_ENV are properly applied +# to library names based on build configuration. +# +# () +# +FUNCTION(TEST_DEBUG_SUFFIX_INTEGRATION) + MESSAGE(STATUS "Testing debug suffix integration with CMDEF_ADD_LIBRARY") + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testdebug + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testdebug-shared) + MESSAGE(FATAL_ERROR "Debug library target 'testdebug-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(debug_output_name testdebug-shared OUTPUT_NAME) + IF(NOT debug_output_name MATCHES "${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}") + MESSAGE(FATAL_ERROR "Debug library OUTPUT_NAME should contain debug suffix '${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}', got: ${debug_output_name}") + ENDIF() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testrelease + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testrelease-shared) + MESSAGE(FATAL_ERROR "Release library target 'testrelease-shared' was not created") + ENDIF() + + # The double d needs to be matched here to not confuse shareD for a debug suffix + GET_TARGET_PROPERTY(release_output_name testrelease-shared OUTPUT_NAME) + IF(release_output_name MATCHES "d${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$") + MESSAGE(FATAL_ERROR "Release library OUTPUT_NAME should NOT contain debug suffix '${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}', got: ${release_output_name}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) + + MESSAGE(STATUS "Debug suffix integration test passed") +ENDFUNCTION() + +## +# Test CMDEF cache variables for Windows platform. +# +# Validates all CMDEF_* cache variables have correct values +# when running on Windows systems. +# +# () +# +FUNCTION(TEST_PLATFORM_SUFFIX_INTEGRATION) + MESSAGE(STATUS "Testing platform-specific suffix integration") + + # Create libraries to test platform-specific suffixes + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testplatform + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testplatform + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testplatform-shared) + MESSAGE(FATAL_ERROR "Platform shared library target 'testplatform-shared' was not created") + ENDIF() + + IF(NOT TARGET testplatform-static) + MESSAGE(FATAL_ERROR "Platform static library target 'testplatform-static' was not created") + ENDIF() + + GET_TARGET_PROPERTY(shared_suffix testplatform-shared SUFFIX) + GET_TARGET_PROPERTY(static_suffix testplatform-static SUFFIX) + + IF(NOT shared_suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}") + MESSAGE(FATAL_ERROR "Shared library suffix '${shared_suffix}' does not match CMDEF_LIBRARY_NAME_SUFFIX_SHARED '${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}'") + ENDIF() + + IF(NOT static_suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}") + MESSAGE(FATAL_ERROR "Static library suffix '${static_suffix}' does not match CMDEF_LIBRARY_NAME_SUFFIX_STATIC '${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}'") + ENDIF() +ENDFUNCTION() + +TEST_CACHE_VARIABLES_INTEGRATION() +TEST_DEBUG_SUFFIX_INTEGRATION() +TEST_PLATFORM_SUFFIX_INTEGRATION() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt new file mode 100644 index 0000000..d02d999 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt @@ -0,0 +1,112 @@ +## Main +# +# Test CMDEF_ADD_LIBRARY_CHECK function +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_CHECK_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test CMDEF_ADD_LIBRARY_CHECK function with CMDEF-created shared library. +# +# Creates a CMDEF shared library and verifies the check function +# correctly identifies it. +# +# () +# +FUNCTION(TEST_CHECK_CMDEF_SHARED_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testcheckshared + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + CMDEF_ADD_LIBRARY_CHECK(testcheckshared-shared cmdef_result_shared) + IF(NOT DEFINED cmdef_result_shared) + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK failed to identify CMDEF shared library target") + ENDIF() + IF(NOT cmdef_result_shared STREQUAL "testcheckshared-shared") + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK returned wrong target name for shared library: ${cmdef_result_shared}") + ENDIF() +ENDFUNCTION() + +## +# Test CMDEF_ADD_LIBRARY_CHECK function with CMDEF-created static library. +# +# Creates a CMDEF static library and verifies the check function +# correctly identifies it. +# +# () +# +FUNCTION(TEST_CHECK_CMDEF_STATIC_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testcheckstatic + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + CMDEF_ADD_LIBRARY_CHECK(testcheckstatic-static cmdef_result_static) + IF(NOT DEFINED cmdef_result_static) + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK failed to identify CMDEF static library target") + ENDIF() + IF(NOT cmdef_result_static STREQUAL "testcheckstatic-static") + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK returned wrong target name for static library: ${cmdef_result_static}") + ENDIF() +ENDFUNCTION() + +## +# Test CMDEF_ADD_LIBRARY_CHECK function with CMDEF-created interface library. +# +# Creates a CMDEF interface library and verifies the check function +# correctly identifies it. +# +# () +# +FUNCTION(TEST_CHECK_CMDEF_INTERFACE_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testcheckinterface + TYPE INTERFACE + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_ADD_LIBRARY_CHECK(testcheckinterface-interface cmdef_result_interface) + IF(NOT DEFINED cmdef_result_interface) + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK failed to identify CMDEF interface library target") + ENDIF() + IF(NOT cmdef_result_interface STREQUAL "testcheckinterface-interface") + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK returned wrong target name for interface library: ${cmdef_result_interface}") + ENDIF() +ENDFUNCTION() + +## +# Test CMDEF_ADD_LIBRARY_CHECK function with regular CMake library. +# +# Creates a regular CMake library and verifies the check function +# correctly identifies it as NOT being a CMDEF-created target. +# +# () +# +FUNCTION(TEST_CHECK_REGULAR_CMAKE_LIBRARY) + ADD_LIBRARY(regularcmakelib STATIC "${LIBRARY_SOURCE_FILE}") + + CMDEF_ADD_LIBRARY_CHECK(regularcmakelib regular_result) + IF(DEFINED regular_result) + MESSAGE(FATAL_ERROR "CMDEF_ADD_LIBRARY_CHECK incorrectly identified regular CMake library as CMDEF target") + ENDIF() +ENDFUNCTION() + +TEST_CHECK_CMDEF_SHARED_LIBRARY() +TEST_CHECK_CMDEF_STATIC_LIBRARY() +TEST_CHECK_CMDEF_INTERFACE_LIBRARY() +TEST_CHECK_REGULAR_CMAKE_LIBRARY() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt new file mode 100644 index 0000000..e799f44 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt @@ -0,0 +1,148 @@ +## Main +# +# Test generator expression handling in CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_GENEX_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test generator expression debug suffix for multi-config generators. +# +# Creates library with CMAKE_BUILD_TYPE set and verifies +# direct debug suffix is applied. +# +# () +# +FUNCTION(TEST_DIRECT_DEBUG_SUFFIX) + # Test that when CMAKE_BUILD_TYPE is set, we get the direct suffix + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testdirectsuffix + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testdirectsuffix-shared OUTPUT_NAME) + MESSAGE(STATUS "Output name with Debug build type: ${output_name}") + + IF(NOT output_name MATCHES ".*${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$") + MESSAGE(FATAL_ERROR "Direct debug suffix not found in output name: ${output_name}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test generator expression debug suffix behavior. +# +# Creates library and verifies the actual debug suffix behavior. +# Note: CMDEF may set a default build type even when CMAKE_BUILD_TYPE is unset. +# +# () +# +FUNCTION(TEST_GENERATOR_EXPRESSION_SUFFIX) + # Save original build type and unset it + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testgenexsuffix + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(output_name testgenexsuffix-shared OUTPUT_NAME) + MESSAGE(STATUS "Output name with unset CMAKE_BUILD_TYPE: ${output_name}") + + SET(has_generator_expr FALSE) + SET(has_direct_suffix FALSE) + + IF(output_name MATCHES ".*\\$<\\$:${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}>") + SET(has_generator_expr TRUE) + MESSAGE(STATUS "Found generator expression for debug suffix") + ENDIF() + + IF(output_name MATCHES ".*${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$") + SET(has_direct_suffix TRUE) + MESSAGE(STATUS "Found direct debug suffix") + ENDIF() + + MESSAGE(STATUS "Output name: ${output_name}/${CMAKE_BUILD_TYPE}") + IF(NOT has_generator_expr) + MESSAGE(FATAL_ERROR "Neither generator expression nor direct suffix found: ${output_name}") + ENDIF() + IF(has_direct_suffix) + MESSAGE(FATAL_ERROR "Unexpected direct debug suffix found: ${output_name}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test BUILD_INTERFACE wrapping of INCLUDE_DIRECTORIES. +# +# Verifies that INCLUDE_DIRECTORIES parameter values are wrapped +# with BUILD_INTERFACE generator expressions for all library types. +# +# () +# +FUNCTION(TEST_BUILD_INTERFACE_WRAPPING) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testshared + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + GET_TARGET_PROPERTY(shared_interface_dirs testshared-shared INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT shared_interface_dirs MATCHES "\\$() +# +FUNCTION(TEST_BASIC_INTERFACE_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testinterfacelib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testinterfacelib-interface) + MESSAGE(FATAL_ERROR "Interface library target 'testinterfacelib-interface' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testinterfacelib-interface CMDEF_LIBRARY "INTERFACE") + TEST_CHECK_TARGET_PROPERTY(testinterfacelib-interface CMDEF_INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(output_name testinterfacelib-interface OUTPUT_NAME) + IF(NOT output_name MATCHES "libtestinterfacelib-interface") + MESSAGE(FATAL_ERROR "Interface library OUTPUT_NAME should follow CMDEF pattern, got: ${output_name}") + ENDIF() + + GET_TARGET_PROPERTY(include_dirs testinterfacelib-interface INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT include_dirs MATCHES "\\$() +# +FUNCTION(TEST_INTERFACE_LIBRARY_WITH_BASE_DIR) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testinterfacebasedir + TYPE INTERFACE + VERSION 1.0.0 + SOURCES + "${LIBRARY_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + SOURCE_BASE_DIRECTORY "${TEST_RESOURCES_DIR}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testinterfacebasedir-interface) + MESSAGE(FATAL_ERROR "Interface library target 'testinterfacebasedir-interface' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testinterfacebasedir-interface CMDEF_LIBRARY "INTERFACE") + + GET_TARGET_PROPERTY(lib_sources testinterfacebasedir-interface CMDEF_LIBRARY_SOURCES) + IF(NOT lib_sources) + MESSAGE(FATAL_ERROR "CMDEF_LIBRARY_SOURCES property should be set for interface library") + ENDIF() +ENDFUNCTION() + +## +# Test interface library without sources. +# +# Creates an interface library without sources (header-only library) +# and verifies it works correctly. +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_NO_SOURCES) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testheaderonly + TYPE INTERFACE + VERSION 2.1.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testheaderonly-interface) + MESSAGE(FATAL_ERROR "Header-only interface library target 'testheaderonly-interface' was not created") + ENDIF() + + TEST_CHECK_TARGET_PROPERTY(testheaderonly-interface CMDEF_LIBRARY "INTERFACE") + + GET_TARGET_PROPERTY(lib_sources testheaderonly-interface CMDEF_LIBRARY_SOURCES) + IF(lib_sources) + MESSAGE(FATAL_ERROR "CMDEF_LIBRARY_SOURCES should not be set for header-only library") + ENDIF() +ENDFUNCTION() + +TEST_BASIC_INTERFACE_LIBRARY() +TEST_INTERFACE_LIBRARY_WITH_BASE_DIR() +TEST_INTERFACE_LIBRARY_NO_SOURCES() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt new file mode 100644 index 0000000..a03da7a --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt @@ -0,0 +1,122 @@ +## Main +# +# Test multiple include directories in CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_MULTIPLE_INCLUDES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../multiple_include_sources/multiple_include_sources.cmake") + +## +# Test library with multiple include directories. +# +# Creates a library with multiple INCLUDE_DIRECTORIES and +# INSTALL_INCLUDE_DIRECTORIES and verifies they're all set correctly. +# INSTALL_INCLUDE_DIRECTORIES contains actual header directories that +# should be included in the generated package. +# +# () +# +FUNCTION(TEST_MULTIPLE_INCLUDE_DIRECTORIES) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testmultipleincludes + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + "${LIBRARY_INCLUDE2_DIR}" + INSTALL_INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + ) + + IF(NOT TARGET testmultipleincludes-shared) + MESSAGE(FATAL_ERROR "Library target 'testmultipleincludes-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(include_dirs testmultipleincludes-shared INTERFACE_INCLUDE_DIRECTORIES) + + # Verify each include directory is present (with BUILD_INTERFACE) + # Use more flexible matching since paths might be normalized + SET(expected_dirs + "multiple_include_sources/include" + "multiple_include_sources/include1" + "multiple_include_sources/include2" + ) + + FOREACH(expected_dir IN LISTS expected_dirs) + IF(NOT include_dirs MATCHES "${expected_dir}") + MESSAGE(FATAL_ERROR "Include directory containing '${expected_dir}' not found in INTERFACE_INCLUDE_DIRECTORIES: ${include_dirs}") + ENDIF() + ENDFOREACH() + + GET_TARGET_PROPERTY(install_include_dirs testmultipleincludes-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + + SET(expected_install_dirs + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + ) + + FOREACH(expected_install_dir IN LISTS expected_install_dirs) + LIST(FIND install_include_dirs "${expected_install_dir}" found_index) + IF(found_index EQUAL -1) + MESSAGE(FATAL_ERROR "Install include directory '${expected_install_dir}' not found in CMDEF_INSTALL_INCLUDE_DIRECTORIES") + ENDIF() + ENDFOREACH() + + MESSAGE(STATUS "Multiple include directories test passed") +ENDFUNCTION() + +## +# Test interface library with multiple include directories. +# +# Creates an interface library with multiple include directories +# and verifies they use INTERFACE visibility correctly. +# INSTALL_INCLUDE_DIRECTORIES contains actual header directories that +# should be included in the generated package. +# +# () +# +FUNCTION(TEST_INTERFACE_MULTIPLE_INCLUDE_DIRECTORIES) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testinterfacemultipleincludes + TYPE INTERFACE + VERSION 1.0.0 + INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + INSTALL_INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + ) + + IF(NOT TARGET testinterfacemultipleincludes-interface) + MESSAGE(FATAL_ERROR "Interface library target 'testinterfacemultipleincludes-interface' was not created") + ENDIF() + + GET_TARGET_PROPERTY(include_dirs testinterfacemultipleincludes-interface INTERFACE_INCLUDE_DIRECTORIES) + + # Verify include directories are present with BUILD_INTERFACE + # Use more flexible matching since paths might be normalized + SET(expected_dirs + "multiple_include_sources/include" + "multiple_include_sources/include1" + ) + + FOREACH(expected_dir IN LISTS expected_dirs) + IF(NOT include_dirs MATCHES "${expected_dir}") + MESSAGE(FATAL_ERROR "Include directory containing '${expected_dir}' not found in interface library INTERFACE_INCLUDE_DIRECTORIES: ${include_dirs}") + ENDIF() + ENDFOREACH() + + MESSAGE(STATUS "Interface library multiple include directories test passed") +ENDFUNCTION() + +TEST_MULTIPLE_INCLUDE_DIRECTORIES() +TEST_INTERFACE_MULTIPLE_INCLUDE_DIRECTORIES() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt new file mode 100644 index 0000000..08dbfa6 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt @@ -0,0 +1,42 @@ +## Main +# +# Test CMDEF_ADD_LIBRARY parameter validation +# +# Tests various error conditions and parameter validation scenarios +# for the CMDEF_ADD_LIBRARY function. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_PARAMETER_VALIDATION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +TEST_RUN_AND_CHECK_OUTPUT("missing_library_group" + FATAL_ERROR_MESSAGE "Key 'LIBRARY_GROUP' is not defined" +) + +TEST_RUN_AND_CHECK_OUTPUT("missing_version" + FATAL_ERROR_MESSAGE "Key 'VERSION' is not defined" +) + +TEST_RUN_AND_CHECK_OUTPUT("invalid_type" + FATAL_ERROR_MESSAGE "Invalid Type 'INVALID'" +) + +TEST_RUN_AND_CHECK_OUTPUT("source_base_directory_non_interface" + FATAL_ERROR_MESSAGE "SOURCE_BASE_DIRECTORY is not supported for non INTERFACE library" +) + +TEST_RUN_AND_CHECK_OUTPUT("missing_sources_non_interface" + FATAL_ERROR_MESSAGE "SOURCES is not defined." +) + +IF(CMDEF_OS_POSIX) + TEST_RUN_AND_CHECK_OUTPUT("soversion_greater_than_version" + FATAL_ERROR_MESSAGE "SOVERSION" + ) +ENDIF() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt new file mode 100644 index 0000000..3117a75 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt @@ -0,0 +1,21 @@ +## Main +# +# Test invalid TYPE parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_INVALID_TYPE_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +# This should fail because INVALID is not a valid library type +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE INVALID + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt new file mode 100644 index 0000000..24fde3e --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt @@ -0,0 +1,20 @@ +## Main +# +# Test missing LIBRARY_GROUP parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_MISSING_LIBRARY_GROUP_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +# This should fail because LIBRARY_GROUP is required +CMDEF_ADD_LIBRARY( + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt new file mode 100644 index 0000000..7c20419 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt @@ -0,0 +1,19 @@ +## Main +# +# Test missing SOURCES for non-INTERFACE library error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_MISSING_SOURCES_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") + +# This should fail because SOURCES is required for non-INTERFACE libraries +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt new file mode 100644 index 0000000..874aa2e --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt @@ -0,0 +1,20 @@ +## Main +# +# Test missing VERSION parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_MISSING_VERSION_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +# This should fail because VERSION is required +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt new file mode 100644 index 0000000..dc8c15b --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt @@ -0,0 +1,22 @@ +## Main +# +# Test SOURCE_BASE_DIRECTORY with non-INTERFACE library error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_SOURCE_BASE_DIR_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +# This should fail because SOURCE_BASE_DIRECTORY is only supported for INTERFACE libraries +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + SOURCE_BASE_DIRECTORY "${TEST_RESOURCES_DIR}" + VERSION 1.0.0 +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt new file mode 100644 index 0000000..ac16791 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt @@ -0,0 +1,27 @@ +## Main +# +# Test SOVERSION greater than VERSION error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_SOVERSION_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +IF(NOT CMDEF_OS_POSIX) + MESSAGE(STATUS "Skipping SOVERSION validation test - not on POSIX system") + RETURN() +ENDIF() + +# This should fail because SOVERSION (2.0.0) is greater than VERSION (1.0.0) +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + SOVERSION 2.0.0 +) diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt new file mode 100644 index 0000000..f445d27 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt @@ -0,0 +1,151 @@ +## Main +# +# Test POSIX-specific features in CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_POSIX_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test SOVERSION setting on POSIX systems. +# +# Creates shared libraries with SOVERSION and verifies +# the property is set correctly on POSIX systems. +# +# () +# +FUNCTION(TEST_SOVERSION_ON_POSIX) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixsoversion + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 3.2.1 + SOVERSION 3.2.0 + ) + + IF(NOT TARGET testposixsoversion-shared) + MESSAGE(FATAL_ERROR "Library target 'testposixsoversion-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(soversion testposixsoversion-shared SOVERSION) + IF(NOT soversion STREQUAL "3.2.0") + MESSAGE(FATAL_ERROR "SOVERSION should be set to '3.2.0' on POSIX systems, got: ${soversion}") + ENDIF() +ENDFUNCTION() + +## +# Test POSIX library suffixes. +# +# Verifies that POSIX libraries get the correct suffixes. +# +# () +# +FUNCTION(TEST_POSIX_LIBRARY_SUFFIXES) + # Test shared library suffix + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixshared + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(shared_suffix testposixshared-shared SUFFIX) + + # Use CMDEF cache variable for expected shared library suffix + IF(NOT shared_suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}") + MESSAGE(FATAL_ERROR "POSIX shared library should have '${CMDEF_LIBRARY_NAME_SUFFIX_SHARED}' suffix, got: ${shared_suffix}") + ENDIF() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixstatic + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(static_suffix testposixstatic-static SUFFIX) + IF(NOT static_suffix STREQUAL "${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}") + MESSAGE(FATAL_ERROR "POSIX static library should have '${CMDEF_LIBRARY_NAME_SUFFIX_STATIC}' suffix, got: ${static_suffix}") + ENDIF() +ENDFUNCTION() + +## +# Test POSITION_INDEPENDENT_CODE for shared libraries. +# +# Verifies that shared libraries have POSITION_INDEPENDENT_CODE +# set to TRUE on POSIX systems. +# +# () +# +FUNCTION(TEST_POSITION_INDEPENDENT_CODE) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixpic + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + IF(NOT TARGET testposixpic-shared) + MESSAGE(FATAL_ERROR "Library target 'testposixpic-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(pic testposixpic-shared POSITION_INDEPENDENT_CODE) + IF(NOT pic) + MESSAGE(FATAL_ERROR "POSITION_INDEPENDENT_CODE should be TRUE for shared libraries") + ENDIF() + + MESSAGE(STATUS "POSITION_INDEPENDENT_CODE correctly set for shared library") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixstaticpic + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(static_pic testposixstaticpic-static POSITION_INDEPENDENT_CODE) + IF(static_pic) + MESSAGE(STATUS "Static library has POSITION_INDEPENDENT_CODE set (may be platform default): ${static_pic}") + ELSE() + MESSAGE(STATUS "Static library does not have POSITION_INDEPENDENT_CODE set (expected)") + ENDIF() +ENDFUNCTION() + +## +# Test library naming on POSIX systems. +# +# Verifies that POSIX libraries follow the expected naming convention. +# +# () +# +FUNCTION(TEST_POSIX_LIBRARY_NAMING) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testposixnaming + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(prefix testposixnaming-shared PREFIX) + IF(NOT prefix STREQUAL "") + MESSAGE(FATAL_ERROR "PREFIX should be empty for CMDEF libraries, got: '${prefix}'") + ENDIF() + + GET_TARGET_PROPERTY(output_name testposixnaming-shared OUTPUT_NAME) + IF(NOT output_name MATCHES "libtestposixnaming-shared") + MESSAGE(FATAL_ERROR "OUTPUT_NAME should follow CMDEF pattern, got: ${output_name}") + ENDIF() +ENDFUNCTION() + +TEST_SOVERSION_ON_POSIX() +TEST_POSIX_LIBRARY_SUFFIXES() +TEST_POSITION_INDEPENDENT_CODE() +TEST_POSIX_LIBRARY_NAMING() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt new file mode 100644 index 0000000..9314e60 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt @@ -0,0 +1,138 @@ +## Main +# +# Test SOVERSION handling in CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_SOVERSION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test valid SOVERSION on POSIX systems. +# +# Creates a shared library with valid SOVERSION and verifies +# it's set correctly on POSIX systems. +# +# () +# +FUNCTION(TEST_VALID_SOVERSION) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testsoversion + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 2.1.0 + SOVERSION 2.0.0 + ) + + IF(NOT TARGET testsoversion-shared) + MESSAGE(FATAL_ERROR "Library target 'testsoversion-shared' was not created") + ENDIF() + + IF(CMDEF_OS_POSIX) + GET_TARGET_PROPERTY(soversion testsoversion-shared SOVERSION) + IF(NOT soversion STREQUAL "2.0.0") + MESSAGE(FATAL_ERROR "SOVERSION should be set to '2.0.0' on POSIX systems, got: ${soversion}") + ENDIF() + MESSAGE(STATUS "SOVERSION correctly set on POSIX system: ${soversion}") + ELSE() + GET_TARGET_PROPERTY(soversion testsoversion-shared SOVERSION) + IF(soversion) + MESSAGE(STATUS "SOVERSION ignored on non-POSIX system (expected): ${soversion}") + ENDIF() + ENDIF() +ENDFUNCTION() + +## +# Test SOVERSION equal to VERSION. +# +# Creates a shared library with SOVERSION equal to VERSION +# and verifies it works correctly. +# +# () +# +FUNCTION(TEST_SOVERSION_EQUAL_VERSION) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testsoversionequal + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.5.0 + SOVERSION 1.5.0 + ) + + IF(NOT TARGET testsoversionequal-shared) + MESSAGE(FATAL_ERROR "Library target 'testsoversionequal-shared' was not created") + ENDIF() + + IF(CMDEF_OS_POSIX) + GET_TARGET_PROPERTY(soversion testsoversionequal-shared SOVERSION) + IF(NOT soversion STREQUAL "1.5.0") + MESSAGE(FATAL_ERROR "SOVERSION should be set to '1.5.0' on POSIX systems, got: ${soversion}") + ENDIF() + MESSAGE(STATUS "SOVERSION equal to VERSION correctly set: ${soversion}") + ENDIF() +ENDFUNCTION() + +## +# Test SOVERSION with static library (should be ignored). +# +# Creates a static library with SOVERSION and verifies +# it's ignored (SOVERSION only applies to shared libraries). +# +# () +# +FUNCTION(TEST_SOVERSION_STATIC_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testsoversionstatic + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + SOVERSION 1.0.0 + ) + + IF(NOT TARGET testsoversionstatic-static) + MESSAGE(FATAL_ERROR "Library target 'testsoversionstatic-static' was not created") + ENDIF() + + GET_TARGET_PROPERTY(soversion testsoversionstatic-static SOVERSION) + IF(soversion) + MESSAGE(FATAL_ERROR "SOVERSION should not be set for static libraries, got: ${soversion}") + ENDIF() +ENDFUNCTION() + +## +# Test SOVERSION with interface library (should be ignored). +# +# Creates an interface library with SOVERSION and verifies +# it's ignored (SOVERSION only applies to shared libraries). +# +# () +# +FUNCTION(TEST_SOVERSION_INTERFACE_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testsoversioninterface + TYPE INTERFACE + VERSION 1.0.0 + SOVERSION 1.0.0 + ) + + IF(NOT TARGET testsoversioninterface-interface) + MESSAGE(FATAL_ERROR "Library target 'testsoversioninterface-interface' was not created") + ENDIF() + + GET_TARGET_PROPERTY(soversion testsoversioninterface-interface SOVERSION) + IF(soversion) + MESSAGE(FATAL_ERROR "SOVERSION should not be set for interface libraries, got: ${soversion}") + ENDIF() +ENDFUNCTION() + +TEST_VALID_SOVERSION() +TEST_SOVERSION_EQUAL_VERSION() +TEST_SOVERSION_STATIC_LIBRARY() +TEST_SOVERSION_INTERFACE_LIBRARY() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt new file mode 100644 index 0000000..5f87494 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt @@ -0,0 +1,200 @@ +## Main +# +# Test comprehensive target properties validation for CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_PROPERTIES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../multiple_include_sources/multiple_include_sources.cmake") + + + +## +# Test INTERFACE library target properties. +# +# Creates an INTERFACE library with comprehensive parameters +# and validates all target properties are correctly set. +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_PROPERTIES) + SET(test_version "2.1.3") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testpropsintf + TYPE INTERFACE + VERSION ${test_version} + INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + INSTALL_INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + SOURCES + "${LIBRARY_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + ) + + TEST_CHECK_TARGET_PROPERTY(testpropsintf-interface TYPE "INTERFACE_LIBRARY") + TEST_CHECK_TARGET_PROPERTY(testpropsintf-interface CMDEF_LIBRARY "INTERFACE") + TEST_CHECK_TARGET_PROPERTY(testpropsintf-interface CMDEF_INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}") + + GET_TARGET_PROPERTY(intf_include_dirs testpropsintf-interface INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT intf_include_dirs MATCHES "\\$() +# +FUNCTION(TEST_SHARED_LIBRARY_PROPERTIES) + SET(test_version "2.1.3") + SET(test_soversion "2.1") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testpropsshared + TYPE SHARED + VERSION ${test_version} + SOVERSION ${test_soversion} + SOURCES + "${LIBRARY_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + INSTALL_INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + ) + + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared TYPE "SHARED_LIBRARY") + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared CMDEF_LIBRARY "SHARED") + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}") + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared PREFIX "") + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared POSITION_INDEPENDENT_CODE TRUE) + + IF(CMDEF_OS_POSIX) + TEST_CHECK_TARGET_PROPERTY(testpropsshared-shared SOVERSION ${test_soversion}) + ENDIF() + + GET_TARGET_PROPERTY(shared_interface_dirs testpropsshared-shared INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT shared_interface_dirs MATCHES "\\$() +# +FUNCTION(TEST_STATIC_LIBRARY_PROPERTIES) + SET(test_version "2.1.3") + SET(test_soversion "2.1") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testpropsstatic + TYPE STATIC + VERSION ${test_version} + SOVERSION ${test_soversion} + SOURCES + "${LIBRARY_SOURCE_FILE}" + "${UTILS_SOURCE_FILE}" + INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + "${LIBRARY_INCLUDE1_DIR}" + INSTALL_INCLUDE_DIRECTORIES + "${LIBRARY_INCLUDE_DIR}" + ) + + TEST_CHECK_TARGET_PROPERTY(testpropsstatic-static TYPE "STATIC_LIBRARY") + TEST_CHECK_TARGET_PROPERTY(testpropsstatic-static CMDEF_LIBRARY "STATIC") + TEST_CHECK_TARGET_PROPERTY(testpropsstatic-static CMDEF_INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}") + TEST_CHECK_TARGET_PROPERTY(testpropsstatic-static PREFIX "") + + GET_TARGET_PROPERTY(static_pic testpropsstatic-static POSITION_INDEPENDENT_CODE) + IF(static_pic) + MESSAGE(FATAL_ERROR "STATIC library should not have POSITION_INDEPENDENT_CODE set to TRUE") + ENDIF() + + IF(CMDEF_OS_POSIX) + TEST_CHECK_TARGET_PROPERTY(testpropsstatic-static SOVERSION ${test_soversion}) + ENDIF() + + GET_TARGET_PROPERTY(static_interface_dirs testpropsstatic-static INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT static_interface_dirs MATCHES "\\$() +# +FUNCTION(TEST_VALID_VERSIONS) + # Test semantic version + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversion1 + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.2.3 + ) + + IF(NOT TARGET testversion1-static) + MESSAGE(FATAL_ERROR "Library with version '1.2.3' was not created") + ENDIF() + + # Test version with patch zero + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversion2 + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 2.1.0 + ) + + IF(NOT TARGET testversion2-static) + MESSAGE(FATAL_ERROR "Library with version '2.1.0' was not created") + ENDIF() + + # Test single digit version + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversion3 + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 5.0.0 + ) + + IF(NOT TARGET testversion3-static) + MESSAGE(FATAL_ERROR "Library with version '5.0.0' was not created") + ENDIF() + + # Test version with larger numbers + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversion4 + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 10.15.25 + ) + + IF(NOT TARGET testversion4-static) + MESSAGE(FATAL_ERROR "Library with version '10.15.25' was not created") + ENDIF() +ENDFUNCTION() + +## +# Test version property setting. +# +# Creates a library and verifies the VERSION property +# is set correctly on the target. +# +# () +# +FUNCTION(TEST_VERSION_PROPERTY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversionprop + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 3.2.1 + ) + + IF(NOT TARGET testversionprop-shared) + MESSAGE(FATAL_ERROR "Library target 'testversionprop-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(version_prop testversionprop-shared VERSION) + IF(version_prop) + MESSAGE(STATUS "VERSION property set to: ${version_prop}") + IF(NOT version_prop STREQUAL "3.2.1") + MESSAGE(FATAL_ERROR "VERSION property should be '3.2.1', got: ${version_prop}") + ENDIF() + ELSE() + MESSAGE(STATUS "VERSION property not set (may be platform-dependent)") + ENDIF() +ENDFUNCTION() + +## +# Test version in output name. +# +# Verifies that the version doesn't appear in the output name +# (CMDEF uses its own naming scheme). +# +# () +# +FUNCTION(TEST_VERSION_OUTPUT_NAME) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testversionoutput + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 4.1.2 + ) + + IF(NOT TARGET testversionoutput-shared) + MESSAGE(FATAL_ERROR "Library target 'testversionoutput-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(output_name testversionoutput-shared OUTPUT_NAME) + MESSAGE(STATUS "Output name: ${output_name}") + + IF(NOT output_name MATCHES "libtestversionoutput-shared") + MESSAGE(FATAL_ERROR "Output name doesn't follow expected CMDEF pattern: ${output_name}") + ENDIF() + + IF(output_name MATCHES "4\\.1\\.2") + MESSAGE(FATAL_ERROR "Version should not appear directly in output name: ${output_name}") + ENDIF() +ENDFUNCTION() + +TEST_VALID_VERSIONS() +TEST_VERSION_PROPERTY() +TEST_VERSION_OUTPUT_NAME() diff --git a/test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt b/test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt new file mode 100644 index 0000000..43e71b6 --- /dev/null +++ b/test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt @@ -0,0 +1,160 @@ +## Main +# +# Test Windows-specific features in CMDEF_ADD_LIBRARY +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_LIBRARY_WINDOWS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + + + +## +# Test MSVC runtime library settings. +# +# Creates libraries and verifies MSVC runtime library +# is set according to CMDEF_WINDOWS_STATIC_RUNTIME. +# +# () +# +FUNCTION(TEST_MSVC_RUNTIME_LIBRARY) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testmsvcruntime + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + IF(NOT TARGET testmsvcruntime-shared) + MESSAGE(FATAL_ERROR "Library target 'testmsvcruntime-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(msvc_runtime testmsvcruntime-shared MSVC_RUNTIME_LIBRARY) + IF(NOT msvc_runtime) + MESSAGE(FATAL_ERROR "MSVC_RUNTIME_LIBRARY property should be set on Windows") + ENDIF() + + MESSAGE(STATUS "MSVC runtime library: ${msvc_runtime}") + + IF(CMDEF_WINDOWS_STATIC_RUNTIME) + IF(NOT msvc_runtime MATCHES "MultiThreaded.*") + MESSAGE(FATAL_ERROR "Expected static runtime pattern, got: ${msvc_runtime}") + ENDIF() + IF(msvc_runtime MATCHES ".*DLL.*") + MESSAGE(FATAL_ERROR "Static runtime should not contain DLL, got: ${msvc_runtime}") + ENDIF() + ELSE() + IF(NOT msvc_runtime MATCHES ".*DLL.*") + MESSAGE(FATAL_ERROR "Expected dynamic runtime (DLL), got: ${msvc_runtime}") + ENDIF() + ENDIF() + + IF(NOT msvc_runtime MATCHES ".*\\$<\\$:Debug>.*") + MESSAGE(FATAL_ERROR "MSVC runtime should support debug configuration, got: ${msvc_runtime}") + ENDIF() +ENDFUNCTION() + +## +# Test Windows library suffixes. +# +# Verifies that Windows libraries get the correct suffixes. +# +# () +# +FUNCTION(TEST_WINDOWS_LIBRARY_SUFFIXES) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testwindowsshared + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(shared_suffix testwindowsshared-shared SUFFIX) + IF(NOT shared_suffix STREQUAL ".dll") + MESSAGE(FATAL_ERROR "Windows shared library should have .dll suffix, got: ${shared_suffix}") + ENDIF() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testwindowsstatic + TYPE STATIC + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.0.0 + ) + + GET_TARGET_PROPERTY(static_suffix testwindowsstatic-static SUFFIX) + IF(NOT static_suffix STREQUAL ".lib") + MESSAGE(FATAL_ERROR "Windows static library should have .lib suffix, got: ${static_suffix}") + ENDIF() +ENDFUNCTION() + +## +# Test Windows resource generation. +# +# Verifies that Windows libraries get resource files generated +# with version information. +# +# () +# +FUNCTION(TEST_WINDOWS_RESOURCE_GENERATION) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testwindowsresource + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 2.1.3 + ) + + IF(NOT TARGET testwindowsresource-shared) + MESSAGE(FATAL_ERROR "Library target 'testwindowsresource-shared' was not created") + ENDIF() + + # Check if resource target was created (this is internal to CMDEF) + # We can't easily verify the resource file generation without building, + # but we can verify the target was created successfully + GET_TARGET_PROPERTY(target_type testwindowsresource-shared TYPE) + IF(NOT target_type STREQUAL "SHARED_LIBRARY") + MESSAGE(FATAL_ERROR "Target should be SHARED_LIBRARY type, got: ${target_type}") + ENDIF() + + MESSAGE(STATUS "Windows resource generation test passed") +ENDFUNCTION() + +## +# Test that SOVERSION is ignored on Windows. +# +# Creates a shared library with SOVERSION on Windows +# and verifies it's ignored. +# +# () +# +FUNCTION(TEST_SOVERSION_IGNORED_ON_WINDOWS) + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testwindowssoversion + TYPE SHARED + SOURCES "${LIBRARY_SOURCE_FILE}" + VERSION 1.5.0 + SOVERSION 1.0.0 + ) + + IF(NOT TARGET testwindowssoversion-shared) + MESSAGE(FATAL_ERROR "Library target 'testwindowssoversion-shared' was not created") + ENDIF() + + GET_TARGET_PROPERTY(soversion testwindowssoversion-shared SOVERSION) + IF(soversion) + MESSAGE(FATAL_ERROR "SOVERSION property found but should be ignored on Windows: ${soversion}") + ELSE() + MESSAGE(STATUS "SOVERSION correctly ignored on Windows") + ENDIF() + + MESSAGE(STATUS "SOVERSION ignored on Windows test passed") +ENDFUNCTION() + +TEST_MSVC_RUNTIME_LIBRARY() +TEST_WINDOWS_LIBRARY_SUFFIXES() +TEST_WINDOWS_RESOURCE_GENERATION() +TEST_SOVERSION_IGNORED_ON_WINDOWS() diff --git a/test/CMDEF_ENV/CMakeLists.txt b/test/CMDEF_ENV/CMakeLists.txt new file mode 100644 index 0000000..a3da5f0 --- /dev/null +++ b/test/CMDEF_ENV/CMakeLists.txt @@ -0,0 +1,23 @@ +## Main +# +# Tests for CMDEF_ENV module +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../CMDEFConfig.cmake") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/basic_init") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/os_detection") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/arch_detection") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/cache_variables_validation") + +IF(CMDEF_OS_WINDOWS) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/windows_specific") +ELSEIF(CMDEF_OS_POSIX) + TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/macos_specific") +ENDIF() \ No newline at end of file diff --git a/test/CMDEF_ENV/README.md b/test/CMDEF_ENV/README.md new file mode 100644 index 0000000..010b94a --- /dev/null +++ b/test/CMDEF_ENV/README.md @@ -0,0 +1,22 @@ +# CMDEF_ENV Test Cases + +## Functionality Covered by Tests + +- OS detection (Linux, Windows, macOS) +- Architecture detection (x86-64, x86, aarch64, aplsil) +- Cache variables validation for all platforms +- Platform-specific features (Windows, macOS) +- Basic initialization and environment variable support + +## Functionality Not Covered by Tests + +- Custom environment variable overrides +- Cross-compilation scenarios +- Non-standard architectures + +## Usage + +Run all CMDEF_ENV tests: +```bash +cmake . +``` diff --git a/test/CMDEF_ENV/arch_detection/CMakeLists.txt b/test/CMDEF_ENV/arch_detection/CMakeLists.txt new file mode 100644 index 0000000..8921861 --- /dev/null +++ b/test/CMDEF_ENV/arch_detection/CMakeLists.txt @@ -0,0 +1,43 @@ +## Main +# +# Test architecture detection in CMDEF_ENV +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_ARCH_DETECTION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + +IF(CMDEF_OS_LINUX) + LIST(FIND _CMDEF_ENV_SUPPORTED_ARCH_LIST "${CMDEF_ARCHITECTURE}" arch_found) + IF(arch_found EQUAL -1) + MESSAGE(FATAL_ERROR "Unsupported architecture detected: ${CMDEF_ARCHITECTURE}") + ENDIF() +ELSEIF(CMDEF_OS_WINDOWS) + TEST_VAR_VALUE_EQUAL(CMDEF_ARCHITECTURE "x86-64") +ELSEIF(CMDEF_OS_MACOS) + TEST_VAR_VALUE_EQUAL(CMDEF_ARCHITECTURE "aplsil") +ELSE() + MESSAGE(FATAL_ERROR "No OS flag is set to true") +ENDIF() + +TEST_VAR_DEFINED(CMDEF_DISTRO_ID) +TEST_VAR_DEFINED(CMDEF_DISTRO_VERSION_ID) + +IF(CMDEF_OS_LINUX) + IF("${CMDEF_DISTRO_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_ID should not be empty on Linux") + ENDIF() + IF("${CMDEF_DISTRO_VERSION_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_VERSION_ID should not be empty on Linux") + ENDIF() +ELSEIF(CMDEF_OS_WINDOWS) + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_ID "windows") + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_VERSION_ID "1") +ELSEIF(CMDEF_OS_MACOS) + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_ID "macos") + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_VERSION_ID "11") +ENDIF() \ No newline at end of file diff --git a/test/CMDEF_ENV/basic_init/CMakeLists.txt b/test/CMDEF_ENV/basic_init/CMakeLists.txt new file mode 100644 index 0000000..c2e26dd --- /dev/null +++ b/test/CMDEF_ENV/basic_init/CMakeLists.txt @@ -0,0 +1,54 @@ +## Main +# +# Test basic initialization of CMDEF_ENV +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_BASIC_INIT_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") + +# Include the module +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + +TEST_VAR_DEFINED(CMDEF_OS_NAME) +TEST_VAR_DEFINED(CMDEF_OS_NAME_SHORT) +TEST_VAR_DEFINED(CMDEF_OS_NAME_UPPER) +TEST_VAR_DEFINED(CMDEF_ARCHITECTURE) +TEST_VAR_DEFINED(CMDEF_DISTRO_ID) +TEST_VAR_DEFINED(CMDEF_DISTRO_VERSION_ID) + +TEST_VAR_DEFINED(CMDEF_OS_MACOS) +TEST_VAR_DEFINED(CMDEF_OS_WINDOWS) +TEST_VAR_DEFINED(CMDEF_OS_LINUX) +TEST_VAR_DEFINED(CMDEF_OS_POSIX) + +TEST_VAR_DEFINED(CMDEF_LIBRARY_PREFIX) +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_FLAG_STATIC) +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_FLAG_SHARED) +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_DEBUG_SUFFIX) +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_DEV_SUFFIX) +TEST_VAR_DEFINED(CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX) + +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_SUFFIX_STATIC) +TEST_VAR_DEFINED(CMDEF_LIBRARY_NAME_SUFFIX_SHARED) + +TEST_VAR_DEFINED(CMDEF_ENV_NAME_SEPARATOR) +TEST_VAR_DEFINED(CMDEF_ENV_NAMESPACE_SUFFIX) + +TEST_VAR_DEFINED(CMDEF_SUPPORTED_LANG_LIST) +TEST_VAR_DEFINED(CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS) +TEST_VAR_DEFINED(CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS) +TEST_VAR_DEFINED(CMDEF_LANG_OBJC_SOURCE_FILE_EXTENSIONS) +TEST_VAR_DEFINED(CMDEF_LANG_OBJCXX_SOURCE_FILE_EXTENSIONS) +TEST_VAR_DEFINED(CMDEF_LANG_RC_SOURCE_FILE_EXTENSIONS) + +TEST_VAR_DEFINED(CMDEF_INCLUDE_INSTALL_DIR) +TEST_VAR_DEFINED(CMDEF_SOURCE_INSTALL_DIR) +TEST_VAR_DEFINED(CMDEF_LIBRARY_INSTALL_DIR) +TEST_VAR_DEFINED(CMDEF_BINARY_INSTALL_DIR) + +TEST_VAR_DEFINED(CMDEF_ENV_DESCRIPTION_COMPANY_NAME) +TEST_VAR_DEFINED(CMDEF_ENV_DESCRIPTION_COPYRIGHT) \ No newline at end of file diff --git a/test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt b/test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt new file mode 100644 index 0000000..1f82a1d --- /dev/null +++ b/test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt @@ -0,0 +1,374 @@ +## Main +# +# Test CMDEF_ENV cache variables validation for all supported platforms +# +# This test validates that all CMDEF_* cache variables defined by CMDEF_ENV +# are properly set with expected values for each supported platform (Linux, macOS, Windows). +# Also tests environment variable support. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_CACHE_VARIABLES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + + + +## +# Test CMDEF_ENV cache variables for Linux platform. +# +# Validates all CMDEF_* cache variables from CMDEF_ENV have correct values +# when running on Linux systems. +# +# () +# +FUNCTION(TEST_LINUX_CACHE_VARIABLES) + IF(NOT CMDEF_OS_LINUX) + MESSAGE(STATUS "Skipping Linux cache variables test - not running on Linux") + RETURN() + ENDIF() + + MESSAGE(STATUS "Testing CMDEF_ENV cache variables for Linux platform") + + # OS Detection Variables + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "linux") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "lin") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "LINUX") + TEST_VAR_TRUE(CMDEF_OS_LINUX) + TEST_VAR_FALSE(CMDEF_OS_WINDOWS) + TEST_VAR_FALSE(CMDEF_OS_MACOS) + TEST_VAR_TRUE(CMDEF_OS_POSIX) + + # Architecture Variables + TEST_VAR_DEFINED(CMDEF_ARCHITECTURE) + # Linux architecture should be one of the supported ones + SET(supported_archs "x86-64" "x86" "aarch64" "aplsil") + LIST(FIND supported_archs "${CMDEF_ARCHITECTURE}" arch_found) + IF(arch_found EQUAL -1) + MESSAGE(FATAL_ERROR "Unsupported architecture detected: ${CMDEF_ARCHITECTURE}") + ENDIF() + + TEST_VAR_DEFINED(CMDEF_DISTRO_ID) + TEST_VAR_DEFINED(CMDEF_DISTRO_VERSION_ID) + IF("${CMDEF_DISTRO_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_ID should not be empty on Linux") + ENDIF() + IF("${CMDEF_DISTRO_VERSION_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_VERSION_ID should not be empty on Linux") + ENDIF() + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_PREFIX "lib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_STATIC "-static") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_SHARED "") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEBUG_SUFFIX "d") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEV_SUFFIX "-dev") + TEST_VAR_VALUE_EQUAL(CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX "d") + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC ".a") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED ".so") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC_LINUX ".a") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED_LINUX ".so") + + CMAKE_PATH(CONVERT "${CMDEF_INCLUDE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "include") + + CMAKE_PATH(CONVERT "${CMDEF_SOURCE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "source") + + CMAKE_PATH(CONVERT "${CMDEF_LIBRARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "lib") + + CMAKE_PATH(CONVERT "${CMDEF_BINARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "bin") + + # Naming Convention Variables + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAME_SEPARATOR "_") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAMESPACE_SUFFIX "::") + + # Supported Languages + TEST_VAR_DEFINED(CMDEF_SUPPORTED_LANG_LIST) + SET(expected_langs "C" "CXX" "OBJC" "OBJCXX" "RC") + FOREACH(lang IN LISTS expected_langs) + LIST(FIND CMDEF_SUPPORTED_LANG_LIST "${lang}" lang_found) + IF(lang_found EQUAL -1) + MESSAGE(FATAL_ERROR "Expected language '${lang}' not found in CMDEF_SUPPORTED_LANG_LIST") + ENDIF() + ENDFOREACH() + + # Output Directory Variables + TEST_VAR_DEFINED(CMDEF_TARGET_OUTPUT_DIRECTORY) + + # Description Variables + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COMPANY_NAME "Company name") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COPYRIGHT "Company name") + + # Multi-config Variables + TEST_VAR_VALUE_EQUAL(CMDEF_MULTICONF_FOLDER_NAME "CMDEF") + + MESSAGE(STATUS "Linux cache variables validation passed") +ENDFUNCTION() + +## +# Test CMDEF_ENV cache variables for macOS platform. +# +# Validates all CMDEF_* cache variables from CMDEF_ENV have correct values +# when running on macOS systems. +# +# () +# +FUNCTION(TEST_MACOS_CACHE_VARIABLES) + IF(NOT CMDEF_OS_MACOS) + MESSAGE(STATUS "Skipping macOS cache variables test - not running on macOS") + RETURN() + ENDIF() + + MESSAGE(STATUS "Testing CMDEF_ENV cache variables for macOS platform") + + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "macos") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "mac") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "MACOS") + TEST_VAR_TRUE(CMDEF_OS_MACOS) + TEST_VAR_FALSE(CMDEF_OS_WINDOWS) + TEST_VAR_FALSE(CMDEF_OS_LINUX) + TEST_VAR_TRUE(CMDEF_OS_POSIX) + + TEST_VAR_VALUE_EQUAL(CMDEF_ARCHITECTURE "aplsil") + + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_ID "macos") + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_VERSION_ID "11") + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_PREFIX "lib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_STATIC "-static") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_SHARED "") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEBUG_SUFFIX "d") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEV_SUFFIX "-dev") + TEST_VAR_VALUE_EQUAL(CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX "d") + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC ".a") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED ".dylib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC_MACOS ".a") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED_MACOS ".dylib") + + CMAKE_PATH(CONVERT "${CMDEF_INCLUDE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "include") + + CMAKE_PATH(CONVERT "${CMDEF_SOURCE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "source") + + CMAKE_PATH(CONVERT "${CMDEF_LIBRARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "lib") + + CMAKE_PATH(CONVERT "${CMDEF_BINARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "bin") + + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAME_SEPARATOR "_") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAMESPACE_SUFFIX "::") + + TEST_VAR_DEFINED(CMDEF_SUPPORTED_LANG_LIST) + SET(expected_langs "C" "CXX" "OBJC" "OBJCXX" "RC") + FOREACH(lang IN LISTS expected_langs) + LIST(FIND CMDEF_SUPPORTED_LANG_LIST "${lang}" lang_found) + IF(lang_found EQUAL -1) + MESSAGE(FATAL_ERROR "Expected language '${lang}' not found in CMDEF_SUPPORTED_LANG_LIST") + ENDIF() + ENDFOREACH() + + TEST_VAR_DEFINED(CMDEF_TARGET_OUTPUT_DIRECTORY) + + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COMPANY_NAME "Company name") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COPYRIGHT "Company name") + + TEST_VAR_VALUE_EQUAL(CMDEF_MULTICONF_FOLDER_NAME "CMDEF") + + TEST_VAR_DEFINED(CMDEF_MACOS_EXECUTABLE_IBTOOL) + + MESSAGE(STATUS "macOS cache variables validation passed") +ENDFUNCTION() + +## +# Test CMDEF_ENV cache variables for Windows platform. +# +# Validates all CMDEF_* cache variables from CMDEF_ENV have correct values +# when running on Windows systems. +# +# () +# +FUNCTION(TEST_WINDOWS_CACHE_VARIABLES) + IF(NOT CMDEF_OS_WINDOWS) + MESSAGE(STATUS "Skipping Windows cache variables test - not running on Windows") + RETURN() + ENDIF() + + MESSAGE(STATUS "Testing CMDEF_ENV cache variables for Windows platform") + + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "windows") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "win") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "WINDOWS") + TEST_VAR_TRUE(CMDEF_OS_WINDOWS) + TEST_VAR_FALSE(CMDEF_OS_LINUX) + TEST_VAR_FALSE(CMDEF_OS_MACOS) + TEST_VAR_FALSE(CMDEF_OS_POSIX) + + TEST_VAR_VALUE_EQUAL(CMDEF_ARCHITECTURE "x86-64") + + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_ID "windows") + TEST_VAR_VALUE_EQUAL(CMDEF_DISTRO_VERSION_ID "1") + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_PREFIX "lib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_STATIC "-static") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_FLAG_SHARED "") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEBUG_SUFFIX "d") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_DEV_SUFFIX "-dev") + TEST_VAR_VALUE_EQUAL(CMDEF_EXECUTABLE_NAME_DEBUG_SUFFIX "d") + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC ".lib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED ".dll") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC_WINDOWS ".lib") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED_WINDOWS ".dll") + + CMAKE_PATH(CONVERT "${CMDEF_INCLUDE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "include") + + CMAKE_PATH(CONVERT "${CMDEF_SOURCE_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "source") + + CMAKE_PATH(CONVERT "${CMDEF_LIBRARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "lib") + + CMAKE_PATH(CONVERT "${CMDEF_BINARY_INSTALL_DIR}" TO_CMAKE_PATH_LIST _normalized) + TEST_VAR_VALUE_EQUAL(_normalized "bin") + + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAME_SEPARATOR "_") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_NAMESPACE_SUFFIX "::") + + # Supported Languages + TEST_VAR_DEFINED(CMDEF_SUPPORTED_LANG_LIST) + SET(expected_langs "C" "CXX" "OBJC" "OBJCXX" "RC") + FOREACH(lang IN LISTS expected_langs) + LIST(FIND CMDEF_SUPPORTED_LANG_LIST "${lang}" lang_found) + IF(lang_found EQUAL -1) + MESSAGE(FATAL_ERROR "Expected language '${lang}' not found in CMDEF_SUPPORTED_LANG_LIST") + ENDIF() + ENDFOREACH() + + TEST_VAR_DEFINED(CMDEF_TARGET_OUTPUT_DIRECTORY) + + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COMPANY_NAME "Company name") + TEST_VAR_VALUE_EQUAL(CMDEF_ENV_DESCRIPTION_COPYRIGHT "Company name") + + TEST_VAR_VALUE_EQUAL(CMDEF_MULTICONF_FOLDER_NAME "CMDEF") + + TEST_VAR_DEFINED(CMDEF_WINDOWS_EXECUTABLE_MT) + TEST_VAR_DEFINED(CMDEF_WINDOWS_STATIC_RUNTIME) + TEST_VAR_TRUE(CMDEF_WINDOWS_STATIC_RUNTIME) + + MESSAGE(STATUS "Windows cache variables validation passed") +ENDFUNCTION() + +## +# Test common CMDEF_ENV cache variables that should be consistent across all platforms. +# +# Validates CMDEF_* cache variables from CMDEF_ENV that have the same expected values +# regardless of the platform. +# +# () +# +FUNCTION(TEST_COMMON_CACHE_VARIABLES) + MESSAGE(STATUS "Testing common CMDEF_ENV cache variables") + + # Language File Extensions + TEST_VAR_DEFINED(CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS) + TEST_VAR_DEFINED(CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS) + TEST_VAR_DEFINED(CMDEF_LANG_OBJC_SOURCE_FILE_EXTENSIONS) + TEST_VAR_DEFINED(CMDEF_LANG_OBJCXX_SOURCE_FILE_EXTENSIONS) + TEST_VAR_DEFINED(CMDEF_LANG_RC_SOURCE_FILE_EXTENSIONS) + + LIST(FIND CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS ".cpp" cpp_found) + IF(cpp_found EQUAL -1) + MESSAGE(FATAL_ERROR ".cpp extension not found in CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS ".c" c_found) + IF(c_found EQUAL -1) + MESSAGE(FATAL_ERROR ".c extension not found in CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_RC_SOURCE_FILE_EXTENSIONS ".rc" rc_found) + IF(rc_found EQUAL -1) + MESSAGE(FATAL_ERROR ".rc extension not found in CMDEF_LANG_RC_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS ".hpp" hpp_found) + IF(hpp_found EQUAL -1) + MESSAGE(FATAL_ERROR ".hpp extension not found in CMDEF_LANG_CXX_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS ".h" h_found) + IF(h_found EQUAL -1) + MESSAGE(FATAL_ERROR ".h extension not found in CMDEF_LANG_C_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_OBJC_SOURCE_FILE_EXTENSIONS ".m" m_found) + IF(m_found EQUAL -1) + MESSAGE(FATAL_ERROR ".m extension not found in CMDEF_LANG_OBJC_SOURCE_FILE_EXTENSIONS") + ENDIF() + + LIST(FIND CMDEF_LANG_OBJCXX_SOURCE_FILE_EXTENSIONS ".mm" mm_found) + IF(mm_found EQUAL -1) + MESSAGE(FATAL_ERROR ".mm extension not found in CMDEF_LANG_OBJCXX_SOURCE_FILE_EXTENSIONS") + ENDIF() + + MESSAGE(STATUS "Common cache variables validation passed") +ENDFUNCTION() + +## +# Test CMDEF_ENV environment variable support. +# +# Tests that CMDEF_ENV properly reads and uses environment variables +# for architecture and distribution detection. +# +# () +# +FUNCTION(TEST_ENVIRONMENT_VARIABLES) + MESSAGE(STATUS "Testing CMDEF_ENV environment variable support") + + # Save current values + SET(original_arch "${CMDEF_ARCHITECTURE}") + SET(original_distro_id "${CMDEF_DISTRO_ID}") + SET(original_distro_version "${CMDEF_DISTRO_VERSION_ID}") + + # Test that environment variables can override detection + # Note: This test verifies the logic exists, but doesn't actually set ENV vars + # since that would affect the global state + + # Verify that the environment variable logic is present in the code + # by checking that the cache variables are defined (they should be from CMDEF_ENV_INIT) + TEST_VAR_DEFINED(CMDEF_ARCHITECTURE) + TEST_VAR_DEFINED(CMDEF_DISTRO_ID) + TEST_VAR_DEFINED(CMDEF_DISTRO_VERSION_ID) + + SET(supported_archs "x86-64" "x86" "aarch64" "aplsil") + LIST(FIND supported_archs "${CMDEF_ARCHITECTURE}" arch_found) + IF(arch_found EQUAL -1) + MESSAGE(FATAL_ERROR "CMDEF_ARCHITECTURE '${CMDEF_ARCHITECTURE}' is not in supported list: ${supported_archs}") + ENDIF() + + IF("${CMDEF_DISTRO_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_ID should not be empty") + ENDIF() + + IF("${CMDEF_DISTRO_VERSION_ID}" STREQUAL "") + MESSAGE(FATAL_ERROR "CMDEF_DISTRO_VERSION_ID should not be empty") + ENDIF() + + MESSAGE(STATUS "Environment variable support validation passed") +ENDFUNCTION() + +TEST_LINUX_CACHE_VARIABLES() +TEST_MACOS_CACHE_VARIABLES() +TEST_WINDOWS_CACHE_VARIABLES() +TEST_COMMON_CACHE_VARIABLES() +TEST_ENVIRONMENT_VARIABLES() diff --git a/test/CMDEF_ENV/macos_specific/CMakeLists.txt b/test/CMDEF_ENV/macos_specific/CMakeLists.txt new file mode 100644 index 0000000..aeed8f6 --- /dev/null +++ b/test/CMDEF_ENV/macos_specific/CMakeLists.txt @@ -0,0 +1,21 @@ +## Main +# +# Test macOS-specific functionality in CMDEF_ENV +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_MACOS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + +IF(CMDEF_OS_MACOS) + TEST_VAR_DEFINED(CMDEF_MACOS_EXECUTABLE_IBTOOL) + + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC "${CMDEF_LIBRARY_NAME_SUFFIX_STATIC_MACOS}") + TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED "${CMDEF_LIBRARY_NAME_SUFFIX_SHARED_MACOS}") +ELSE() + MESSAGE(STATUS "Skipping macOS-specific tests - not running on macOS") +ENDIF() \ No newline at end of file diff --git a/test/CMDEF_ENV/os_detection/CMakeLists.txt b/test/CMDEF_ENV/os_detection/CMakeLists.txt new file mode 100644 index 0000000..5e507e6 --- /dev/null +++ b/test/CMDEF_ENV/os_detection/CMakeLists.txt @@ -0,0 +1,40 @@ +## Main +# +# Test OS detection in CMDEF_ENV +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_OS_DETECTION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + +IF(CMDEF_OS_LINUX) + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "linux") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "lin") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "LINUX") + TEST_VAR_TRUE(CMDEF_OS_LINUX) + TEST_VAR_FALSE(CMDEF_OS_WINDOWS) + TEST_VAR_FALSE(CMDEF_OS_MACOS) + TEST_VAR_TRUE(CMDEF_OS_POSIX) +ELSEIF(CMDEF_OS_WINDOWS) + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "windows") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "win") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "WINDOWS") + TEST_VAR_TRUE(CMDEF_OS_WINDOWS) + TEST_VAR_FALSE(CMDEF_OS_LINUX) + TEST_VAR_FALSE(CMDEF_OS_MACOS) + TEST_VAR_FALSE(CMDEF_OS_POSIX) +ELSEIF(CMDEF_OS_MACOS) + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME "macos") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_SHORT "mac") + TEST_VAR_VALUE_EQUAL(CMDEF_OS_NAME_UPPER "MACOS") + TEST_VAR_TRUE(CMDEF_OS_MACOS) + TEST_VAR_FALSE(CMDEF_OS_LINUX) + TEST_VAR_FALSE(CMDEF_OS_WINDOWS) + TEST_VAR_TRUE(CMDEF_OS_POSIX) +ELSE() + MESSAGE(FATAL_ERROR "No OS flag is set to true") +ENDIF() \ No newline at end of file diff --git a/test/CMDEF_ENV/windows_specific/CMakeLists.txt b/test/CMDEF_ENV/windows_specific/CMakeLists.txt new file mode 100644 index 0000000..c3f3bb3 --- /dev/null +++ b/test/CMDEF_ENV/windows_specific/CMakeLists.txt @@ -0,0 +1,20 @@ +## Main +# +# Test Windows-specific functionality in CMDEF_ENV +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ENV_WINDOWS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../system_modules/CMDEF_ENV.cmake") + +TEST_VAR_DEFINED(CMDEF_WINDOWS_EXECUTABLE_MT) + +TEST_VAR_DEFINED(CMDEF_WINDOWS_STATIC_RUNTIME) +TEST_VAR_TRUE(CMDEF_WINDOWS_STATIC_RUNTIME) + +TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_STATIC "${CMDEF_LIBRARY_NAME_SUFFIX_STATIC_WINDOWS}") +TEST_VAR_VALUE_EQUAL(CMDEF_LIBRARY_NAME_SUFFIX_SHARED "${CMDEF_LIBRARY_NAME_SUFFIX_SHARED_WINDOWS}") \ No newline at end of file diff --git a/test/CMDEF_INSTALL/CMakeLists.txt b/test/CMDEF_INSTALL/CMakeLists.txt new file mode 100644 index 0000000..a517bcd --- /dev/null +++ b/test/CMDEF_INSTALL/CMakeLists.txt @@ -0,0 +1,22 @@ +## Main +# +# Test CMDEF_INSTALL +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../CMDEFConfig.cmake") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/shared_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/static_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/interface_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/executable") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/with_namespace") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/with_configs") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/include_dirs") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/no_config") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/multiple_calls") diff --git a/test/CMDEF_INSTALL/README.md b/test/CMDEF_INSTALL/README.md new file mode 100644 index 0000000..146bbdd --- /dev/null +++ b/test/CMDEF_INSTALL/README.md @@ -0,0 +1,24 @@ +# CMDEF_INSTALL Tests + +Unit tests for the `CMDEF_INSTALL` function. + +## Directory Structure + +### `shared_sources/` + +Contains reusable test resources - C++ source files and headers + +### `test_cases/` + +Individual test cases covering: +- Library installation (shared, static, interface) +- Executable installation destinations +- Export configuration and namespace handling +- Error conditions and parameter validation + +## Usage + +Run all CMDEF_INSTALL tests: +```bash +cmake . +``` diff --git a/test/CMDEF_INSTALL/install_test_macros.cmake b/test/CMDEF_INSTALL/install_test_macros.cmake new file mode 100644 index 0000000..6eafd1b --- /dev/null +++ b/test/CMDEF_INSTALL/install_test_macros.cmake @@ -0,0 +1,103 @@ +## Main +# +# CMDEF_INSTALL specific test helper macros +# +# This module provides specialized test macros for verifying target properties +# set by CMDEF_INSTALL. These macros complement the INSTALL command verification +# functions in install_override.cmake by focusing on target property validation. +# + +## +# Verify target include directories contain expected interface. +# +# Checks that a target's include directories property contains the expected +# generator expression or path. This is used to verify that CMDEF_INSTALL +# properly adds INSTALL_INTERFACE generator expressions to targets. +# +# ( +# // Target name to check +# // Type of include directories (INTERFACE, PUBLIC, PRIVATE) +# // Expected interface string (e.g., generator expression) +# ) +# +MACRO(TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS target include_type expected_interface) + SET(property_name) + IF(${include_type} STREQUAL "INTERFACE") + SET(property_name "INTERFACE_INCLUDE_DIRECTORIES") + ELSEIF(${include_type} STREQUAL "PUBLIC") + SET(property_name "INCLUDE_DIRECTORIES") + ELSEIF(${include_type} STREQUAL "PRIVATE") + SET(property_name "INCLUDE_DIRECTORIES") + ELSE() + MESSAGE(FATAL_ERROR "Invalid include_type '${include_type}'. Must be INTERFACE, PUBLIC, or PRIVATE") + ENDIF() + + GET_TARGET_PROPERTY(include_dirs ${target} ${property_name}) + IF(NOT include_dirs) + MESSAGE(FATAL_ERROR "Target ${target} has no ${property_name} property") + ENDIF() + + STRING(FIND "${include_dirs}" "${expected_interface}" found_pos) + IF(found_pos EQUAL -1) + MESSAGE(FATAL_ERROR "${property_name} for target ${target} does not contain '${expected_interface}'. Got: ${include_dirs}") + ENDIF() +ENDMACRO() + +## +# Verify target EXPORT_PROPERTIES contains expected property. +# +# Checks that a target's EXPORT_PROPERTIES list contains the expected property name. +# This is used to verify that CMDEF_INSTALL properly adds properties to the export +# list for interface libraries. +# +# ( +# // Target name to check +# // Expected property name in EXPORT_PROPERTIES list +# ) +# +MACRO(TEST_CHECK_TARGET_EXPORT_PROPERTIES_CONTAINS target expected_property) + GET_TARGET_PROPERTY(export_props ${target} EXPORT_PROPERTIES) + IF(NOT export_props) + SET(export_props "") + ENDIF() + + IF(NOT "${expected_property}" IN_LIST export_props) + MESSAGE(FATAL_ERROR "EXPORT_PROPERTIES for target ${target} does not contain '${expected_property}'. Got: ${export_props}") + ENDIF() +ENDMACRO() + +## +# Verify target has specific property set. +# +# Checks that a target has the specified property defined (not empty/unset). +# This is used to verify property dependencies in CMDEF_INSTALL. +# +# ( +# // Target name to check +# // Property name that should be set +# ) +# +MACRO(TEST_CHECK_TARGET_HAS_PROPERTY target property) + GET_TARGET_PROPERTY(prop_value ${target} ${property}) + IF(NOT prop_value) + MESSAGE(FATAL_ERROR "Target ${target} should have property ${property} set but it is not set or empty") + ENDIF() +ENDMACRO() + +## +# Verify target does NOT have specific property set. +# +# Checks that a target does not have the specified property defined or it is empty. +# This is used to verify conditional behavior in CMDEF_INSTALL. +# +# ( +# // Target name to check +# // Property name that should NOT be set +# ) +# +MACRO(TEST_CHECK_TARGET_LACKS_PROPERTY target property) + GET_TARGET_PROPERTY(prop_value ${target} ${property}) + IF(prop_value) + MESSAGE(FATAL_ERROR "Target ${target} should NOT have property ${property} set but it is set to: ${prop_value}") + ENDIF() +ENDMACRO() \ No newline at end of file diff --git a/test/CMDEF_INSTALL/library_tests.cmake b/test/CMDEF_INSTALL/library_tests.cmake new file mode 100644 index 0000000..0496457 --- /dev/null +++ b/test/CMDEF_INSTALL/library_tests.cmake @@ -0,0 +1,29 @@ + + +## +# +# Test library installation with complete INSTALL command verification. +# +# Creates a library and verifies all INSTALL commands are called +# with correct destinations and parameters. +# +# ( +# +# ) +# +FUNCTION(LIBRARY_TESTS target_name) + TEST_INSTALL_TARGETS_EXPORT_EQUALS(${target_name}) + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("LIBRARY" "${CMDEF_LIBRARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("RUNTIME" "${CMDEF_BINARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("BUNDLE" "${CMDEF_BINARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("PUBLIC_HEADER" "${CMDEF_INCLUDE_INSTALL_DIR}") + + TEST_INSTALL_TARGETS_CONFIGURATIONS_CONTAINS("DEBUG") + TEST_INSTALL_TARGETS_CONFIGURATIONS_CONTAINS("RELEASE") + + TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake//") + + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("DEBUG") + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("RELEASE") +ENDFUNCTION() \ No newline at end of file diff --git a/test/CMDEF_INSTALL/shared_sources/include/library.h b/test/CMDEF_INSTALL/shared_sources/include/library.h new file mode 100644 index 0000000..1ebbc9c --- /dev/null +++ b/test/CMDEF_INSTALL/shared_sources/include/library.h @@ -0,0 +1,4 @@ +#pragma once + +int get_library_version(); +void library_function(); diff --git a/test/CMDEF_INSTALL/shared_sources/shared_sources.cmake b/test/CMDEF_INSTALL/shared_sources/shared_sources.cmake new file mode 100644 index 0000000..0f89d74 --- /dev/null +++ b/test/CMDEF_INSTALL/shared_sources/shared_sources.cmake @@ -0,0 +1,11 @@ +## Shared Sources Configuration +# +# Defines common paths and variables for CMDEF_INSTALL tests +# + +SET(SHARED_SOURCES_DIR "${CMAKE_CURRENT_LIST_DIR}") + +SET(LIBRARY_SOURCE_FILE "${SHARED_SOURCES_DIR}/src/library.cpp") +SET(MAIN_SOURCE_FILE "${SHARED_SOURCES_DIR}/src/main.cpp") + +SET(LIBRARY_INCLUDE_DIR "${SHARED_SOURCES_DIR}/include") diff --git a/test/CMDEF_INSTALL/shared_sources/src/library.cpp b/test/CMDEF_INSTALL/shared_sources/src/library.cpp new file mode 100644 index 0000000..58e00ed --- /dev/null +++ b/test/CMDEF_INSTALL/shared_sources/src/library.cpp @@ -0,0 +1,9 @@ +#include "library.h" + +int get_library_version() { + return 100; +} + +void library_function() { + // Simple library function for testing +} diff --git a/test/CMDEF_INSTALL/shared_sources/src/main.cpp b/test/CMDEF_INSTALL/shared_sources/src/main.cpp new file mode 100644 index 0000000..63ab199 --- /dev/null +++ b/test/CMDEF_INSTALL/shared_sources/src/main.cpp @@ -0,0 +1,6 @@ +#include "library.h" + +int main() { + library_function(); + return get_library_version(); +} diff --git a/test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt new file mode 100644 index 0000000..1c37b2d --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt @@ -0,0 +1,62 @@ +## Main +# +# Test CMDEF_INSTALL with executable +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_EXECUTABLE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../library_tests.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test executable installation with INSTALL command verification. +# +# Creates an executable and verifies INSTALL commands are called +# with correct destinations for executables. +# +# () +# +FUNCTION(TEST_EXECUTABLE_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_EXECUTABLE( + TARGET texe + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + CMDEF_INSTALL(TARGET texe) + LIBRARY_TESTS("texe") +ENDFUNCTION() + +## +# Test executable installation with property verification. +# +# Creates an executable and verifies all target properties set by +# CMDEF_INSTALL are correctly configured. +# +# () +# +FUNCTION(TEST_EXECUTABLE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_EXECUTABLE( + TARGET epexe + SOURCES "${MAIN_SOURCE_FILE}" + VERSION 1.0.0 + ) + + CMDEF_INSTALL(TARGET epexe) + + TEST_CHECK_TARGET_PROPERTY(epexe CMDEF_INSTALL ON) +ENDFUNCTION() + +TEST_EXECUTABLE_INSTALL() +TEST_EXECUTABLE_PROPERTIES() diff --git a/test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt new file mode 100644 index 0000000..a61d5eb --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt @@ -0,0 +1,118 @@ +## Main +# +# Test CMDEF_INSTALL with include directories +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_INCLUDE_DIRS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test installation with include directories. +# +# Creates a library with INSTALL_INCLUDE_DIRECTORIES and verifies +# INSTALL(DIRECTORY) is called with correct destination. +# +# () +# +FUNCTION(TEST_INCLUDE_DIRECTORIES_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP dlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET dlib-shared) + + TEST_INSTALL_TARGETS_EXPORT_EQUALS("dlib-shared") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("PUBLIC_HEADER" "${CMDEF_INCLUDE_INSTALL_DIR}") + + TEST_INSTALL_DIRECTORY_DESTINATION_EQUALS("${CMDEF_INCLUDE_INSTALL_DIR}") + + TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake//") +ENDFUNCTION() + +## +# Test include directories installation with property verification. +# +# Creates a library with INSTALL_INCLUDE_DIRECTORIES and verifies all target +# properties set by CMDEF_INSTALL are correctly configured, including +# INSTALL_INTERFACE generator expressions. +# +# () +# +FUNCTION(TEST_INCLUDE_DIRECTORIES_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP dplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET dplib-shared) + + TEST_CHECK_TARGET_PROPERTY(dplib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(dplib-shared INTERFACE "$") + + TEST_CHECK_TARGET_HAS_PROPERTY(dplib-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + + GET_TARGET_PROPERTY(all_include_dirs dplib-shared INTERFACE_INCLUDE_DIRECTORIES) + IF(NOT all_include_dirs MATCHES "BUILD_INTERFACE") + MESSAGE(FATAL_ERROR "INTERFACE_INCLUDE_DIRECTORIES should contain BUILD_INTERFACE but does not. Got: ${all_include_dirs}") + ENDIF() + IF(NOT all_include_dirs MATCHES "INSTALL_INTERFACE") + MESSAGE(FATAL_ERROR "INTERFACE_INCLUDE_DIRECTORIES should contain INSTALL_INTERFACE but does not. Got: ${all_include_dirs}") + ENDIF() +ENDFUNCTION() + +## +# Test include directories behavior without INSTALL_INCLUDE_DIRECTORIES. +# +# Creates a library with regular INCLUDE_DIRECTORIES but no INSTALL_INCLUDE_DIRECTORIES +# and verifies that INSTALL_INTERFACE is NOT added. +# +# () +# +FUNCTION(TEST_INCLUDE_DIRECTORIES_NO_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP dnilib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET dnilib-shared) + + TEST_CHECK_TARGET_PROPERTY(dnilib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_LACKS_PROPERTY(dnilib-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + + GET_TARGET_PROPERTY(include_dirs dnilib-shared INTERFACE_INCLUDE_DIRECTORIES) + IF(include_dirs AND include_dirs MATCHES "INSTALL_INTERFACE") + MESSAGE(FATAL_ERROR "INTERFACE_INCLUDE_DIRECTORIES should not contain INSTALL_INTERFACE when no INSTALL_INCLUDE_DIRECTORIES. Got: ${include_dirs}") + ENDIF() +ENDFUNCTION() + +TEST_INCLUDE_DIRECTORIES_INSTALL() +TEST_INCLUDE_DIRECTORIES_PROPERTIES() +TEST_INCLUDE_DIRECTORIES_NO_INSTALL() diff --git a/test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt new file mode 100644 index 0000000..5d3e9eb --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt @@ -0,0 +1,206 @@ +## Main +# +# Test CMDEF_INSTALL with interface library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_INTERFACE_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../library_tests.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + + + +## +# Verify target CMDEF_INSTALL_INTERFACE_SOURCES contains expected source path. +# +# Checks that a target's CMDEF_INSTALL_INTERFACE_SOURCES property contains +# the expected source file path. This is used to verify that CMDEF_INSTALL +# properly processes interface library sources. +# +# ( +# // Target name to check +# // Expected source path in the property +# ) +# +MACRO(TEST_CHECK_TARGET_INSTALL_INTERFACE_SOURCES_CONTAINS target expected_source_path) + GET_TARGET_PROPERTY(interface_sources ${target} CMDEF_INSTALL_INTERFACE_SOURCES) + IF(NOT interface_sources) + MESSAGE(FATAL_ERROR "Target ${target} has no CMDEF_INSTALL_INTERFACE_SOURCES property") + ENDIF() + + STRING(FIND "${interface_sources}" "${expected_source_path}" found_pos) + IF(found_pos EQUAL -1) + MESSAGE(FATAL_ERROR "CMDEF_INSTALL_INTERFACE_SOURCES for target ${target} does not contain '${expected_source_path}'. Got: ${interface_sources}") + ENDIF() +ENDMACRO() + +## +# Verify target CMDEF_INSTALL_INTERFACE_SOURCES has expected number of entries. +# +# Checks that a target's CMDEF_INSTALL_INTERFACE_SOURCES property has the +# expected number of source file entries. +# +# ( +# // Target name to check +# // Expected number of source entries +# ) +# +MACRO(TEST_CHECK_TARGET_INSTALL_INTERFACE_SOURCES_COUNT target expected_count) + GET_TARGET_PROPERTY(interface_sources ${target} CMDEF_INSTALL_INTERFACE_SOURCES) + IF(NOT interface_sources) + SET(interface_sources "") + ENDIF() + + LIST(LENGTH interface_sources actual_count) + IF(NOT actual_count EQUAL ${expected_count}) + MESSAGE(FATAL_ERROR "CMDEF_INSTALL_INTERFACE_SOURCES for target ${target} should have ${expected_count} entries but has ${actual_count}. Got: ${interface_sources}") + ENDIF() +ENDMACRO() + + + +## +# Test interface library installation with source files. +# +# Creates an interface library with sources and verifies INSTALL(TARGETS) +# and INSTALL(FILES) commands are called correctly. +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP ilib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET ilib-interface) + + LIBRARY_TESTS("ilib-interface") + + TEST_GET_INSTALL_FILES_CALLS(files_calls) + IF(NOT files_calls MATCHES "FILES.*DESTINATION.*${CMDEF_SOURCE_INSTALL_DIR}") + MESSAGE(FATAL_ERROR "INSTALL FILES for interface sources not found with correct destination") + ENDIF() +ENDFUNCTION() + +## +# Test interface library with sources but no base directory. +# +# Creates an interface library with sources but no SOURCE_BASE_DIRECTORY. +# According to _CMDEF_INSTALL_INTERFACE_TARGET implementation: +# - CMDEF_INSTALL_INTERFACE_SOURCES is set to empty (line 206) +# - EXPORT_PROPERTIES always includes CMDEF_INSTALL_INTERFACE_SOURCES (line 219) +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_NO_BASE_DIR) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP inbdlib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET inbdlib-interface) + + TEST_CHECK_TARGET_PROPERTY(inbdlib-interface CMDEF_INSTALL ON) + + TEST_CHECK_TARGET_HAS_PROPERTY(inbdlib-interface CMDEF_LIBRARY) + TEST_CHECK_TARGET_HAS_PROPERTY(inbdlib-interface CMDEF_LIBRARY_SOURCES) + TEST_CHECK_TARGET_LACKS_PROPERTY(inbdlib-interface CMDEF_LIBRARY_BASE_DIR) + + TEST_CHECK_TARGET_INSTALL_INTERFACE_SOURCES_COUNT(inbdlib-interface 0) + + TEST_CHECK_TARGET_EXPORT_PROPERTIES_CONTAINS(inbdlib-interface "CMDEF_INSTALL_INTERFACE_SOURCES") +ENDFUNCTION() + +## +# Test interface library with sources and base directory. +# +# Creates an interface library with SOURCE_BASE_DIRECTORY. +# According to _CMDEF_INSTALL_INTERFACE_TARGET implementation: +# - Sources with base directory prefix get added to CMDEF_INSTALL_INTERFACE_SOURCES (line 217) +# - EXPORT_PROPERTIES always includes CMDEF_INSTALL_INTERFACE_SOURCES (line 219) +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_WITH_BASE_DIR) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP ibdlib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + SOURCE_BASE_DIRECTORY "../../shared_sources" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET ibdlib-interface) + + TEST_CHECK_TARGET_PROPERTY(ibdlib-interface CMDEF_INSTALL ON) + + TEST_CHECK_TARGET_HAS_PROPERTY(ibdlib-interface CMDEF_LIBRARY) + TEST_CHECK_TARGET_HAS_PROPERTY(ibdlib-interface CMDEF_LIBRARY_SOURCES) + TEST_CHECK_TARGET_HAS_PROPERTY(ibdlib-interface CMDEF_LIBRARY_BASE_DIR) + + TEST_CHECK_TARGET_INSTALL_INTERFACE_SOURCES_COUNT(ibdlib-interface 1) + TEST_CHECK_TARGET_INSTALL_INTERFACE_SOURCES_CONTAINS(ibdlib-interface "library.cpp") + + TEST_CHECK_TARGET_EXPORT_PROPERTIES_CONTAINS(ibdlib-interface "CMDEF_INSTALL_INTERFACE_SOURCES") +ENDFUNCTION() + +## +# Test interface library without sources. +# +# Creates an interface library without sources. +# According to _CMDEF_INSTALL_INTERFACE_TARGET implementation: +# - Function returns early if no CMDEF_LIBRARY_SOURCES (line 182-184) +# - No interface-specific properties are set +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_NO_SOURCES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP inslib + TYPE INTERFACE + VERSION 1.0.0 + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET inslib-interface) + + TEST_CHECK_TARGET_PROPERTY(inslib-interface CMDEF_INSTALL ON) + + TEST_CHECK_TARGET_HAS_PROPERTY(inslib-interface CMDEF_LIBRARY) + TEST_CHECK_TARGET_LACKS_PROPERTY(inslib-interface CMDEF_LIBRARY_SOURCES) + + TEST_CHECK_TARGET_LACKS_PROPERTY(inslib-interface CMDEF_INSTALL_INTERFACE_SOURCES) + + GET_TARGET_PROPERTY(export_props inslib-interface EXPORT_PROPERTIES) + IF(export_props AND "CMDEF_INSTALL_INTERFACE_SOURCES" IN_LIST export_props) + MESSAGE(FATAL_ERROR "EXPORT_PROPERTIES should not contain CMDEF_INSTALL_INTERFACE_SOURCES when no sources") + ENDIF() +ENDFUNCTION() + +TEST_INTERFACE_LIBRARY_INSTALL() +TEST_INTERFACE_LIBRARY_NO_BASE_DIR() +TEST_INTERFACE_LIBRARY_WITH_BASE_DIR() +TEST_INTERFACE_LIBRARY_NO_SOURCES() diff --git a/test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt new file mode 100644 index 0000000..6ac5955 --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt @@ -0,0 +1,110 @@ +## Main +# +# Test CMDEF_INSTALL with multiple targets +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_MULTIPLE_CALLS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test multiple CMDEF_INSTALL calls work independently. +# +# Creates two targets and installs them separately, verifying +# each gets its own INSTALL commands without interference. +# +# () +# +FUNCTION(TEST_MULTIPLE_INSTALL_CALLS) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mlib1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mlib2 + TYPE STATIC + VERSION 2.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET mlib1-shared) + CMDEF_INSTALL(TARGET mlib2-static) + + TEST_GET_INSTALL_TARGETS_CALLS(targets_calls) + + IF(NOT targets_calls MATCHES "TARGETS;mlib1-shared") + MESSAGE(FATAL_ERROR "INSTALL(TARGETS) not found for mlib1-shared") + ENDIF() + IF(NOT targets_calls MATCHES "TARGETS;mlib2-static") + MESSAGE(FATAL_ERROR "INSTALL(TARGETS) not found for mlib2-static") + ENDIF() + + TEST_GET_INSTALL_EXPORT_CALLS(export_calls) + IF(NOT export_calls MATCHES "EXPORT;mlib1-shared") + MESSAGE(FATAL_ERROR "INSTALL(EXPORT) not found for mlib1-shared") + ENDIF() + IF(NOT export_calls MATCHES "EXPORT;mlib2-static") + MESSAGE(FATAL_ERROR "INSTALL(EXPORT) not found for mlib2-static") + ENDIF() + + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("LIBRARY" "${CMDEF_LIBRARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("RUNTIME" "${CMDEF_BINARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("BUNDLE" "${CMDEF_BINARY_INSTALL_DIR}") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("PUBLIC_HEADER" "${CMDEF_INCLUDE_INSTALL_DIR}") +ENDFUNCTION() + +## +# Test multiple CMDEF_INSTALL calls with property verification. +# +# Creates two targets and installs them separately, verifying all target +# properties set by CMDEF_INSTALL are correctly configured for both targets. +# +# () +# +FUNCTION(TEST_MULTIPLE_INSTALL_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mplib1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mplib2 + TYPE STATIC + VERSION 2.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET mplib1-shared) + CMDEF_INSTALL(TARGET mplib2-static) + + TEST_CHECK_TARGET_PROPERTY(mplib1-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_PROPERTY(mplib2-static CMDEF_INSTALL ON) + + TEST_CHECK_TARGET_PROPERTY(mplib1-shared TYPE "SHARED_LIBRARY") + TEST_CHECK_TARGET_PROPERTY(mplib2-static TYPE "STATIC_LIBRARY") + + TEST_CHECK_TARGET_LACKS_PROPERTY(mplib1-shared CMDEF_NAMESPACE) + TEST_CHECK_TARGET_LACKS_PROPERTY(mplib2-static CMDEF_NAMESPACE) + TEST_CHECK_TARGET_LACKS_PROPERTY(mplib1-shared CMDEF_NO_INSTALL_CONFIG) + TEST_CHECK_TARGET_LACKS_PROPERTY(mplib2-static CMDEF_NO_INSTALL_CONFIG) +ENDFUNCTION() + +TEST_MULTIPLE_INSTALL_CALLS() +TEST_MULTIPLE_INSTALL_PROPERTIES() diff --git a/test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt new file mode 100644 index 0000000..ea29d41 --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt @@ -0,0 +1,73 @@ +## Main +# +# Test CMDEF_INSTALL with NO_INSTALL_CONFIG option +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_NO_CONFIG_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test installation with NO_INSTALL_CONFIG option. +# +# Creates a library and installs it with NO_INSTALL_CONFIG ON, +# verifying INSTALL(TARGETS) is called but INSTALL(EXPORT) is not. +# +# () +# +FUNCTION(TEST_NO_INSTALL_CONFIG) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP nclib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET nclib-shared NO_INSTALL_CONFIG ON) + + TEST_INSTALL_TARGETS_EXPORT_EQUALS("nclib-shared") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + + TEST_GET_INSTALL_EXPORT_CALLS(export_calls) + IF(export_calls MATCHES "EXPORT;nclib-shared") + MESSAGE(FATAL_ERROR "INSTALL(EXPORT) should not be called with NO_INSTALL_CONFIG ON") + ENDIF() + + MESSAGE(STATUS "NO_INSTALL_CONFIG test passed") +ENDFUNCTION() + +## +# Test NO_INSTALL_CONFIG installation with property verification. +# +# Creates a library with NO_INSTALL_CONFIG and verifies all target properties +# set by CMDEF_INSTALL are correctly configured, including NO_INSTALL_CONFIG property. +# +# () +# +FUNCTION(TEST_NO_INSTALL_CONFIG_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP ncplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET ncplib-shared NO_INSTALL_CONFIG ON) + + TEST_CHECK_TARGET_PROPERTY(ncplib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_PROPERTY(ncplib-shared CMDEF_NO_INSTALL_CONFIG ON) +ENDFUNCTION() + +TEST_NO_INSTALL_CONFIG() +TEST_NO_INSTALL_CONFIG_PROPERTIES() diff --git a/test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt new file mode 100644 index 0000000..f4e8122 --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt @@ -0,0 +1,130 @@ +## Main +# +# Test CMDEF_INSTALL with shared library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_SHARED_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../library_tests.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test shared library installation with complete INSTALL command verification. +# +# Creates a shared library and verifies all INSTALL commands are called +# with correct destinations and parameters. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP slib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET slib-shared) + + LIBRARY_TESTS("slib-shared") + + TEST_CHECK_TARGET_PROPERTY(slib-shared CMDEF_INSTALL ON) +ENDFUNCTION() + +## +# Test shared library installation with property verification. +# +# Creates a shared library with include directories and verifies all target +# properties set by CMDEF_INSTALL are correctly configured. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP splib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET splib-shared) + + TEST_CHECK_TARGET_PROPERTY(splib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(splib-shared INTERFACE "$") +ENDFUNCTION() + +## +# Test shared library installation without include directories. +# +# Creates a shared library without INSTALL_INCLUDE_DIRECTORIES and verifies +# that INSTALL_INTERFACE generator expression is NOT added. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_NO_INSTALL_INCLUDES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP snilib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET snilib-shared) + + TEST_CHECK_TARGET_PROPERTY(snilib-shared CMDEF_INSTALL ON) + + TEST_CHECK_TARGET_LACKS_PROPERTY(snilib-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + + GET_TARGET_PROPERTY(include_dirs snilib-shared INTERFACE_INCLUDE_DIRECTORIES) + IF(include_dirs AND include_dirs MATCHES "INSTALL_INTERFACE") + MESSAGE(FATAL_ERROR "INTERFACE_INCLUDE_DIRECTORIES should not contain INSTALL_INTERFACE when no INSTALL_INCLUDE_DIRECTORIES. Got: ${include_dirs}") + ENDIF() +ENDFUNCTION() + +## +# Test shared library property dependencies. +# +# Verifies that CMDEF_INSTALL correctly reads and uses target properties +# to control its behavior. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_PROPERTY_DEPENDENCIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP spdlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + TEST_CHECK_TARGET_HAS_PROPERTY(spdlib-shared CMDEF_INSTALL_INCLUDE_DIRECTORIES) + TEST_CHECK_TARGET_PROPERTY(spdlib-shared TYPE "SHARED_LIBRARY") + + CMDEF_INSTALL(TARGET spdlib-shared) + + TEST_CHECK_TARGET_PROPERTY(spdlib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(spdlib-shared INTERFACE "$") +ENDFUNCTION() + +TEST_SHARED_LIBRARY_INSTALL() +TEST_SHARED_LIBRARY_PROPERTIES() +TEST_SHARED_LIBRARY_NO_INSTALL_INCLUDES() +TEST_SHARED_LIBRARY_PROPERTY_DEPENDENCIES() diff --git a/test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt new file mode 100644 index 0000000..f71f476 --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt @@ -0,0 +1,95 @@ +## Main +# +# Test CMDEF_INSTALL with static library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_STATIC_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../library_tests.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test static library installation with complete INSTALL command verification. +# +# Creates a static library and verifies all INSTALL commands are called +# with correct destinations and parameters. +# +# () +# +FUNCTION(TEST_STATIC_LIBRARY_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP alib + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET alib-static) + LIBRARY_TESTS("alib-static") +ENDFUNCTION() + +## +# Test static library installation with property verification. +# +# Creates a static library with include directories and verifies all target +# properties set by CMDEF_INSTALL are correctly configured. +# +# () +# +FUNCTION(TEST_STATIC_LIBRARY_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP stlib + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET stlib-static) + + TEST_CHECK_TARGET_PROPERTY(stlib-static CMDEF_INSTALL ON) + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(stlib-static INTERFACE "$") +ENDFUNCTION() + +## +# Test static library property dependencies. +# +# Verifies that CMDEF_INSTALL correctly reads and uses target properties +# to control its behavior for static libraries. +# +# () +# +FUNCTION(TEST_STATIC_LIBRARY_PROPERTY_DEPENDENCIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP stpdlib + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + TEST_CHECK_TARGET_HAS_PROPERTY(stpdlib-static CMDEF_INSTALL_INCLUDE_DIRECTORIES) + TEST_CHECK_TARGET_PROPERTY(stpdlib-static TYPE "STATIC_LIBRARY") + + CMDEF_INSTALL(TARGET stpdlib-static) + + TEST_CHECK_TARGET_PROPERTY(stpdlib-static CMDEF_INSTALL ON) + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(stpdlib-static INTERFACE "$") +ENDFUNCTION() + +TEST_STATIC_LIBRARY_INSTALL() +TEST_STATIC_LIBRARY_PROPERTIES() +TEST_STATIC_LIBRARY_PROPERTY_DEPENDENCIES() diff --git a/test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt new file mode 100644 index 0000000..d4667dd --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt @@ -0,0 +1,74 @@ +## Main +# +# Test CMDEF_INSTALL with specific configurations +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_CONFIGURATIONS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test installation with specific configurations. +# +# Creates a library and installs it with specific configurations, +# verifying CONFIGURATIONS parameter is passed correctly to both +# INSTALL(TARGETS) and INSTALL(EXPORT). +# +# () +# +FUNCTION(TEST_CONFIGURATIONS_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP clib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET clib-shared CONFIGURATIONS Debug Release) + + TEST_INSTALL_TARGETS_EXPORT_EQUALS("clib-shared") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + + TEST_INSTALL_TARGETS_CONFIGURATIONS_CONTAINS("Debug") + TEST_INSTALL_TARGETS_CONFIGURATIONS_CONTAINS("Release") + + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("Debug") + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("Release") + + TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake//") +ENDFUNCTION() + +## +# Test configurations installation with property verification. +# +# Creates a library with specific configurations and verifies all target +# properties set by CMDEF_INSTALL are correctly configured. +# +# () +# +FUNCTION(TEST_CONFIGURATIONS_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP cplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET cplib-shared CONFIGURATIONS Debug Release) + + TEST_CHECK_TARGET_PROPERTY(cplib-shared CMDEF_INSTALL ON) +ENDFUNCTION() + +TEST_CONFIGURATIONS_INSTALL() +TEST_CONFIGURATIONS_PROPERTIES() diff --git a/test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt b/test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt new file mode 100644 index 0000000..6bd5418 --- /dev/null +++ b/test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt @@ -0,0 +1,110 @@ +## Main +# +# Test CMDEF_INSTALL with namespace parameter +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_INSTALL_NAMESPACE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake") + +## +# Test installation with namespace parameter. +# +# Creates a library and installs it with a namespace, verifying +# INSTALL(EXPORT) is called with correct NAMESPACE and DESTINATION. +# +# () +# +FUNCTION(TEST_NAMESPACE_INSTALL) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP nlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET nlib-shared NAMESPACE nlib::) + + TEST_INSTALL_TARGETS_EXPORT_EQUALS("nlib-shared") + TEST_INSTALL_TARGETS_DESTINATION_EQUALS("ARCHIVE" "${CMDEF_LIBRARY_INSTALL_DIR}") + + TEST_INSTALL_EXPORT_NAMESPACE_EQUALS("nlib::") + TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/nlib/") + + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("DEBUG") + TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS("RELEASE") +ENDFUNCTION() + +## +# Test namespace installation with property verification. +# +# Creates a library with namespace and verifies all target properties +# set by CMDEF_INSTALL are correctly configured, including namespace property. +# +# () +# +FUNCTION(TEST_NAMESPACE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP nplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET nplib-shared NAMESPACE nplib::) + + TEST_CHECK_TARGET_PROPERTY(nplib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_PROPERTY(nplib-shared CMDEF_NAMESPACE "nplib") + TEST_CHECK_TARGET_INCLUDE_DIRECTORIES_CONTAINS(nplib-shared INTERFACE "$") + + GET_TARGET_PROPERTY(namespace_value nplib-shared CMDEF_NAMESPACE) + IF(namespace_value MATCHES "::") + MESSAGE(FATAL_ERROR "CMDEF_NAMESPACE should be stripped of '::' suffix but contains '::': ${namespace_value}") + ENDIF() +ENDFUNCTION() + +## +# Test namespace property edge cases. +# +# Verifies namespace handling with different namespace formats and +# that properties are set correctly. +# +# () +# +FUNCTION(TEST_NAMESPACE_EDGE_CASES) + TEST_CLEAR_INSTALL_CALLS() + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP neclib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET neclib-shared NAMESPACE "MyCompany::MyLib::") + + TEST_CHECK_TARGET_PROPERTY(neclib-shared CMDEF_INSTALL ON) + TEST_CHECK_TARGET_PROPERTY(neclib-shared CMDEF_NAMESPACE "MyCompany::MyLib") + + GET_TARGET_PROPERTY(complex_namespace neclib-shared CMDEF_NAMESPACE) + IF(complex_namespace MATCHES "::$") + MESSAGE(FATAL_ERROR "CMDEF_NAMESPACE should not end with '::' but does: ${complex_namespace}") + ENDIF() +ENDFUNCTION() + +TEST_NAMESPACE_INSTALL() +TEST_NAMESPACE_PROPERTIES() +TEST_NAMESPACE_EDGE_CASES() diff --git a/test/CMDEF_PACKAGE/CMakeLists.txt b/test/CMDEF_PACKAGE/CMakeLists.txt new file mode 100644 index 0000000..3d88d0c --- /dev/null +++ b/test/CMDEF_PACKAGE/CMakeLists.txt @@ -0,0 +1,21 @@ +## Main +# +# Tests for CMDEF_PACKAGE module +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") + +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/executable") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/static_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/shared_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/interface_lib") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/with_configs") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/with_cpack_config") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/multiconfig_build") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/dependency_inclusion") +TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/invalid_arguments") diff --git a/test/CMDEF_PACKAGE/README.md b/test/CMDEF_PACKAGE/README.md new file mode 100644 index 0000000..5181080 --- /dev/null +++ b/test/CMDEF_PACKAGE/README.md @@ -0,0 +1,24 @@ +# CMDEF_PACKAGE Tests + +Unit tests for the `CMDEF_PACKAGE` function. + +## Directory Structure + +### `shared_sources/` + +Contains reusable test resources - C++ source files and headers + +### `test_cases/` + +Individual test cases covering: +- Package creation (executable, shared, static, interface libraries) +- Configuration file generation and custom targets +- Multiconfig generator support and dependency handling +- Error conditions and parameter validation + +## Usage + +Run all CMDEF_PACKAGE tests: +```bash +cmake . +``` \ No newline at end of file diff --git a/test/CMDEF_PACKAGE/package_test_macros.cmake b/test/CMDEF_PACKAGE/package_test_macros.cmake new file mode 100644 index 0000000..cdd3779 --- /dev/null +++ b/test/CMDEF_PACKAGE/package_test_macros.cmake @@ -0,0 +1,183 @@ +## Main +# +# CMDEF_PACKAGE specific test helper macros +# +# This module provides specialized test macros for verifying functionality +# specific to CMDEF_PACKAGE. These macros complement the INSTALL command verification +# functions in install_override.cmake by focusing on package file creation, +# custom target verification, and package-specific properties. +# + +## +# Verify that package config file exists and contains expected content. +# +# Checks that CONFIGURE_PACKAGE_CONFIG_FILE created the expected config file +# in the build directory with the correct name pattern. +# +# ( +# // Target name used for package config file naming +# ) +# +MACRO(TEST_PACKAGE_CONFIG_FILE_EXISTS target_name) + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}Config.cmake") + IF(NOT EXISTS "${config_file}") + MESSAGE(FATAL_ERROR "Package config file should exist: ${config_file}") + ENDIF() +ENDMACRO() + +## +# Verify that package version file exists and contains expected content. +# +# Checks that WRITE_BASIC_PACKAGE_VERSION_FILE created the expected version file +# in the build directory with the correct name pattern. +# +# ( +# // Target name used for package version file naming +# ) +# +MACRO(TEST_PACKAGE_VERSION_FILE_EXISTS target_name) + SET(version_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}ConfigVersion.cmake") + IF(NOT EXISTS "${version_file}") + MESSAGE(FATAL_ERROR "Package version file should exist: ${version_file}") + ENDIF() +ENDMACRO() + +## +# Verify that package config file contains expected content. +# +# Reads the config file and checks for specific content patterns +# that should be generated by CONFIGURE_PACKAGE_CONFIG_FILE. +# +# ( +# // Target name used for package config file naming +# // Content pattern to search for in the file +# ) +# +MACRO(TEST_PACKAGE_CONFIG_FILE_CONTAINS target_name expected_content) + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}Config.cmake") + FILE(READ "${config_file}" file_content) + STRING(FIND "${file_content}" "${expected_content}" found_pos) + IF(found_pos EQUAL -1) + MESSAGE(FATAL_ERROR "Package config file should contain '${expected_content}' but content is: ${file_content}") + ENDIF() +ENDMACRO() + +## +# Verify that package version file contains expected version. +# +# Reads the version file and checks that it contains the expected version number. +# +# ( +# // Target name used for package version file naming +# // Version string that should be in the file +# ) +# +MACRO(TEST_PACKAGE_VERSION_FILE_CONTAINS target_name expected_version) + SET(version_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}ConfigVersion.cmake") + FILE(READ "${version_file}" file_content) + STRING(FIND "${file_content}" "${expected_version}" found_pos) + IF(found_pos EQUAL -1) + MESSAGE(FATAL_ERROR "Package version file should contain version '${expected_version}' but content is: ${file_content}") + ENDIF() +ENDMACRO() + +## +# Verify that PACKAGE custom target does not exist. Used in multiconf tests. +# +# Checks that ADD_CUSTOM_TARGET did not create the PACKAGE target for single-config builds. +# This target should not exist when CMAKE_BUILD_TYPE is set. +# +# () +# +MACRO(TEST_PACKAGE_CUSTOM_TARGET_NOT_EXISTS) + IF(TARGET PACKAGE) + MESSAGE(FATAL_ERROR "PACKAGE custom target should not exist for single-config builds") + ENDIF() +ENDMACRO() + +## +# Verify that CPACK_PACKAGE_VERSION is set correctly. +# +# Checks that CMDEF_PACKAGE set the CPACK_PACKAGE_VERSION variable +# to the expected version value. +# +# ( +# // Expected version string +# ) +# +MACRO(TEST_PACKAGE_CPACK_PACKAGE_VERSION expected_version) + IF(NOT DEFINED CPACK_PACKAGE_VERSION) + MESSAGE(FATAL_ERROR "CPACK_PACKAGE_VERSION should be set by CMDEF_PACKAGE") + ENDIF() + IF(NOT CPACK_PACKAGE_VERSION STREQUAL "${expected_version}") + MESSAGE(FATAL_ERROR "CPACK_PACKAGE_VERSION should be '${expected_version}' but is '${CPACK_PACKAGE_VERSION}'") + ENDIF() +ENDMACRO() + +## +# Verify that CPACK_PACKAGE_FILE_NAME is set correctly for single-config builds. +# +# Checks that CMDEF_PACKAGE set the CPACK_PACKAGE_FILE_NAME variable +# with the expected pattern for single-config builds (CMAKE_BUILD_TYPE set). +# +# ( +# // Target name to check in the file name +# // Expected version string +# ) +# +MACRO(TEST_PACKAGE_CPACK_PACKAGE_FILE_NAME target_name expected_version) + IF(NOT DEFINED CPACK_PACKAGE_FILE_NAME) + MESSAGE(FATAL_ERROR "CPACK_PACKAGE_FILE_NAME should be set by CMDEF_PACKAGE for single-config builds") + ENDIF() + + STRING(FIND "${CPACK_PACKAGE_FILE_NAME}" "${target_name}" target_found) + IF(target_found EQUAL -1) + MESSAGE(FATAL_ERROR "CPACK_PACKAGE_FILE_NAME should contain target name '${target_name}' but is '${CPACK_PACKAGE_FILE_NAME}'") + ENDIF() + + STRING(FIND "${CPACK_PACKAGE_FILE_NAME}" "v${expected_version}" version_found) + IF(version_found EQUAL -1) + MESSAGE(FATAL_ERROR "CPACK_PACKAGE_FILE_NAME should contain version 'v${expected_version}' but is '${CPACK_PACKAGE_FILE_NAME}'") + ENDIF() +ENDMACRO() + +## +# Verify that CPACK_OUTPUT_CONFIG_FILE is set correctly for multiconfig builds. +# +# Checks that CMDEF_PACKAGE set the CPACK_OUTPUT_CONFIG_FILE variable +# for multiconfig builds (CMAKE_BUILD_TYPE not set). +# +# () +# +MACRO(TEST_PACKAGE_CPACK_OUTPUT_CONFIG_FILE) + IF(NOT DEFINED CPACK_OUTPUT_CONFIG_FILE) + MESSAGE(FATAL_ERROR "CPACK_OUTPUT_CONFIG_FILE should be set by CMDEF_PACKAGE for multiconfig builds") + ENDIF() + + STRING(FIND "${CPACK_OUTPUT_CONFIG_FILE}" "CMDEFCPackConfig.cmake" config_found) + IF(config_found EQUAL -1) + MESSAGE(FATAL_ERROR "CPACK_OUTPUT_CONFIG_FILE should contain 'CMDEFCPackConfig.cmake' but is '${CPACK_OUTPUT_CONFIG_FILE}'") + ENDIF() +ENDMACRO() + +## +# Perform comprehensive package validation checks for single-config builds. +# +# Consolidates the complete test pattern used across all test cases. +# Verifies config file creation, version file creation, config file content, +# version content, absence of custom target, and CPACK variables for single-config builds. +# +# ( +# // Target name for file naming and CPACK validation +# // Expected version string +# ) +# +MACRO(TEST_PACKAGE_EXTENDED_CHECKS target_name version) + TEST_PACKAGE_CONFIG_FILE_EXISTS("${target_name}") + TEST_PACKAGE_VERSION_FILE_EXISTS("${target_name}") + TEST_PACKAGE_CONFIG_FILE_CONTAINS("${target_name}" "@PACKAGE_INIT@") + TEST_PACKAGE_VERSION_FILE_CONTAINS("${target_name}" "${version}") + TEST_PACKAGE_CUSTOM_TARGET_NOT_EXISTS() + TEST_PACKAGE_CPACK_PACKAGE_VERSION("${version}") + TEST_PACKAGE_CPACK_PACKAGE_FILE_NAME("${target_name}" "${version}") +ENDMACRO() diff --git a/test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake b/test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake new file mode 100644 index 0000000..4280bf3 --- /dev/null +++ b/test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake @@ -0,0 +1,2 @@ +# Custom CPack configuration for testing CPACK_CONFIG_FILE parameter +SET(CPACK_GENERATOR "ZIP") diff --git a/test/CMDEF_PACKAGE/shared_sources/include/library.h b/test/CMDEF_PACKAGE/shared_sources/include/library.h new file mode 100644 index 0000000..1ebbc9c --- /dev/null +++ b/test/CMDEF_PACKAGE/shared_sources/include/library.h @@ -0,0 +1,4 @@ +#pragma once + +int get_library_version(); +void library_function(); diff --git a/test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake b/test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake new file mode 100644 index 0000000..deb6953 --- /dev/null +++ b/test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake @@ -0,0 +1,13 @@ +## Shared Sources Configuration +# +# Defines common paths and variables for CMDEF_PACKAGE tests +# + +SET(SHARED_SOURCES_DIR "${CMAKE_CURRENT_LIST_DIR}") + +SET(LIBRARY_SOURCE_FILE "${SHARED_SOURCES_DIR}/src/library.cpp") +SET(MAIN_SOURCE_FILE "${SHARED_SOURCES_DIR}/src/main.cpp") + +SET(LIBRARY_INCLUDE_DIR "${SHARED_SOURCES_DIR}/include") + +SET(CUSTOM_CPACK_CONFIG_FILE "${SHARED_SOURCES_DIR}/custom_cpack_config.cmake") diff --git a/test/CMDEF_PACKAGE/shared_sources/src/library.cpp b/test/CMDEF_PACKAGE/shared_sources/src/library.cpp new file mode 100644 index 0000000..58e00ed --- /dev/null +++ b/test/CMDEF_PACKAGE/shared_sources/src/library.cpp @@ -0,0 +1,9 @@ +#include "library.h" + +int get_library_version() { + return 100; +} + +void library_function() { + // Simple library function for testing +} diff --git a/test/CMDEF_PACKAGE/shared_sources/src/main.cpp b/test/CMDEF_PACKAGE/shared_sources/src/main.cpp new file mode 100644 index 0000000..63ab199 --- /dev/null +++ b/test/CMDEF_PACKAGE/shared_sources/src/main.cpp @@ -0,0 +1,6 @@ +#include "library.h" + +int main() { + library_function(); + return get_library_version(); +} diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt new file mode 100644 index 0000000..ce9f5dd --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt @@ -0,0 +1,41 @@ +## Main Orchestrator +# +# Test CMDEF_PACKAGE dependency inclusion - Orchestrator for focused test cases +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_DEPENDENCY_INCLUSION_TEST) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +TEST_RUN("basic_dependency_inclusion") +TEST_RUN("dependency_exclusion") +TEST_RUN("transitive_dependencies") + +TEST_RUN_AND_CHECK_OUTPUT( + "transitive_dependency_warning" + WARNING_MESSAGE "Library transitivedep-shared is a dependency of directdep-shared, but is.*NOT an IMPORTED target and it is not direct dependency of main-shared" +) + +TEST_RUN_AND_CHECK_OUTPUT( + "test_fail/non_installed_dependency" + "Dependency notinstalled-shared is not installed" +) + +TEST_RUN_AND_CHECK_OUTPUT( + "test_fail/namespace_mismatch" + "NAMESPACE of target \"nsdep-shared\" is not the same as the main target's" +) + +TEST_RUN_AND_CHECK_OUTPUT( + "test_fail/multiple_errors" + "Dependency notinstalleddep-shared is not installed" +) + + diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt new file mode 100644 index 0000000..2ca48bc --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt @@ -0,0 +1,221 @@ +## Basic Dependency Inclusion Tests +# +# Test core dependency inclusion functionality in CMDEF_PACKAGE +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_BASIC_DEPENDENCY_INCLUSION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../cache_var.cmake") + +## +# Test basic single dependency inclusion. +# +# Creates two libraries with a dependency relationship, installs them, and packages the main target, +# verifying that the dependency is correctly included in the generated config file. +# +# () +# +FUNCTION(TEST_SINGLE_DEPENDENCY_INCLUSION) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP deplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mainlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(mainlib-shared PUBLIC deplib-shared) + + CMDEF_INSTALL(TARGET deplib-shared NAMESPACE mainlib-shared::) + CMDEF_INSTALL(TARGET mainlib-shared NAMESPACE mainlib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET mainlib-shared + VERSION 1.6.3 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/mainlib-shared/") + + TEST_PACKAGE_EXTENDED_CHECKS("mainlib-shared" "1.6.3") + + TEST_PACKAGE_CONFIG_FILE_CONTAINS("mainlib-shared" "__INCLUDE_TARGETS_CONFIGS(\"deplib-shared;mainlib-shared\")") + + # Verify dependency is properly configured for export + GET_TARGET_PROPERTY(dep_install_status deplib-shared CMDEF_INSTALL) + IF(NOT dep_install_status) + MESSAGE(FATAL_ERROR "Dependency should be marked as installed by CMDEF_INSTALL") + ENDIF() + + # Verify namespace consistency + GET_TARGET_PROPERTY(main_ns mainlib-shared CMDEF_NAMESPACE) + GET_TARGET_PROPERTY(dep_ns deplib-shared CMDEF_NAMESPACE) + IF(NOT main_ns STREQUAL "mainlib-shared") + MESSAGE(FATAL_ERROR "Main target namespace should be 'mainlib-shared' but is '${main_ns}'") + ENDIF() + IF(NOT dep_ns STREQUAL "mainlib-shared") + MESSAGE(FATAL_ERROR "Dependency namespace should be 'mainlib-shared' but is '${dep_ns}'") + ENDIF() + + # Verify link libraries are set correctly + GET_TARGET_PROPERTY(linked_libs mainlib-shared INTERFACE_LINK_LIBRARIES) + IF(NOT "deplib-shared" IN_LIST linked_libs) + MESSAGE(FATAL_ERROR "mainlib-shared should link to deplib-shared but linked libraries are: ${linked_libs}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test multiple dependencies inclusion with properties. +# +# Creates libraries with dependencies and include directories, verifying all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_MULTIPLE_DEPENDENCIES_WITH_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP basicdep1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP basicdep2 + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mainmulti + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + TARGET_LINK_LIBRARIES(mainmulti-shared PUBLIC basicdep1-shared basicdep2-static) + + CMDEF_INSTALL(TARGET basicdep1-shared NAMESPACE mainmulti-shared::) + CMDEF_INSTALL(TARGET basicdep2-static NAMESPACE mainmulti-shared::) + CMDEF_INSTALL(TARGET mainmulti-shared NAMESPACE mainmulti-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET mainmulti-shared + VERSION 0.8.4 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("mainmulti-shared" "0.8.4") + + TEST_PACKAGE_CONFIG_FILE_CONTAINS("mainmulti-shared" "__INCLUDE_TARGETS_CONFIGS(\"basicdep1-shared;basicdep2-static;mainmulti-shared\")") + + GET_TARGET_PROPERTY(dep1_install_status basicdep1-shared CMDEF_INSTALL) + GET_TARGET_PROPERTY(dep2_install_status basicdep2-static CMDEF_INSTALL) + IF(NOT dep1_install_status OR NOT dep2_install_status) + MESSAGE(FATAL_ERROR "All dependencies should be marked as installed by CMDEF_INSTALL") + ENDIF() + + GET_TARGET_PROPERTY(main_ns mainmulti-shared CMDEF_NAMESPACE) + GET_TARGET_PROPERTY(dep1_ns basicdep1-shared CMDEF_NAMESPACE) + GET_TARGET_PROPERTY(dep2_ns basicdep2-static CMDEF_NAMESPACE) + IF(NOT main_ns STREQUAL "mainmulti-shared" OR NOT dep1_ns STREQUAL "mainmulti-shared" OR NOT dep2_ns STREQUAL "mainmulti-shared") + MESSAGE(FATAL_ERROR "All targets should have matching namespace 'mainmulti-shared'") + ENDIF() + + GET_TARGET_PROPERTY(linked_libs mainmulti-shared INTERFACE_LINK_LIBRARIES) + IF(NOT "basicdep1-shared" IN_LIST linked_libs OR NOT "basicdep2-static" IN_LIST linked_libs) + MESSAGE(FATAL_ERROR "mainmulti-shared should link to both dependencies but linked libraries are: ${linked_libs}") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test mixed target types as dependencies. +# +# Creates dependencies of different types (SHARED, STATIC, INTERFACE) +# and verifies all CMDEF library targets are included regardless of type. +# +# () +# +FUNCTION(TEST_MIXED_TARGET_TYPES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP shareddep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP staticdep + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP interfacedep + TYPE INTERFACE + VERSION 1.0.0 + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mixedmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(mixedmain-shared PUBLIC shareddep-shared staticdep-static interfacedep-interface) + + CMDEF_INSTALL(TARGET shareddep-shared NAMESPACE mixedmain-shared::) + CMDEF_INSTALL(TARGET staticdep-static NAMESPACE mixedmain-shared::) + CMDEF_INSTALL(TARGET interfacedep-interface NAMESPACE mixedmain-shared::) + CMDEF_INSTALL(TARGET mixedmain-shared NAMESPACE mixedmain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET mixedmain-shared + VERSION 2.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("mixedmain-shared" "2.0.0") + + TEST_PACKAGE_CONFIG_FILE_CONTAINS("mixedmain-shared" "__INCLUDE_TARGETS_CONFIGS(\"shareddep-shared;staticdep-static;interfacedep-interface;mixedmain-shared\")") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_SINGLE_DEPENDENCY_INCLUSION() +TEST_MULTIPLE_DEPENDENCIES_WITH_PROPERTIES() +TEST_MIXED_TARGET_TYPES() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt new file mode 100644 index 0000000..be890ee --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt @@ -0,0 +1,253 @@ +## Dependency Exclusion Tests +# +# Test exclusion of non-CMDEF and IMPORTED targets from dependency inclusion +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_DEPENDENCY_EXCLUSION_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../cache_var.cmake") + +## +# Test exclusion of non-CMDEF targets. +# +# Creates standard CMake targets and system libraries that should be +# excluded from dependency inclusion. +# +# () +# +FUNCTION(TEST_NON_CMDEF_EXCLUSION) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + # Create CMDEF dependency that should be included + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP cmdefdep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + # Create main library + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP exclusionmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + # Create standard CMake targets that should be excluded + ADD_LIBRARY(standard_shared SHARED "${LIBRARY_SOURCE_FILE}") + ADD_LIBRARY(standard_static STATIC "${LIBRARY_SOURCE_FILE}") + + # Find system library that should be excluded + FIND_PACKAGE(Threads QUIET) + + # Link all dependencies + TARGET_LINK_LIBRARIES(exclusionmain-shared PUBLIC cmdefdep-shared standard_shared standard_static) + IF(Threads_FOUND) + TARGET_LINK_LIBRARIES(exclusionmain-shared PUBLIC Threads::Threads) + ENDIF() + + # Install only CMDEF targets + CMDEF_INSTALL(TARGET cmdefdep-shared NAMESPACE exclusionmain-shared::) + CMDEF_INSTALL(TARGET exclusionmain-shared NAMESPACE exclusionmain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET exclusionmain-shared + VERSION 3.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("exclusionmain-shared" "3.0.0") + + # Verify only CMDEF targets are included + TEST_PACKAGE_CONFIG_FILE_CONTAINS("exclusionmain-shared" "__INCLUDE_TARGETS_CONFIGS(\"cmdefdep-shared;exclusionmain-shared\")") + + # Verify non-CMDEF targets are excluded + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/exclusionmain-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "standard_shared" standard_shared_found) + STRING(FIND "${config_content}" "standard_static" standard_static_found) + STRING(FIND "${config_content}" "Threads::Threads" threads_found) + + IF(NOT standard_shared_found EQUAL -1) + MESSAGE(FATAL_ERROR "standard_shared should be excluded from config file") + ENDIF() + IF(NOT standard_static_found EQUAL -1) + MESSAGE(FATAL_ERROR "standard_static should be excluded from config file") + ENDIF() + IF(NOT threads_found EQUAL -1) + MESSAGE(FATAL_ERROR "Threads::Threads should be excluded from config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test exclusion of IMPORTED targets. +# +# Creates IMPORTED targets that should be excluded from dependency inclusion. +# +# () +# +FUNCTION(TEST_IMPORTED_TARGET_EXCLUSION) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + # Create CMDEF dependency that should be included + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP cmdefdep2 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + # Create main library + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP importmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + ADD_LIBRARY(imported_shared SHARED IMPORTED) + IF(WIN32) + SET_TARGET_PROPERTIES(imported_shared PROPERTIES + IMPORTED_LOCATION "/fake/path/shared.dll" + IMPORTED_IMPLIB "/fake/path/shared.lib" + ) + ELSE() + SET_TARGET_PROPERTIES(imported_shared PROPERTIES IMPORTED_LOCATION "/fake/path/libshared.so") + ENDIF() + + ADD_LIBRARY(imported_static STATIC IMPORTED) + IF(WIN32) + SET_TARGET_PROPERTIES(imported_static PROPERTIES IMPORTED_LOCATION "/fake/path/static.lib") + ELSE() + SET_TARGET_PROPERTIES(imported_static PROPERTIES IMPORTED_LOCATION "/fake/path/libstatic.a") + ENDIF() + + TARGET_LINK_LIBRARIES(importmain-shared PUBLIC cmdefdep2-shared imported_shared imported_static) + + CMDEF_INSTALL(TARGET cmdefdep2-shared NAMESPACE importmain-shared::) + CMDEF_INSTALL(TARGET importmain-shared NAMESPACE importmain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET importmain-shared + VERSION 4.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("importmain-shared" "4.0.0") + + TEST_PACKAGE_CONFIG_FILE_CONTAINS("importmain-shared" "__INCLUDE_TARGETS_CONFIGS(\"cmdefdep2-shared;importmain-shared\")") + + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/importmain-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "imported_shared" imported_shared_found) + STRING(FIND "${config_content}" "imported_static" imported_static_found) + + IF(NOT imported_shared_found EQUAL -1) + MESSAGE(FATAL_ERROR "imported_shared should be excluded from config file") + ENDIF() + IF(NOT imported_static_found EQUAL -1) + MESSAGE(FATAL_ERROR "imported_static should be excluded from config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test mixed scenarios with CMDEF and non-CMDEF dependencies. +# +# Creates a complex scenario with multiple types of dependencies to verify +# that only CMDEF targets are included while others are properly excluded. +# +# () +# +FUNCTION(TEST_MIXED_EXCLUSION_SCENARIOS) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP included1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP included2 + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mixedmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + ADD_LIBRARY(excluded_standard SHARED "${LIBRARY_SOURCE_FILE}") + ADD_LIBRARY(excluded_imported SHARED IMPORTED) + IF(WIN32) + SET_TARGET_PROPERTIES(excluded_imported PROPERTIES + IMPORTED_LOCATION "/fake/path/lib.dll" + IMPORTED_IMPLIB "/fake/path/lib.lib" + ) + ELSE() + SET_TARGET_PROPERTIES(excluded_imported PROPERTIES IMPORTED_LOCATION "/fake/path/lib.so") + ENDIF() + + TARGET_LINK_LIBRARIES(mixedmain-shared PUBLIC + included1-shared + included2-static + excluded_standard + excluded_imported + ) + + # Install only CMDEF targets + CMDEF_INSTALL(TARGET included1-shared NAMESPACE mixedmain-shared::) + CMDEF_INSTALL(TARGET included2-static NAMESPACE mixedmain-shared::) + CMDEF_INSTALL(TARGET mixedmain-shared NAMESPACE mixedmain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET mixedmain-shared + VERSION 5.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("mixedmain-shared" "5.0.0") + + # Verify only CMDEF targets are included (sorted alphabetically) + TEST_PACKAGE_CONFIG_FILE_CONTAINS("mixedmain-shared" "__INCLUDE_TARGETS_CONFIGS(\"included1-shared;included2-static;mixedmain-shared\")") + + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/mixedmain-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "excluded_standard" excluded_standard_found) + STRING(FIND "${config_content}" "excluded_imported" excluded_imported_found) + + IF(NOT excluded_standard_found EQUAL -1) + MESSAGE(FATAL_ERROR "excluded_standard should be excluded from config file") + ENDIF() + IF(NOT excluded_imported_found EQUAL -1) + MESSAGE(FATAL_ERROR "excluded_imported should be excluded from config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_NON_CMDEF_EXCLUSION() +TEST_IMPORTED_TARGET_EXCLUSION() +TEST_MIXED_EXCLUSION_SCENARIOS() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt new file mode 100644 index 0000000..f43511c --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt @@ -0,0 +1,87 @@ +## Test Fail Case - Multiple Dependency Errors +# +# Test error condition with multiple types of dependency errors +# This test is designed to fail and should only be run when CMDEF_TEST_FAIL_CASES is set +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_MULTIPLE_ERRORS_FAIL_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../cache_var.cmake") + +## +# Test multiple dependency errors. +# +# Creates a scenario with multiple types of errors to verify +# that CMDEF_PACKAGE fails appropriately. +# +# This test should FAIL with the first error encountered +# +# () +# +FUNCTION(TEST_MULTIPLE_DEPENDENCY_ERRORS_FAIL) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP installeddep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP notinstalleddep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP wrongnamespacedep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multierror + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(multierror-shared PUBLIC + installeddep-shared + notinstalleddep-shared + wrongnamespacedep-shared + ) + + # Install some targets with correct namespace + CMDEF_INSTALL(TARGET installeddep-shared NAMESPACE multierror-shared::) + CMDEF_INSTALL(TARGET multierror-shared NAMESPACE multierror-shared::) + + CMDEF_INSTALL(TARGET wrongnamespacedep-shared NAMESPACE wrong::) + + # Don't install notinstalleddep-shared + + # This should FAIL due to dependency issues + CMDEF_PACKAGE( + MAIN_TARGET multierror-shared + VERSION 1.0.0 + ) + + MESSAGE(FATAL_ERROR "TEST FAILURE: CMDEF_PACKAGE should have failed due to dependency errors") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_MULTIPLE_DEPENDENCY_ERRORS_FAIL() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt new file mode 100644 index 0000000..d0cb4a6 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt @@ -0,0 +1,72 @@ +## Test Fail Case - Namespace Mismatch +# +# Test error condition when dependencies have mismatched namespaces +# This test is designed to fail and should only be run when CMDEF_TEST_FAIL_CASES is set +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_NAMESPACE_MISMATCH_FAIL_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../cache_var.cmake") + +## +# Test namespace mismatch error. +# +# Creates libraries with mismatched namespaces and verifies that +# CMDEF_PACKAGE fails with appropriate error message. +# +# This test should FAIL with namespace mismatch error +# +# () +# +FUNCTION(TEST_NAMESPACE_MISMATCH_FAIL) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP nsdep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP nsmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(nsmain-shared PUBLIC nsdep-shared) + + # Install with DIFFERENT namespaces (this should cause error) + CMDEF_INSTALL(TARGET nsdep-shared NAMESPACE different-namespace::) + CMDEF_INSTALL(TARGET nsmain-shared NAMESPACE nsmain-shared::) + + GET_TARGET_PROPERTY(main_ns nsmain-shared CMDEF_NAMESPACE) + GET_TARGET_PROPERTY(dep_ns nsdep-shared CMDEF_NAMESPACE) + + IF(main_ns STREQUAL dep_ns) + MESSAGE(FATAL_ERROR "Test setup error: namespaces should be different for this test") + ENDIF() + + MESSAGE(STATUS "Expected FATAL_ERROR: Namespace mismatch between '${main_ns}' and '${dep_ns}'") + + # This should FAIL due to namespace mismatch + CMDEF_PACKAGE( + MAIN_TARGET nsmain-shared + VERSION 1.0.0 + ) + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_NAMESPACE_MISMATCH_FAIL() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt new file mode 100644 index 0000000..66c828b --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt @@ -0,0 +1,66 @@ +## Test Fail Case - Non-Installed Dependency +# +# Test error condition when a CMDEF dependency is not installed +# This test is designed to fail and should only be run when CMDEF_TEST_FAIL_CASES is set +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_NON_INSTALLED_DEPENDENCY_FAIL_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../cache_var.cmake") + +## +# Test non-installed CMDEF dependency error. +# +# Creates a CMDEF dependency that is not installed and verifies that +# CMDEF_PACKAGE fails with appropriate error message. +# +# This test should FAIL with: "Dependency is not installed" +# +# () +# +FUNCTION(TEST_NON_INSTALLED_CMDEF_DEPENDENCY_FAIL) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP notinstalled + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP failmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(failmain-shared PUBLIC notinstalled-shared) + + # Install only the main target, NOT the dependency + CMDEF_INSTALL(TARGET failmain-shared NAMESPACE failmain-shared::) + + # This should FAIL because notinstalled-shared is not installed + MESSAGE(STATUS "Expected FATAL_ERROR: Dependency notinstalled-shared is not installed") + + CMDEF_PACKAGE( + MAIN_TARGET failmain-shared + VERSION 1.0.0 + ) + + MESSAGE(FATAL_ERROR "TEST FAILURE: CMDEF_PACKAGE should have failed due to non-installed dependency") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_NON_INSTALLED_CMDEF_DEPENDENCY_FAIL() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt new file mode 100644 index 0000000..915b2d4 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt @@ -0,0 +1,251 @@ +## Transitive Dependencies Tests +# +# Test multi-level dependency chains and warning generation +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_TRANSITIVE_DEPENDENCIES_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../package_test_macros.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../cache_var.cmake") + +## +# Test multi-level dependency chains. +# +# Creates a chain: main -> dep1 -> dep2 and verifies that only direct +# dependencies are included while transitive ones generate warnings. +# +# () +# +FUNCTION(TEST_MULTI_LEVEL_DEPENDENCIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + # + # Create dependency chain: main -> dep1 -> dep2 + # + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP transdep2 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP transdep1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multilevel + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(transdep1-shared PUBLIC transdep2-shared) + TARGET_LINK_LIBRARIES(multilevel-shared PUBLIC transdep1-shared) + + CMDEF_INSTALL(TARGET transdep2-shared NAMESPACE multilevel-shared::) + CMDEF_INSTALL(TARGET transdep1-shared NAMESPACE multilevel-shared::) + CMDEF_INSTALL(TARGET multilevel-shared NAMESPACE multilevel-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET multilevel-shared + VERSION 1.5.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("multilevel-shared" "1.5.0") + + # Verify only direct dependencies are included (transdep1-shared, multilevel-shared) + # transdep2-shared should not be included as it's a transitive dependency + TEST_PACKAGE_CONFIG_FILE_CONTAINS("multilevel-shared" "__INCLUDE_TARGETS_CONFIGS(\"transdep1-shared;multilevel-shared\")") + + # Verify transitive dependency is not in the config file + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/multilevel-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "transdep2-shared" dep2_found) + IF(NOT dep2_found EQUAL -1) + MESSAGE(FATAL_ERROR "Transitive dependency transdep2-shared should not be included in config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test deeper dependency chains. +# +# Creates a longer chain: main -> dep1 -> dep2 -> dep3 and verifies +# that only the direct dependency is included. +# +# () +# +FUNCTION(TEST_DEEP_DEPENDENCY_CHAIN) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + # + # Create deep dependency chain: main -> dep1 -> dep2 -> dep3 + # + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP deepdep3 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP deepdep2 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP deepdep1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP deepmain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(deepdep2-shared PUBLIC deepdep3-shared) + TARGET_LINK_LIBRARIES(deepdep1-shared PUBLIC deepdep2-shared) + TARGET_LINK_LIBRARIES(deepmain-shared PUBLIC deepdep1-shared) + + CMDEF_INSTALL(TARGET deepdep3-shared NAMESPACE deepmain-shared::) + CMDEF_INSTALL(TARGET deepdep2-shared NAMESPACE deepmain-shared::) + CMDEF_INSTALL(TARGET deepdep1-shared NAMESPACE deepmain-shared::) + CMDEF_INSTALL(TARGET deepmain-shared NAMESPACE deepmain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET deepmain-shared + VERSION 2.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("deepmain-shared" "2.0.0") + + # Verify only direct dependency is included + TEST_PACKAGE_CONFIG_FILE_CONTAINS("deepmain-shared" "__INCLUDE_TARGETS_CONFIGS(\"deepdep1-shared;deepmain-shared\")") + + # Verify transitive dependencies are not in the config file + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/deepmain-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "deepdep2-shared" dep2_found) + STRING(FIND "${config_content}" "deepdep3-shared" dep3_found) + + IF(NOT dep2_found EQUAL -1) + MESSAGE(FATAL_ERROR "Transitive dependency deepdep2-shared should not be included in config file") + ENDIF() + IF(NOT dep3_found EQUAL -1) + MESSAGE(FATAL_ERROR "Transitive dependency deepdep3-shared should not be included in config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test multiple direct dependencies with transitive chains. +# +# Creates: main -> dep1 -> dep1_sub, main -> dep2 -> dep2_sub +# Verifies only direct dependencies (dep1, dep2) are included. +# +# () +# +FUNCTION(TEST_MULTIPLE_DIRECT_WITH_TRANSITIVE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multidep1sub + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multidep2sub + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multidep1 + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multidep2 + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP multimain + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + TARGET_LINK_LIBRARIES(multidep1-shared PUBLIC multidep1sub-shared) + TARGET_LINK_LIBRARIES(multidep2-static PUBLIC multidep2sub-static) + TARGET_LINK_LIBRARIES(multimain-shared PUBLIC multidep1-shared multidep2-static) + + CMDEF_INSTALL(TARGET multidep1sub-shared NAMESPACE multimain-shared::) + CMDEF_INSTALL(TARGET multidep2sub-static NAMESPACE multimain-shared::) + CMDEF_INSTALL(TARGET multidep1-shared NAMESPACE multimain-shared::) + CMDEF_INSTALL(TARGET multidep2-static NAMESPACE multimain-shared::) + CMDEF_INSTALL(TARGET multimain-shared NAMESPACE multimain-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET multimain-shared + VERSION 3.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("multimain-shared" "3.0.0") + + # Verify only direct dependencies are included (sorted alphabetically) + TEST_PACKAGE_CONFIG_FILE_CONTAINS("multimain-shared" "__INCLUDE_TARGETS_CONFIGS(\"multidep1-shared;multidep2-static;multimain-shared\")") + + # Verify transitive dependencies are not in the config file + SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/multimain-sharedConfig.cmake") + FILE(READ "${config_file}" config_content) + STRING(FIND "${config_content}" "multidep1sub-shared" dep1sub_found) + STRING(FIND "${config_content}" "multidep2sub-static" dep2sub_found) + + IF(NOT dep1sub_found EQUAL -1) + MESSAGE(FATAL_ERROR "Transitive dependency multidep1sub-shared should not be included in config file") + ENDIF() + IF(NOT dep2sub_found EQUAL -1) + MESSAGE(FATAL_ERROR "Transitive dependency multidep2sub-static should not be included in config file") + ENDIF() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_MULTI_LEVEL_DEPENDENCIES() +TEST_DEEP_DEPENDENCY_CHAIN() +TEST_MULTIPLE_DIRECT_WITH_TRANSITIVE() diff --git a/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependency_warning/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependency_warning/CMakeLists.txt new file mode 100644 index 0000000..0ff751b --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependency_warning/CMakeLists.txt @@ -0,0 +1,49 @@ +## Transitive Dependency Warning Test +# +# Test that warning is generated for transitive dependencies that are not imported +# and not directly linked to the main target. +# +# This test creates a dependency chain: main -> direct_dep -> transitive_dep +# and verifies that the warning message is generated for transitive_dep. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_TRANSITIVE_DEPENDENCY_WARNING_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP transitivedep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" +) + +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP directdep + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" +) + +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP main + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" +) + +TARGET_LINK_LIBRARIES(directdep-shared PUBLIC transitivedep-shared) +TARGET_LINK_LIBRARIES(main-shared PUBLIC directdep-shared) + +CMDEF_INSTALL(TARGET transitivedep-shared NAMESPACE main-shared::) +CMDEF_INSTALL(TARGET directdep-shared NAMESPACE main-shared::) +CMDEF_INSTALL(TARGET main-shared NAMESPACE main-shared::) + +CMDEF_PACKAGE( + MAIN_TARGET main-shared + VERSION 1.0.0 +) diff --git a/test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt new file mode 100644 index 0000000..90e886e --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt @@ -0,0 +1,83 @@ +## Main +# +# Test CMDEF_PACKAGE with executable +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_EXECUTABLE_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test executable packaging with complete verification. +# +# Creates an executable, installs it, and packages it, verifying all +# INSTALL commands, file creation, and package properties. +# +# () +# +FUNCTION(TEST_EXECUTABLE_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_EXECUTABLE( + TARGET elib + VERSION 1.0.0 + SOURCES "${MAIN_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET elib NAMESPACE elib::) + + CMDEF_PACKAGE( + MAIN_TARGET elib + VERSION 1.2.3 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/elib/") + + TEST_PACKAGE_EXTENDED_CHECKS("elib" "1.2.3") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test executable packaging properties verification. +# +# Creates an executable and verifies all properties set by CMDEF_PACKAGE +# are correctly configured. +# +# () +# +FUNCTION(TEST_EXECUTABLE_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_EXECUTABLE( + TARGET eplib + VERSION 1.0.0 + SOURCES "${MAIN_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET eplib NAMESPACE eplib::) + + CMDEF_PACKAGE( + MAIN_TARGET eplib + VERSION 2.0.0 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("eplib" "2.0.0") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_EXECUTABLE_PACKAGE() +TEST_EXECUTABLE_PACKAGE_PROPERTIES() diff --git a/test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt new file mode 100644 index 0000000..8ddff32 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt @@ -0,0 +1,89 @@ +## Main +# +# Test CMDEF_PACKAGE with interface library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_INTERFACE_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test interface library packaging with complete verification. +# +# Creates an interface library, installs it, and packages it, verifying all +# INSTALL commands, file creation, and interface-specific properties. +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP ilib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET ilib-interface NAMESPACE ilib-interface::) + + CMDEF_PACKAGE( + MAIN_TARGET ilib-interface + VERSION 1.8.2 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/ilib-interface/") + + TEST_PACKAGE_EXTENDED_CHECKS("ilib-interface" "1.8.2") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) + + MESSAGE(STATUS "Interface library package test passed") +ENDFUNCTION() + +## +# Test interface library packaging properties verification. +# +# Creates an interface library with sources and verifies all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_INTERFACE_LIBRARY_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP iplib + TYPE INTERFACE + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET iplib-interface NAMESPACE iplib-interface::) + + CMDEF_PACKAGE( + MAIN_TARGET iplib-interface + VERSION 0.9.1 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("iplib-interface" "0.9.1") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_INTERFACE_LIBRARY_PACKAGE() +TEST_INTERFACE_LIBRARY_PACKAGE_PROPERTIES() diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt new file mode 100644 index 0000000..061acab --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt @@ -0,0 +1,36 @@ +## Main +# +# Test CMDEF_PACKAGE invalid argument combinations +# +# Tests various error conditions and invalid parameter combinations +# for the CMDEF_PACKAGE function. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_INVALID_ARGUMENTS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") + +TEST_RUN_AND_CHECK_OUTPUT("missing_main_target" + FATAL_ERROR_MESSAGE "MAIN_TARGET" +) + +TEST_RUN_AND_CHECK_OUTPUT("missing_version" + FATAL_ERROR_MESSAGE "VERSION" +) + +TEST_RUN_AND_CHECK_OUTPUT("invalid_main_target" + FATAL_ERROR_MESSAGE "Not a valid CMake target:" +) + +TEST_RUN_AND_CHECK_OUTPUT("main_target_not_cmake_target" + FATAL_ERROR_MESSAGE "Not a valid CMake target:" +) + +TEST_RUN_AND_CHECK_OUTPUT("invalid_version_format" + FATAL_ERROR_MESSAGE "not in valid format" +) diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt new file mode 100644 index 0000000..95a0244 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt @@ -0,0 +1,16 @@ +## Main +# +# Test invalid MAIN_TARGET parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_INVALID_MAIN_TARGET_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") + +CMDEF_PACKAGE( + MAIN_TARGET nonexistent_target + VERSION 1.0.0 +) diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt new file mode 100644 index 0000000..8e67965 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt @@ -0,0 +1,27 @@ +## Main +# +# Test invalid VERSION format error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_INVALID_VERSION_FORMAT_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" +) + +CMDEF_INSTALL(TARGET testlib-shared NAMESPACE testlib-shared::) + +CMDEF_PACKAGE( + MAIN_TARGET testlib-shared + VERSION "invalid_version_format" +) diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt new file mode 100644 index 0000000..eb8f758 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt @@ -0,0 +1,16 @@ +## Main +# +# Test MAIN_TARGET that is not a valid CMake target +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_MAIN_TARGET_NOT_CMAKE_TARGET_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") + +CMDEF_PACKAGE( + MAIN_TARGET "not_a_target" + VERSION 1.0.0 +) diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt new file mode 100644 index 0000000..e2ed808 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt @@ -0,0 +1,15 @@ +## Main +# +# Test missing MAIN_TARGET parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_MISSING_MAIN_TARGET_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") + +CMDEF_PACKAGE( + VERSION 1.0.0 +) diff --git a/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt new file mode 100644 index 0000000..7a9fad8 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt @@ -0,0 +1,23 @@ +## Main +# +# Test missing VERSION parameter error +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_MISSING_VERSION_ERROR_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../shared_sources/shared_sources.cmake") + +CMDEF_ADD_LIBRARY( + LIBRARY_GROUP testlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" +) + +CMDEF_PACKAGE( + MAIN_TARGET testlib-shared +) diff --git a/test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt new file mode 100644 index 0000000..6ac246a --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt @@ -0,0 +1,96 @@ +## Main +# +# Test CMDEF_PACKAGE with multiconfig build (CMAKE_BUILD_TYPE not set) +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_MULTICONFIG_BUILD_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Verify that PACKAGE custom target exists. +# +# Checks that ADD_CUSTOM_TARGET created the PACKAGE target for multiconfig builds. +# This target should only exist when CMAKE_BUILD_TYPE is not set. +# +# () +# +MACRO(TEST_PACKAGE_CUSTOM_TARGET_EXISTS) + IF(NOT TARGET PACKAGE) + MESSAGE(FATAL_ERROR "PACKAGE custom target should exist for multiconfig builds") + ENDIF() +ENDMACRO() + +## +# Verify that PACKAGE custom target has correct properties. +# +# Checks that the PACKAGE target has the expected properties set by CMDEF_PACKAGE, +# including FOLDER property and dependencies. +# +# ( +# // Main target that should be a dependency of PACKAGE target +# ) +# +MACRO(TEST_PACKAGE_CUSTOM_TARGET_PROPERTIES main_target) + GET_TARGET_PROPERTY(folder_prop PACKAGE FOLDER) + IF(NOT folder_prop STREQUAL "${CMDEF_MULTICONF_FOLDER_NAME}") + MESSAGE(FATAL_ERROR "PACKAGE target FOLDER should be '${CMDEF_MULTICONF_FOLDER_NAME}' but is '${folder_prop}'") + ENDIF() + + GET_TARGET_PROPERTY(dependencies PACKAGE MANUALLY_ADDED_DEPENDENCIES) + IF(NOT dependencies OR NOT "${main_target}" IN_LIST dependencies) + MESSAGE(FATAL_ERROR "PACKAGE target should depend on '${main_target}' but dependencies are: ${dependencies}") + ENDIF() +ENDMACRO() + +## +# Test multiconfig packaging with ADD_CUSTOM_TARGET verification. +# +# Creates a library, installs it, and packages it without CMAKE_BUILD_TYPE set, +# verifying that ADD_CUSTOM_TARGET creates the PACKAGE target with correct properties. +# +# () +# +FUNCTION(TEST_MULTICONFIG_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_UNSET(CMAKE_BUILD_TYPE) + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP mclib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET mclib-shared NAMESPACE mclib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET mclib-shared + VERSION 2.5.8 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/mclib-shared/") + + TEST_PACKAGE_CONFIG_FILE_EXISTS("mclib-shared") + TEST_PACKAGE_VERSION_FILE_EXISTS("mclib-shared") + TEST_PACKAGE_VERSION_FILE_CONTAINS("mclib-shared" "2.5.8") + + TEST_PACKAGE_CUSTOM_TARGET_EXISTS() + TEST_PACKAGE_CUSTOM_TARGET_PROPERTIES("mclib-shared") + + TEST_PACKAGE_CPACK_PACKAGE_VERSION("2.5.8") + TEST_PACKAGE_CPACK_OUTPUT_CONFIG_FILE() + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_MULTICONFIG_PACKAGE() diff --git a/test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt new file mode 100644 index 0000000..edd4791 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt @@ -0,0 +1,88 @@ +## Main +# +# Test CMDEF_PACKAGE with shared library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_SHARED_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test shared library packaging with complete verification. +# +# Creates a shared library, installs it, and packages it, verifying all +# INSTALL commands, file creation, and package properties. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP shlib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET shlib-shared NAMESPACE shlib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET shlib-shared + VERSION 2.1.0 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/shlib-shared/") + + TEST_PACKAGE_EXTENDED_CHECKS("shlib-shared" "2.1.0") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) + + MESSAGE(STATUS "Shared library package test passed") +ENDFUNCTION() + +## +# Test shared library packaging properties verification. +# +# Creates a shared library with include directories and verifies all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_SHARED_LIBRARY_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP shplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET shplib-shared NAMESPACE shplib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET shplib-shared + VERSION 4.2.1 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("shplib-shared" "4.2.1") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_SHARED_LIBRARY_PACKAGE() +TEST_SHARED_LIBRARY_PACKAGE_PROPERTIES() diff --git a/test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt new file mode 100644 index 0000000..8ca43cc --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt @@ -0,0 +1,88 @@ +## Main +# +# Test CMDEF_PACKAGE with static library +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_STATIC_LIB_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test static library packaging with complete verification. +# +# Creates a static library, installs it, and packages it, verifying all +# INSTALL commands, file creation, and package name suffix. +# +# () +# +FUNCTION(TEST_STATIC_LIBRARY_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP slib + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET slib-static NAMESPACE slib-static::) + + CMDEF_PACKAGE( + MAIN_TARGET slib-static + VERSION 1.5.0 + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/slib-static/") + + TEST_PACKAGE_EXTENDED_CHECKS("slib-static" "1.5.0") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) + + MESSAGE(STATUS "Static library package test passed") +ENDFUNCTION() + +## +# Test static library packaging properties verification. +# +# Creates a static library with include directories and verifies all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_STATIC_LIBRARY_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP splib + TYPE STATIC + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET splib-static NAMESPACE splib-static::) + + CMDEF_PACKAGE( + MAIN_TARGET splib-static + VERSION 3.1.4 + ) + + TEST_PACKAGE_EXTENDED_CHECKS("splib-static" "3.1.4") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_STATIC_LIBRARY_PACKAGE() +TEST_STATIC_LIBRARY_PACKAGE_PROPERTIES() diff --git a/test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt new file mode 100644 index 0000000..b18bf36 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt @@ -0,0 +1,90 @@ +## Main +# +# Test CMDEF_PACKAGE with CONFIGURATIONS parameter +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_WITH_CONFIGS_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test packaging with specific configurations. +# +# Creates a library, installs it with specific configurations, and packages it +# with the same configurations, verifying configuration handling. +# +# () +# +FUNCTION(TEST_CONFIGURATIONS_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP clib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET clib-shared CONFIGURATIONS Debug Release NAMESPACE clib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET clib-shared + VERSION 1.3.7 + CONFIGURATIONS Debug Release + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/clib-shared/") + + TEST_PACKAGE_EXTENDED_CHECKS("clib-shared" "1.3.7") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) + + MESSAGE(STATUS "Configurations package test passed") +ENDFUNCTION() + +## +# Test configurations packaging properties verification. +# +# Creates a library with specific configurations and verifies all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_CONFIGURATIONS_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP cplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET cplib-shared CONFIGURATIONS Debug MinSizeRel NAMESPACE cplib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET cplib-shared + VERSION 2.4.6 + CONFIGURATIONS Debug MinSizeRel + ) + + TEST_PACKAGE_EXTENDED_CHECKS("cplib-shared" "2.4.6") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_CONFIGURATIONS_PACKAGE() +TEST_CONFIGURATIONS_PACKAGE_PROPERTIES() diff --git a/test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt b/test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt new file mode 100644 index 0000000..d795f02 --- /dev/null +++ b/test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt @@ -0,0 +1,88 @@ +## Main +# +# Test CMDEF_PACKAGE with custom CPACK_CONFIG_FILE parameter +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_PACKAGE_WITH_CPACK_CONFIG_TEST) + +FIND_PACKAGE(CMLIB REQUIRED) + +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../cache_var.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../CMDEFConfig.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../install_override.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../shared_sources/shared_sources.cmake") +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../package_test_macros.cmake") + +## +# Test packaging with custom CPack config file. +# +# Creates a library, installs it, and packages it with a custom CPack config file, +# verifying that the custom config is used instead of the auto-generated one. +# +# () +# +FUNCTION(TEST_CUSTOM_CPACK_CONFIG_PACKAGE) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Release") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP cclib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + ) + + CMDEF_INSTALL(TARGET cclib-shared NAMESPACE cclib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET cclib-shared + VERSION 1.9.5 + CPACK_CONFIG_FILE "${CUSTOM_CPACK_CONFIG_FILE}" + ) + + TEST_INSTALL_FILES_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/cclib-shared/") + + TEST_PACKAGE_EXTENDED_CHECKS("cclib-shared" "1.9.5") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +## +# Test custom CPack config packaging properties verification. +# +# Creates a library with custom CPack config and verifies all +# properties set by CMDEF_PACKAGE are correctly configured. +# +# () +# +FUNCTION(TEST_CUSTOM_CPACK_CONFIG_PACKAGE_PROPERTIES) + TEST_CLEAR_INSTALL_CALLS() + + CACHE_VAR_FORCE_SET(CMAKE_BUILD_TYPE "Debug") + + CMDEF_ADD_LIBRARY( + LIBRARY_GROUP ccplib + TYPE SHARED + VERSION 1.0.0 + SOURCES "${LIBRARY_SOURCE_FILE}" + INSTALL_INCLUDE_DIRECTORIES "${LIBRARY_INCLUDE_DIR}" + ) + + CMDEF_INSTALL(TARGET ccplib-shared NAMESPACE ccplib-shared::) + + CMDEF_PACKAGE( + MAIN_TARGET ccplib-shared + VERSION 3.7.1 + CPACK_CONFIG_FILE "${CUSTOM_CPACK_CONFIG_FILE}" + ) + + TEST_PACKAGE_EXTENDED_CHECKS("ccplib-shared" "3.7.1") + + CACHE_VAR_RESTORE(CMAKE_BUILD_TYPE) +ENDFUNCTION() + +TEST_CUSTOM_CPACK_CONFIG_PACKAGE() +TEST_CUSTOM_CPACK_CONFIG_PACKAGE_PROPERTIES() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..4bbe515 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +## Main +# +# Run all tests :) +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.22) +PROJECT(CMDEF_ADD_EXECUTABLE_TEST) + +ADD_SUBDIRECTORY(CMDEF_ENV) +ADD_SUBDIRECTORY(CMDEF_ADD_EXECUTABLE) +ADD_SUBDIRECTORY(CMDEF_ADD_LIBRARY) +ADD_SUBDIRECTORY(CMDEF_INSTALL) +ADD_SUBDIRECTORY(CMDEF_PACKAGE) diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..fbd0308 --- /dev/null +++ b/test/README.md @@ -0,0 +1,65 @@ +# CMDEF Test Suite + +Comprehensive test suite for the CMDEF (CMake Definition Framework) component library. + +## Test Modules + +Currently tested functionality + +- **`CMDEF_ADD_EXECUTABLE`** +- **`CMDEF_ADD_LIBRARY`** +- **`CMDEF_ENV`** +- **`CMDEF_INSTALL`** +- **`CMDEF_PACKAGE`** + +### Test Structure + +Tests are organized into subdirectories, each containing a `CMakeLists.txt` file that tests specific functionality. + +Each CMDEF_* directory has a test_cases directory which contains individual test cases. + +If test resources are shared between test cases, they are placed in a `shared_sources` directory. +(exceptions can apply of reasoned). + +In `shared_sources` directory there is a `shared_sources.cmake` file which defines variables for test resources. +This file is included by all test cases which needs test files to implement/run the test. + +Tests are designed as it run on Linux based systems as an main developemnt platform. Other supported platforms have platform specific directories which are included automatically when running on those platforms. + +## Test Framework + +- `TEST.cmake` - common test macros and functions to run tests and check required conditions. +- `install_override.cmake` - INSTALL command override to intercept and verify all cmake INSTALL calls use by CMDEF* functions. +- `cache_var.cmake` - Macros to force set and restore cache variables. + +### Platform/OS Detection + +To detect platform to execute tests valid only for a given platform +CMDEF_OS* variables are used. + +CMDEF_OS* varaibles are properly tested thus it shall have a correct value and can be used to determine the platform to decide which tests shall be run. + +### Test Resource Creation and Maintenance + +When external resources are needed to test a functionality + +- they are created from scratch. +- There are no external dependencies to download or install. +- There shall be no dynamic creation of test resources (C++ files, rc files etc.) during a test run. + Exceptions can apply if reasoned. + +## Running Tests + +**All tests are designed to be run from a clean source tree.** + +### Run All Tests + +```bash +cmake . +``` + +### Clean Up + +```bash +git clean -xfd . +``` diff --git a/test/TEST.cmake b/test/TEST.cmake new file mode 100644 index 0000000..865e2de --- /dev/null +++ b/test/TEST.cmake @@ -0,0 +1,253 @@ +## Main +# +# Test macros for CMDEF tests +# + +# Find CMLIB package which provides CMLIB_PARSE_ARGUMENTS +FIND_PACKAGE(CMLIB REQUIRED) + +# +# var - varialbe name of value +# +MACRO(TEST_VAR_DEFINED var) + IF(NOT DEFINED ${var}) + MESSAGE(FATAL_ERROR "Variable ${var} is not defined") + ENDIF() +ENDMACRO() + +# +# var - varialbe name of value +# +MACRO(TEST_VAR_NOT_DEFINED var) + IF(DEFINED ${var}) + MESSAGE(FATAL_ERROR "Variable ${var} is defined") + ENDIF() +ENDMACRO() + +# +# var - varialbe name of value +# +MACRO(TEST_VAR_TRUE var) + IF(NOT ${var}) + MESSAGE(FATAL_ERROR "var '${var}' is not true") + ENDIF() +ENDMACRO() + +# +# var - varialbe name of first value +# +MACRO(TEST_VAR_FALSE var) + IF(${var}) + MESSAGE(FATAL_ERROR "var '${var}' is not false") + ENDIF() +ENDMACRO() + +# +# var_a - varialbe name of first value +# var_b - varialbe name of second value +# +MACRO(TEST_VAR_EQUAL var_a var_b) + IF(NOT ("${${var_a}}" STREQUAL "${${var_b}}")) + MESSAGE(FATAL_ERROR "Variable ${var_a}(${${var_a}}) is not equal to ${var_b}(${${var_b}})") + ENDIF() +ENDMACRO() + +# +# var_a - varialbe name of first value +# var_b - varialbe name of second value +# +MACRO(TEST_VAR_NOT_EQUAL var_a var_b) + IF(("${${var_a}}" STREQUAL "${${var_b}}")) + MESSAGE(FATAL_ERROR "Variable ${var_a}(${${var_a}}) is not equal to ${var_b}(${${var_b}})") + ENDIF() +ENDMACRO() + +# +# var - variable name to check +# expected_value - expected value to compare against +# +MACRO(TEST_VAR_VALUE_EQUAL var expected_value) + TEST_VAR_DEFINED(${var}) + IF(NOT "${${var}}" STREQUAL "${expected_value}") + MESSAGE(FATAL_ERROR "Variable ${var} should be '${expected_value}' but is '${${var}}'") + ENDIF() +ENDMACRO() + +# +# test - Path to the test directory containing a CMakeLists.txt file +# +# Runs a test by executing its CMakeLists.txt file. In script mode, runs the file directly. +# In normal mode, creates a build directory and configures the test there. +# Fails with a detailed error message if the test fails. +# +FUNCTION(TEST_RUN test) + MESSAGE(STATUS "TEST ${test}") + SET(result_variable 0) + SET(error_variable "") + FILE(TO_CMAKE_PATH "${test}" working_dir) + IF(NOT IS_ABSOLUTE "${working_dir}") + SET(working_dir "${CMAKE_CURRENT_LIST_DIR}/${working_dir}") + ENDIF() + IF(NOT EXISTS "${working_dir}") + MESSAGE(FATAL_ERROR "test does not exist: ${working_dir}") + ENDIF() + + IF(DEFINED CMAKE_SCRIPT_MODE_FILE) + EXECUTE_PROCESS( + COMMAND "${CMAKE_COMMAND}" -P "${working_dir}/CMakeLists.txt" + WORKING_DIRECTORY "${working_dir}" + RESULT_VARIABLE result_variable + ERROR_VARIABLE error_variable + OUTPUT_VARIABLE output_variable + ) + ELSE() + EXECUTE_PROCESS( + COMMAND "${CMAKE_COMMAND}" -E make_directory "${working_dir}/build" + RESULT_VARIABLE mkdir_result + ) + IF(NOT mkdir_result EQUAL 0) + MESSAGE(FATAL_ERROR "Failed to create build directory for test: ${test}") + ENDIF() + + EXECUTE_PROCESS( + COMMAND "${CMAKE_COMMAND}" "${working_dir}" + WORKING_DIRECTORY "${working_dir}/build" + RESULT_VARIABLE result_variable + ERROR_VARIABLE error_variable + OUTPUT_VARIABLE output_variable + ) + ENDIF() + + IF(result_variable GREATER 0) + MESSAGE(FATAL_ERROR "Test '${test}' failed with '${result_variable}'\nError: ${error_variable}\nOutput: ${output_variable}") + ENDIF() +ENDFUNCTION() + +# +# Function to run a test and check its output +# Usage: +# ( +# WARNING_MESSAGE # Check warning in stdout +# FATAL_ERROR_MESSAGE # Check fatal error in stderr +# ) +FUNCTION(TEST_RUN_AND_CHECK_OUTPUT test_name) + MESSAGE(STATUS "TEST FAIL ${test_name}") + CMLIB_PARSE_ARGUMENTS( + PREFIX TEST_RUN + ONE_VALUE WARNING_MESSAGE WARNING_ERROR_MESSAGE FATAL_ERROR_MESSAGE + P_ARGN ${ARGN} + ) + GET_FILENAME_COMPONENT(_file_name "${test_name}" NAME) + GET_FILENAME_COMPONENT(_dir_name "${test_name}" DIRECTORY) + IF(_dir_name STREQUAL _file_name) + MESSAGE(FATAL_ERROR "Only name of the test could be there!") + ENDIF() + + SET(working_dir "${CMAKE_CURRENT_LIST_DIR}") + FILE(MAKE_DIRECTORY "${working_dir}/build") + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} "../${test_name}" + WORKING_DIRECTORY "${working_dir}/build" + OUTPUT_VARIABLE output + ERROR_VARIABLE error + RESULT_VARIABLE result + ) + FILE(REMOVE_RECURSE "${working_dir}/build") + + IF(DEFINED TEST_RUN_WARNING_MESSAGE) + IF(NOT error MATCHES "${TEST_RUN_WARNING_MESSAGE}") + MESSAGE(FATAL_ERROR "Expected WARNING message not found in output: ${TEST_RUN_WARNING_MESSAGE}") + ENDIF() + + IF(NOT result EQUAL 0) + MESSAGE(FATAL_ERROR "Expected process to succeed but it failed") + ENDIF() + ENDIF() + + IF(DEFINED TEST_RUN_FATAL_ERROR_MESSAGE) + IF(NOT error MATCHES "${TEST_RUN_FATAL_ERROR_MESSAGE}") + MESSAGE(FATAL_ERROR "Expected FATAL_ERROR message not found in output: ${TEST_RUN_FATAL_ERROR_MESSAGE}") + ENDIF() + + IF(result EQUAL 0) + MESSAGE(FATAL_ERROR "Expected process to fail but it succeeded") + ENDIF() + ENDIF() +ENDFUNCTION() + + +## +# Verify target has specific property set. +# +# Checks that a target has the specified property defined (not empty/unset). +# This is used to verify property dependencies in CMDEF_INSTALL. +# +# ( +# // Target name to check +# // Property name that should be set +# ) +# +MACRO(TEST_CHECK_TARGET_HAS_PROPERTY target property) + GET_TARGET_PROPERTY(prop_value ${target} ${property}) + IF(NOT prop_value) + MESSAGE(FATAL_ERROR "Target ${target} should have property ${property} set but it is not set or empty") + ENDIF() +ENDMACRO() + + +## +# Verify target does NOT have specific property set. +# +# Checks that a target does not have the specified property defined or it is empty. +# This is used to verify conditional behavior in CMDEF_INSTALL. +# +# ( +# // Target name to check +# // Property name that should NOT be set +# ) +# +MACRO(TEST_CHECK_TARGET_LACKS_PROPERTY target property) + GET_TARGET_PROPERTY(prop_value ${target} ${property}) + IF(prop_value) + MESSAGE(FATAL_ERROR "Target ${target} should NOT have property ${property} set but it is set to: ${prop_value}") + ENDIF() +ENDMACRO() + + +## +# Verify target property has exact expected value. +# +# Checks that a target's property matches the expected value exactly using string comparison. +# This is used for precise property validation in CMDEF tests. +# +# ( +# // Target name to check +# // Property name to verify +# // Exact value the property should have +# ) +# +FUNCTION(TEST_CHECK_TARGET_PROPERTY target property expected_value) + GET_PROPERTY(actual_value TARGET ${target} PROPERTY ${property}) + IF(NOT actual_value STREQUAL "${expected_value}") + MESSAGE(FATAL_ERROR "${property} property is not set correctly for target ${target}. Expected '${expected_value}', got '${actual_value}'") + ENDIF() +ENDFUNCTION() + +## +# Verify target property contains expected pattern. +# +# Checks that a target's property contains the expected pattern using regex matching. +# This is used for flexible property validation when exact matching is not required. +# +# ( +# // Target name to check +# // Property name to verify +# // Pattern/regex that the property should contain +# ) +# +FUNCTION(TEST_CHECK_TARGET_PROPERTY_CONTAINS target property expected_value) + GET_PROPERTY(actual_value TARGET ${target} PROPERTY ${property}) + IF(NOT actual_value MATCHES "${expected_value}") + MESSAGE(FATAL_ERROR "${property} property is not set correctly for target ${target}. Expected to contain '${expected_value}', got '${actual_value}'") + ENDIF() +ENDFUNCTION() \ No newline at end of file diff --git a/test/cache_var.cmake b/test/cache_var.cmake new file mode 100644 index 0000000..b719637 --- /dev/null +++ b/test/cache_var.cmake @@ -0,0 +1,79 @@ +## +# Cache Variable Management Functions for CMDEF Tests +# +# This file provides utilities for safely manipulating CMake cache variables +# in test environments with proper backup and restoration capabilities. +# + +## +# Force set a cache variable and store original value for restoration. +# +# Stores the current cache variable value (if exists) in a global property +# and then force sets the cache variable to the new value. The original +# state can be restored later using CACHE_VAR_RESTORE. +# +# (var_name, value) +# +FUNCTION(CACHE_VAR_FORCE_SET var_name value) + GET_PROPERTY(was_defined CACHE ${var_name} PROPERTY VALUE SET) + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_WAS_DEFINED_${var_name} ${was_defined}) + + IF(was_defined) + GET_PROPERTY(original_value CACHE ${var_name} PROPERTY VALUE) + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_ORIGINAL_${var_name} "${original_value}") + ENDIF() + + SET(${var_name} "${value}" CACHE STRING "Test override" FORCE) +ENDFUNCTION() + +## +# Unset a cache variable and store original value for restoration. +# +# Stores the current cache variable value (if exists) in a global property +# and then unsets the cache variable. The original state can be restored +# later using CACHE_VAR_RESTORE. +# +# Note: This function only handles cache variables, not normal variables. +# +# (var_name) +# +FUNCTION(CACHE_VAR_FORCE_UNSET var_name) + GET_PROPERTY(was_defined CACHE ${var_name} PROPERTY VALUE SET) + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_WAS_DEFINED_${var_name} ${was_defined}) + + IF(was_defined) + GET_PROPERTY(original_value CACHE ${var_name} PROPERTY VALUE) + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_ORIGINAL_${var_name} "${original_value}") + ENDIF() + + UNSET(${var_name} CACHE) +ENDFUNCTION() + +## +# Restore a cache variable to its original state. +# +# Restores a cache variable that was previously modified using +# CACHE_VAR_FORCE_SET or CACHE_VAR_FORCE_UNSET to its original state. +# Cleans up the global properties used for storage. +# +# (var_name) +# +FUNCTION(CACHE_VAR_RESTORE var_name) + GET_PROPERTY(was_defined GLOBAL PROPERTY CACHE_VAR_WAS_DEFINED_${var_name} SET) + IF(NOT was_defined) + MESSAGE(FATAL_ERROR "No stored information found for cache variable '${var_name}'. Cannot restore.") + RETURN() + ENDIF() + + GET_PROPERTY(originally_defined GLOBAL PROPERTY CACHE_VAR_WAS_DEFINED_${var_name}) + + IF(originally_defined) + GET_PROPERTY(original_value GLOBAL PROPERTY CACHE_VAR_ORIGINAL_${var_name}) + SET(${var_name} "${original_value}" CACHE STRING "Restored after test" FORCE) + ELSE() + UNSET(${var_name} CACHE) + ENDIF() + + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_WAS_DEFINED_${var_name}) + SET_PROPERTY(GLOBAL PROPERTY CACHE_VAR_ORIGINAL_${var_name}) +ENDFUNCTION() diff --git a/test/install_override.cmake b/test/install_override.cmake new file mode 100644 index 0000000..31a66b1 --- /dev/null +++ b/test/install_override.cmake @@ -0,0 +1,302 @@ +## Main +# +# INSTALL command override for CMDEF testing +# +# This module provides macros and functions to intercept INSTALL commands +# during testing of CMDEF functionality. It overrides the built-in +# INSTALL command to collect all arguments without executing actual installation. +# Used by both CMDEF_INSTALL and CMDEF_PACKAGE tests. +# + +## +# Override INSTALL command to collect data for testing. +# +# This macro intercepts all INSTALL command calls and stores their arguments +# in separate global properties based on the INSTALL command type. The original +# INSTALL command is not executed, allowing tests to verify command parameters +# without performing actual installation. +# +# Arguments are stored in type-specific global properties: +# - CMDEF_TEST_INSTALL_TARGETS_CALLS - for INSTALL(TARGETS ...) +# - CMDEF_TEST_INSTALL_EXPORT_CALLS - for INSTALL(EXPORT ...) +# - CMDEF_TEST_INSTALL_DIRECTORY_CALLS - for INSTALL(DIRECTORY ...) +# - CMDEF_TEST_INSTALL_FILES_CALLS - for INSTALL(FILES ...) +# +# ( +# ... +# ) +# +MACRO(INSTALL) + SET(install_args ${ARGN}) + LIST(GET install_args 0 install_type) + + IF(install_type STREQUAL "TARGETS") + SET_PROPERTY(GLOBAL APPEND PROPERTY CMDEF_TEST_INSTALL_TARGETS_CALLS "${ARGN}") + ELSEIF(install_type STREQUAL "EXPORT") + SET_PROPERTY(GLOBAL APPEND PROPERTY CMDEF_TEST_INSTALL_EXPORT_CALLS "${ARGN}") + ELSEIF(install_type STREQUAL "DIRECTORY") + SET_PROPERTY(GLOBAL APPEND PROPERTY CMDEF_TEST_INSTALL_DIRECTORY_CALLS "${ARGN}") + ELSEIF(install_type STREQUAL "FILES") + SET_PROPERTY(GLOBAL APPEND PROPERTY CMDEF_TEST_INSTALL_FILES_CALLS "${ARGN}") + ELSE() + SET_PROPERTY(GLOBAL APPEND PROPERTY CMDEF_TEST_INSTALL_OTHER_CALLS "${ARGN}") + ENDIF() + + GET_PROPERTY(call_count GLOBAL PROPERTY CMDEF_TEST_INSTALL_COUNT) + IF(NOT call_count) + SET(call_count 0) + ENDIF() + MATH(EXPR call_count "${call_count} + 1") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_COUNT ${call_count}) +ENDMACRO() + +## +# Retrieve collected INSTALL(TARGETS) command calls. +# +# ( +# // Variable to store the collected INSTALL(TARGETS) calls +# ) +# +FUNCTION(TEST_GET_INSTALL_TARGETS_CALLS output_var) + GET_PROPERTY(install_calls GLOBAL PROPERTY CMDEF_TEST_INSTALL_TARGETS_CALLS) + SET(${output_var} "${install_calls}" PARENT_SCOPE) +ENDFUNCTION() + +## +# Retrieve collected INSTALL(EXPORT) command calls. +# +# ( +# // Variable to store the collected INSTALL(EXPORT) calls +# ) +# +FUNCTION(TEST_GET_INSTALL_EXPORT_CALLS output_var) + GET_PROPERTY(install_calls GLOBAL PROPERTY CMDEF_TEST_INSTALL_EXPORT_CALLS) + SET(${output_var} "${install_calls}" PARENT_SCOPE) +ENDFUNCTION() + +## +# Retrieve collected INSTALL(DIRECTORY) command calls. +# +# ( +# // Variable to store the collected INSTALL(DIRECTORY) calls +# ) +# +FUNCTION(TEST_GET_INSTALL_DIRECTORY_CALLS output_var) + GET_PROPERTY(install_calls GLOBAL PROPERTY CMDEF_TEST_INSTALL_DIRECTORY_CALLS) + SET(${output_var} "${install_calls}" PARENT_SCOPE) +ENDFUNCTION() + +## +# Retrieve collected INSTALL(FILES) command calls. +# +# ( +# // Variable to store the collected INSTALL(FILES) calls +# ) +# +FUNCTION(TEST_GET_INSTALL_FILES_CALLS output_var) + GET_PROPERTY(install_calls GLOBAL PROPERTY CMDEF_TEST_INSTALL_FILES_CALLS) + SET(${output_var} "${install_calls}" PARENT_SCOPE) +ENDFUNCTION() + +## +# Clear all collected INSTALL command data. +# +# Resets all INSTALL calls lists and call count to empty/zero state. +# This should be called before each test to ensure test isolation. +# +# () +# +FUNCTION(TEST_CLEAR_INSTALL_CALLS) + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_TARGETS_CALLS "") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_EXPORT_CALLS "") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_DIRECTORY_CALLS "") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_FILES_CALLS "") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_OTHER_CALLS "") + SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_COUNT 0) +ENDFUNCTION() + +## +# Verify INSTALL(TARGETS) destination parameter. +# +# Checks that an INSTALL(TARGETS) command was called with the specified +# destination type and that the destination value matches the expected value. +# This verifies that CMDEF_INSTALL uses correct CMDEF_ENV variables for +# installation destinations. +# +# ( +# // Type of destination (ARCHIVE, LIBRARY, RUNTIME, BUNDLE, PUBLIC_HEADER) +# // Expected destination path (e.g., "lib/", "bin/", "include/") +# ) +# +FUNCTION(TEST_INSTALL_TARGETS_DESTINATION_EQUALS destination_type expected_value) + TEST_GET_INSTALL_TARGETS_CALLS(calls) + + STRING(REGEX MATCH "${destination_type};DESTINATION;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL TARGETS ${destination_type} DESTINATION not found in calls: ${calls}") + ENDIF() + + SET(actual_value "${CMAKE_MATCH_1}") + IF(NOT actual_value STREQUAL expected_value) + MESSAGE(FATAL_ERROR "INSTALL TARGETS ${destination_type} DESTINATION should be '${expected_value}' but is '${actual_value}'") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(TARGETS) EXPORT parameter. +# +# Checks that an INSTALL(TARGETS) command was called with the EXPORT parameter +# and that the export name matches the expected target name. +# +# ( +# // Expected export name (should match target name) +# ) +# +FUNCTION(TEST_INSTALL_TARGETS_EXPORT_EQUALS expected_export) + TEST_GET_INSTALL_TARGETS_CALLS(calls) + + STRING(REGEX MATCH "EXPORT;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL TARGETS EXPORT not found in calls: ${calls}") + ENDIF() + + SET(actual_export "${CMAKE_MATCH_1}") + IF(NOT actual_export STREQUAL expected_export) + MESSAGE(FATAL_ERROR "INSTALL TARGETS EXPORT should be '${expected_export}' but is '${actual_export}'") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(TARGETS) CONFIGURATIONS parameter. +# +# Checks that an INSTALL(TARGETS) command was called with the CONFIGURATIONS +# parameter and that it contains the expected configuration name. +# +# ( +# // Expected configuration name (e.g., "Debug", "Release") +# ) +# +FUNCTION(TEST_INSTALL_TARGETS_CONFIGURATIONS_CONTAINS expected_config) + TEST_GET_INSTALL_TARGETS_CALLS(calls) + + STRING(REGEX MATCH "CONFIGURATIONS;([^;]*;)*${expected_config}" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL TARGETS CONFIGURATIONS not found in calls: ${calls}") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(EXPORT) destination parameter. +# +# Checks that an INSTALL(EXPORT) command was called with the correct +# DESTINATION parameter. The destination should include the cmake subdirectory +# and namespace path when applicable. +# +# ( +# // Expected destination path (e.g., "lib/cmake/namespace/") +# ) +# +FUNCTION(TEST_INSTALL_EXPORT_DESTINATION_EQUALS expected_value) + TEST_GET_INSTALL_EXPORT_CALLS(calls) + + STRING(REGEX MATCH "EXPORT;[^;]+;CONFIGURATIONS;[^;]+;[^;]+;DESTINATION;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL EXPORT DESTINATION not found in calls: ${calls}") + ENDIF() + + SET(actual_value "${CMAKE_MATCH_1}") + IF(NOT actual_value STREQUAL expected_value) + MESSAGE(FATAL_ERROR "INSTALL EXPORT DESTINATION should be '${expected_value}' but is '${actual_value}'") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(EXPORT) NAMESPACE parameter. +# +# Checks that an INSTALL(EXPORT) command was called with the NAMESPACE +# parameter and that the namespace value matches the expected value. +# +# ( +# // Expected namespace (e.g., "mylib::") +# ) +# +FUNCTION(TEST_INSTALL_EXPORT_NAMESPACE_EQUALS expected_namespace) + TEST_GET_INSTALL_EXPORT_CALLS(calls) + + STRING(REGEX MATCH "NAMESPACE;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL EXPORT NAMESPACE not found in calls: ${calls}") + ENDIF() + + SET(actual_namespace "${CMAKE_MATCH_1}") + IF(NOT actual_namespace STREQUAL expected_namespace) + MESSAGE(FATAL_ERROR "INSTALL EXPORT NAMESPACE should be '${expected_namespace}' but is '${actual_namespace}'") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(EXPORT) CONFIGURATIONS parameter. +# +# Checks that an INSTALL(EXPORT) command was called with the CONFIGURATIONS +# parameter and that it contains the expected configuration name. +# +# ( +# // Expected configuration name (e.g., "Debug", "Release") +# ) +# +FUNCTION(TEST_INSTALL_EXPORT_CONFIGURATIONS_CONTAINS expected_config) + TEST_GET_INSTALL_EXPORT_CALLS(calls) + + STRING(REGEX MATCH "EXPORT;[^;]+;CONFIGURATIONS;([^;]*;)*${expected_config}" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL EXPORT CONFIGURATIONS not found in calls: ${calls}") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(DIRECTORY) destination parameter. +# +# Checks that an INSTALL(DIRECTORY) command was called with the correct +# DESTINATION parameter. This is used to verify include directory installation. +# +# ( +# // Expected destination path (e.g., "include/") +# ) +# +FUNCTION(TEST_INSTALL_DIRECTORY_DESTINATION_EQUALS expected_value) + TEST_GET_INSTALL_DIRECTORY_CALLS(calls) + + STRING(REGEX MATCH "DIRECTORY;[^;]+;CONFIGURATIONS;[^;]+;[^;]+;DESTINATION;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL DIRECTORY DESTINATION not found in calls: ${calls}") + ENDIF() + + SET(actual_value "${CMAKE_MATCH_1}") + IF(NOT actual_value STREQUAL expected_value) + MESSAGE(FATAL_ERROR "INSTALL DIRECTORY DESTINATION should be '${expected_value}' but is '${actual_value}'") + ENDIF() +ENDFUNCTION() + +## +# Verify INSTALL(FILES) destination parameter. +# +# Checks that an INSTALL(FILES) command was called with the correct +# DESTINATION parameter. This is used to verify package config file installation. +# +# ( +# // Expected destination path (e.g., "lib/cmake/target/") +# ) +# +FUNCTION(TEST_INSTALL_FILES_DESTINATION_EQUALS expected_value) + TEST_GET_INSTALL_FILES_CALLS(calls) + + STRING(REGEX MATCH "FILES;[^;]+;[^;]+;DESTINATION;([^;]+)" match "${calls}") + IF(NOT match) + MESSAGE(FATAL_ERROR "INSTALL FILES DESTINATION not found in calls: ${calls}") + ENDIF() + + SET(actual_value "${CMAKE_MATCH_1}") + IF(NOT actual_value STREQUAL expected_value) + MESSAGE(FATAL_ERROR "INSTALL FILES DESTINATION should be '${expected_value}' but is '${actual_value}'") + ENDIF() +ENDFUNCTION() diff --git a/version.txt b/version.txt index caeaf12..aef125e 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -version=0.2.0 +version=1.0.0