mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-17 07:11:52 +08:00
@@ -42,6 +42,15 @@ is equivalent to
|
|||||||
|
|
||||||
message(STATUS "Hello World!")
|
message(STATUS "Hello World!")
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
To ensure consistency of the code, the following commands are not allowed:
|
||||||
|
|
||||||
|
* ``if`` / ``elseif`` / ``else`` / ``endif``
|
||||||
|
* ``while`` / ``endwhile``
|
||||||
|
* ``foreach`` / ``endforeach``
|
||||||
|
* ``function`` / ``endfunction``
|
||||||
|
* ``macro`` / ``endmacro``
|
||||||
|
|
||||||
Evaluating Code
|
Evaluating Code
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@@ -3,15 +3,32 @@
|
|||||||
#include "cmCMakeLanguageCommand.h"
|
#include "cmCMakeLanguageCommand.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <cm/string_view>
|
||||||
|
#include <cmext/string_view>
|
||||||
|
|
||||||
#include "cmExecutionStatus.h"
|
#include "cmExecutionStatus.h"
|
||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
#include "cmRange.h"
|
#include "cmRange.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::array<cm::static_string_view, 12> InvalidCommands{
|
||||||
|
{ // clang-format off
|
||||||
|
"function"_s, "endfunction"_s,
|
||||||
|
"macro"_s, "endmacro"_s,
|
||||||
|
"if"_s, "elseif"_s, "else"_s, "endif"_s,
|
||||||
|
"while"_s, "endwhile"_s,
|
||||||
|
"foreach"_s, "endforeach"_s
|
||||||
|
} // clang-format on
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
|
bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
|
||||||
cmExecutionStatus& status)
|
cmExecutionStatus& status)
|
||||||
@@ -64,6 +81,15 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
|
|||||||
startArg = 1;
|
startArg = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure specified command is valid
|
||||||
|
// start/end flow control commands are not allowed
|
||||||
|
auto cmd = cmSystemTools::LowerCase(callCommand);
|
||||||
|
if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
|
||||||
|
InvalidCommands.cend()) {
|
||||||
|
status.SetError(cmStrCat("invalid command specified: "_s, callCommand));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
cmListFileFunction func;
|
cmListFileFunction func;
|
||||||
func.Name = callCommand;
|
func.Name = callCommand;
|
||||||
func.Line = context.Line;
|
func.Line = context.Line;
|
||||||
|
2
Tests/RunCMake/cmake_language/CallInvalidCommand.cmake
Normal file
2
Tests/RunCMake/cmake_language/CallInvalidCommand.cmake
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
cmake_language(CALL ${COMMAND})
|
4
Tests/RunCMake/cmake_language/CheckIncludeGuard.cmake
Normal file
4
Tests/RunCMake/cmake_language/CheckIncludeGuard.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
cmake_language (CALL "include_guard")
|
||||||
|
|
||||||
|
set (GUARD_VALUE 1)
|
19
Tests/RunCMake/cmake_language/CheckProject/CMakeLists.txt
Normal file
19
Tests/RunCMake/cmake_language/CheckProject/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
cmake_language (CALL cmake_minimum_required VERSION 3.17...3.18)
|
||||||
|
|
||||||
|
cmake_language (CALL project CheckProject VERSION 1.2.3 LANGUAGES C)
|
||||||
|
|
||||||
|
if (NOT PROJECT_NAME STREQUAL "CheckProject")
|
||||||
|
message (SEND_ERROR "error on project() usage.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT CheckProject_VERSION VERSION_EQUAL "1.2.3")
|
||||||
|
message (SEND_ERROR "error on project() usage.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_property (languages GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||||
|
if (NOT "C" IN_LIST languages)
|
||||||
|
message (SEND_ERROR "error on project() usage.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library (lib SHARED lib.c)
|
0
Tests/RunCMake/cmake_language/CheckProject/lib.c
Normal file
0
Tests/RunCMake/cmake_language/CheckProject/lib.c
Normal file
@@ -2,6 +2,8 @@ include(RunCMake)
|
|||||||
|
|
||||||
run_cmake(no_parameters)
|
run_cmake(no_parameters)
|
||||||
run_cmake(unknown_meta_operation)
|
run_cmake(unknown_meta_operation)
|
||||||
|
run_cmake(call_invalid_command)
|
||||||
|
run_cmake(call_valid_command)
|
||||||
run_cmake(call_double_evaluation)
|
run_cmake(call_double_evaluation)
|
||||||
run_cmake(call_expanded_command)
|
run_cmake(call_expanded_command)
|
||||||
run_cmake(call_expanded_command_and_arguments)
|
run_cmake(call_expanded_command_and_arguments)
|
||||||
|
14
Tests/RunCMake/cmake_language/call_invalid_command.cmake
Normal file
14
Tests/RunCMake/cmake_language/call_invalid_command.cmake
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
foreach (command IN ITEMS "function" "ENDFUNCTION"
|
||||||
|
"macro" "endMACRO"
|
||||||
|
"if" "elseif" "else" "endif"
|
||||||
|
"while" "endwhile"
|
||||||
|
"foreach" "endforeach")
|
||||||
|
execute_process(COMMAND "${CMAKE_COMMAND}" -DCOMMAND=${command}
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/CallInvalidCommand.cmake"
|
||||||
|
OUTPUT_QUIET ERROR_QUIET
|
||||||
|
RESULT_VARIABLE result)
|
||||||
|
if (NOT result)
|
||||||
|
message (SEND_ERROR "cmake_language(CALL ${command}) unexpectedly successfull.")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
99
Tests/RunCMake/cmake_language/call_valid_command.cmake
Normal file
99
Tests/RunCMake/cmake_language/call_valid_command.cmake
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
## check continue() usage
|
||||||
|
set (VALUE 0)
|
||||||
|
foreach (i RANGE 1 4)
|
||||||
|
set (VALUE "${i}")
|
||||||
|
cmake_language (CALL "continue")
|
||||||
|
set (VALUE "0")
|
||||||
|
endforeach()
|
||||||
|
if (NOT VALUE EQUAL "4")
|
||||||
|
message (SEND_ERROR "error on continue() usage.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
## check break() usage
|
||||||
|
set (VALUE 0)
|
||||||
|
foreach (i RANGE 1 4)
|
||||||
|
set (VALUE "${i}")
|
||||||
|
cmake_language (CALL "break")
|
||||||
|
set (VALUE 0)
|
||||||
|
endforeach()
|
||||||
|
if (NOT VALUE EQUAL "1")
|
||||||
|
message (SEND_ERROR "error on break() usage.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
## check return() usage in macro
|
||||||
|
macro (call_return_in_macro)
|
||||||
|
cmake_language (CALL "return")
|
||||||
|
set (VALUE 1)
|
||||||
|
endmacro()
|
||||||
|
function (wrapper)
|
||||||
|
call_return_in_macro()
|
||||||
|
set (VALUE 1 PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
wrapper()
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in macro.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
cmake_language (CALL "wrapper")
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in macro.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function (wrapper2)
|
||||||
|
cmake_language (CALL "call_return_in_macro")
|
||||||
|
set (VALUE 1 PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
wrapper2()
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in macro.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
cmake_language (CALL "wrapper2")
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in macro.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## check return() usage in function
|
||||||
|
function (call_return_in_function)
|
||||||
|
cmake_language (CALL "return")
|
||||||
|
set (VALUE 1 PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
call_return_in_function()
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in function.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (VALUE 0)
|
||||||
|
cmake_language (CALL "call_return_in_function")
|
||||||
|
if (NOT VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on return() usage in function.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
## check usage of include_guard()
|
||||||
|
set (GUARD_VALUE 0)
|
||||||
|
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckIncludeGuard.cmake")
|
||||||
|
if (NOT GUARD_VALUE EQUAL "1")
|
||||||
|
message (SEND_ERROR "error on include_guard() on first include.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (GUARD_VALUE 0)
|
||||||
|
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckIncludeGuard.cmake")
|
||||||
|
if (NOT GUARD_VALUE EQUAL "0")
|
||||||
|
message (SEND_ERROR "error on include_guard() on second include.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
## check usage of cmake_minimum_required() and project()
|
||||||
|
add_subdirectory (CheckProject)
|
Reference in New Issue
Block a user