Просмотр исходного кода

OUTPUT_DIRECTORY: Support tgt genex in output artifact vars

Following variables now support target dependent generator expressions.
- CMAKE_RUNTIME_OUTPUT_DIRECTORY
- CMAKE_LIBRARY_OUTPUT_DIRECTORY
- CMAKE_ARCHIVE_OUTPUT_DIRECTORY

Fixes: #18055
Asit Dhal 5 лет назад
Родитель
Сommit
64c3857780

+ 7 - 0
Help/release/dev/OUTPUT_DIRECTORY.rst

@@ -0,0 +1,7 @@
+OUTPUT_DIRECTORY
+----------------
+
+* The variables :variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY`,
+  :variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY`, and
+  :variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY` now support target-dependent
+  generator expressions.

+ 3 - 4
Source/cmGeneratorTarget.cxx

@@ -6491,15 +6491,14 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
   if (cmProp config_outdir = this->GetProperty(configProp)) {
     // Use the user-specified per-configuration output directory.
     out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
-                                          config);
+                                          config, this);
 
     // Skip per-configuration subdirectory.
     conf.clear();
   } else if (cmProp outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
-    out =
-      cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
-
+    out = cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator,
+                                          config, this);
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
     if (out != *outdir) {

+ 27 - 0
Tests/RunCMake/ArtifactOutputDirs/ArtifactOutputDirs.cmake

@@ -0,0 +1,27 @@
+enable_language(C)
+
+if(CMAKE_IMPORT_LIBRARY_SUFFIX)
+  set(expect_dll 1)
+else()
+  set(expect_dll 0)
+endif()
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/$<IF:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>,rtlib,rtbin>")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/$<IF:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>,sharedlib,others>")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/$<IF:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>,staticlib,others>")
+
+add_executable(exe_tgt main.c)
+add_library(shared_tgt SHARED lib.c)
+add_library(static_tgt STATIC lib.c)
+
+add_custom_target(checkDirs ALL
+  COMMAND ${CMAKE_COMMAND}
+    -Dartifact_path=${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>
+    -Dexe_name=$<TARGET_FILE_NAME:exe_tgt>
+    -Dshared_name=$<TARGET_FILE_NAME:shared_tgt>
+    -Dstatic_name=$<TARGET_FILE_NAME:static_tgt>
+    -Dexpect_dll=${expect_dll}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
+  )
+
+add_dependencies(checkDirs exe_tgt shared_tgt static_tgt)

+ 3 - 0
Tests/RunCMake/ArtifactOutputDirs/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.19)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 19 - 0
Tests/RunCMake/ArtifactOutputDirs/RunCMakeTest.cmake

@@ -0,0 +1,19 @@
+include(RunCMake)
+
+function(run_cmake_and_verify_after_build case)
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${case}-build")
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
+  else()
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  run_cmake(${case})
+  run_cmake_command("${case}-build" ${CMAKE_COMMAND} --build .)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_BINARY_DIR)
+endfunction()
+
+run_cmake_and_verify_after_build(ArtifactOutputDirs)

+ 21 - 0
Tests/RunCMake/ArtifactOutputDirs/check.cmake

@@ -0,0 +1,21 @@
+set(expected ${artifact_path}/rtbin/${exe_name})
+if(NOT EXISTS "${expected}")
+  message(SEND_ERROR "executable artifact not created in the expected path:\n  ${expected}")
+endif()
+
+set(expected ${artifact_path}/staticlib/${static_name})
+if(NOT EXISTS "${expected}")
+  message(SEND_ERROR "static artifact not created in the expected path:\n  ${expected}")
+endif()
+
+if(expect_dll)
+  set(expected ${artifact_path}/rtlib/${shared_name})
+  if(NOT EXISTS "${expected}")
+    message(SEND_ERROR "dll artifact not created in the expected path:\n  ${expected}")
+  endif()
+else()
+  set(expected ${artifact_path}/sharedlib/${shared_name})
+  if(NOT EXISTS "${expected}")
+    message(SEND_ERROR "shared artifact not created in the expected path:\n  ${expected}")
+  endif()
+endif()

+ 4 - 0
Tests/RunCMake/ArtifactOutputDirs/lib.c

@@ -0,0 +1,4 @@
+int func(void)
+{
+  return 0;
+}

+ 4 - 0
Tests/RunCMake/ArtifactOutputDirs/main.c

@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}

+ 3 - 0
Tests/RunCMake/CMakeLists.txt

@@ -197,6 +197,9 @@ if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
   set(autogen_with_qt5 TRUE)
 endif ()
 add_RunCMake_test(Autogen -Dwith_qt5=${autogen_with_qt5})
+
+add_RunCMake_test(ArtifactOutputDirs)
+
 if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
     AND CMAKE_C_COMPILER_ID STREQUAL "GNU"
     AND CMAKE_GENERATOR MATCHES "^Ninja"