From f97d1bf7d8951841b32ba448372891bdbc5912c3 Mon Sep 17 00:00:00 2001 From: John Parent Date: Wed, 21 May 2025 23:14:57 +0200 Subject: [PATCH] Visual Studio: support shortened object filenames --- Help/release/dev/short-object-names.rst | 1 + Source/cmGlobalVisualStudio10Generator.cxx | 6 + Source/cmGlobalVisualStudio10Generator.h | 2 + Source/cmLocalVisualStudio7Generator.cxx | 7 +- Source/cmLocalVisualStudioGenerator.cxx | 23 +++- Source/cmVisualStudio10TargetGenerator.cxx | 31 ++++- .../AutoExportDll/AutoExportShort.cmake | 29 +++++ .../AutoExportShortBuild-stderr.txt | 1 + .../RunCMake/AutoExportDll/RunCMakeTest.cmake | 115 ++++++++++-------- .../RunCMake/ObjectLibrary/RunCMakeTest.cmake | 2 +- .../PchDebugGenexShort-check.cmake | 17 +++ .../PchDebugGenexShort.cmake | 10 ++ .../PrecompileHeaders/RunCMakeTest.cmake | 5 +- Tests/RunCMake/UnityBuild/RunCMakeTest.cmake | 2 +- Tests/RunCMake/VS10Project/NoImpLib.cmake | 2 + .../NoImpLibShort-build-stdout.txt | 1 + .../RunCMake/VS10Project/NoImpLibShort.cmake | 5 + Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 17 ++- .../RunCMake/VS10Project/RuntimeLibrary.cmake | 2 + .../RuntimeLibraryShort-build-stdout.txt | 1 + .../VS10Project/RuntimeLibraryShort.cmake | 22 ++++ .../UnityBuildNativeGroupedShort-check.cmake | 56 +++++++++ .../UnityBuildNativeGroupedShort.cmake | 22 ++++ .../UnityBuildNativeShort-check.cmake | 45 +++++++ .../VS10Project/UnityBuildNativeShort.cmake | 14 +++ .../UnityBuildPCHShort-build-check.cmake | 10 ++ .../VS10Project/UnityBuildPCHShort.cmake | 6 + .../VsPrecompileHeadersShort-check.cmake | 66 ++++++++++ .../VsPrecompileHeadersShort.cmake | 6 + 29 files changed, 453 insertions(+), 73 deletions(-) create mode 100644 Tests/RunCMake/AutoExportDll/AutoExportShort.cmake create mode 100644 Tests/RunCMake/AutoExportDll/AutoExportShortBuild-stderr.txt create mode 100644 Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort-check.cmake create mode 100644 Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort.cmake create mode 100644 Tests/RunCMake/VS10Project/NoImpLibShort-build-stdout.txt create mode 100644 Tests/RunCMake/VS10Project/NoImpLibShort.cmake create mode 100644 Tests/RunCMake/VS10Project/RuntimeLibraryShort-build-stdout.txt create mode 100644 Tests/RunCMake/VS10Project/RuntimeLibraryShort.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort-check.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildNativeShort-check.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildNativeShort.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildPCHShort-build-check.cmake create mode 100644 Tests/RunCMake/VS10Project/UnityBuildPCHShort.cmake create mode 100644 Tests/RunCMake/VS10Project/VsPrecompileHeadersShort-check.cmake create mode 100644 Tests/RunCMake/VS10Project/VsPrecompileHeadersShort.cmake diff --git a/Help/release/dev/short-object-names.rst b/Help/release/dev/short-object-names.rst index 758bf27800..49f923da50 100644 --- a/Help/release/dev/short-object-names.rst +++ b/Help/release/dev/short-object-names.rst @@ -9,5 +9,6 @@ short-object-names - :ref:`Ninja Generators` - :ref:`Makefile Generators` + - :ref:`Visual Studio Generators` Note that the strategy implementation may differ between generators. diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 1a21b06e6f..129b326b4e 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -1563,6 +1563,12 @@ bool cmGlobalVisualStudio10Generator::IsBuildInParallelSupported() const return (vsVer && cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer15_8_0)); } + +bool cmGlobalVisualStudio10Generator::SupportsShortObjectNames() const +{ + return true; +} + std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const { std::string const& toolset = this->GetPlatformToolsetString(); diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 5248b4da9d..386e12f711 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -184,6 +184,8 @@ public: bool IsMsBuildRestoreSupported() const; bool IsBuildInParallelSupported() const; + bool SupportsShortObjectNames() const override; + protected: cmGlobalVisualStudio10Generator(cmake* cm, std::string const& name); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 471681ccfd..1d6d973125 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -2231,7 +2231,12 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( std::string cmLocalVisualStudio7Generator::GetTargetDirectory( cmGeneratorTarget const* target) const { - std::string dir = cmStrCat(target->GetName(), ".dir"); + std::string dir; + if (target->GetUseShortObjectNames()) { + dir = this->ComputeShortTargetDirectory(target); + } else { + dir = cmStrCat(target->GetName(), ".dir"); + } return dir; } diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index ae953d571b..9d33b13608 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -51,8 +51,14 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames( for (auto const& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectNameLower = cmSystemTools::LowerCase( - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())); + std::string baseObjectName; + if (gt->GetUseShortObjectNames()) { + baseObjectName = this->GetShortObjectFileName(*sf); + } else { + baseObjectName = + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); + } + std::string objectNameLower = cmSystemTools::LowerCase(baseObjectName); if (custom_ext) { objectNameLower += custom_ext; } else { @@ -67,8 +73,13 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames( for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName = - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); + std::string objectName; + if (gt->GetUseShortObjectNames()) { + objectName = this->GetShortObjectFileName(*sf); + } else { + objectName = + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); + } if (custom_ext) { objectName += custom_ext; } else { @@ -86,6 +97,10 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames( std::string cmLocalVisualStudioGenerator::GetObjectOutputRoot() const { + if (this->UseShortObjectNames()) { + return cmStrCat(this->GetCurrentBinaryDirectory(), '/', + this->GetGlobalGenerator()->GetShortBinaryOutputDir()); + } return this->GetCurrentBinaryDirectory(); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 13d4b42b6d..9ab525c41a 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2721,6 +2721,18 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) this->WriteExcludeFromBuild(e2, exclude_configs); } + if (this->GlobalGenerator->UseShortObjectNames()) { + std::string outputName = "ObjectFileName"; + if (si.Source->GetLanguage() == "CUDA"_s) { + outputName = "CompileOut"; + } + e2.Element( + outputName, + cmStrCat("$(IntDir)", + this->LocalGenerator->GetShortObjectFileName(*si.Source), + ".obj")); + } + this->FinishWritingSource(e2, toolSettings); } else if (fs && fs->GetType() == "CXX_MODULES"_s) { this->GeneratorTarget->Makefile->IssueMessage( @@ -3078,9 +3090,20 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( for (std::string const& config : this->Configurations) { std::string const cond = this->CalcCondition(config); + std::string fullIntermediateDir = + cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/'); + cmSystemTools::MakeDirectory(fullIntermediateDir); + std::string intermediateDir = + this->LocalGenerator->MaybeRelativeToCurBinDir(fullIntermediateDir); + ConvertToWindowsSlash(intermediateDir); + if (ttype >= cmStateEnums::UTILITY) { - e1.WritePlatformConfigTag( - "IntDir", cond, R"($(Platform)\$(Configuration)\$(ProjectName)\)"); + if (this->GlobalGenerator->UseShortObjectNames()) { + e1.WritePlatformConfigTag("IntDir", cond, intermediateDir); + } else { + e1.WritePlatformConfigTag( + "IntDir", cond, R"($(Platform)\$(Configuration)\$(ProjectName)\)"); + } } else { if (ttype == cmStateEnums::SHARED_LIBRARY || ttype == cmStateEnums::MODULE_LIBRARY || @@ -3092,9 +3115,6 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( } } - std::string intermediateDir = - this->LocalGenerator->MaybeRelativeToCurBinDir(cmStrCat( - this->GeneratorTarget->GetSupportDirectory(), '/', config, '/')); std::string outDir; std::string targetNameFull; if (ttype == cmStateEnums::OBJECT_LIBRARY) { @@ -3104,7 +3124,6 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions( outDir = cmStrCat(this->GeneratorTarget->GetDirectory(config), '/'); targetNameFull = this->GeneratorTarget->GetFullName(config); } - ConvertToWindowsSlash(intermediateDir); ConvertToWindowsSlash(outDir); e1.WritePlatformConfigTag("OutDir", cond, outDir); diff --git a/Tests/RunCMake/AutoExportDll/AutoExportShort.cmake b/Tests/RunCMake/AutoExportDll/AutoExportShort.cmake new file mode 100644 index 0000000000..08ee5d467e --- /dev/null +++ b/Tests/RunCMake/AutoExportDll/AutoExportShort.cmake @@ -0,0 +1,29 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +project(autoexport) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin) +add_subdirectory(sub) +add_library(objlib OBJECT objlib.c) +set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1) +add_library(autoexport SHARED hello.cxx world.cxx foo.c $) +add_library(autoexport3 SHARED cppCLI.cxx) +if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600 + AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") + set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "") +endif() + +add_executable(say say.cxx) +if(MSVC) + set_target_properties(say PROPERTIES ENABLE_EXPORTS ON) + add_library(autoexport_for_exec SHARED hello2.c) + target_link_libraries(autoexport_for_exec say) + if(NOT MSVC_VERSION VERSION_LESS 1600 AND + NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") + enable_language(ASM_MASM) + target_sources(autoexport PRIVATE nop.asm) + set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh) + target_compile_definitions(say PRIVATE HAS_JUSTNOP) + endif() +endif() +target_link_libraries(say autoexport autoexport2 autoexport3) diff --git a/Tests/RunCMake/AutoExportDll/AutoExportShortBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportShortBuild-stderr.txt new file mode 100644 index 0000000000..d483c2ce1b --- /dev/null +++ b/Tests/RunCMake/AutoExportDll/AutoExportShortBuild-stderr.txt @@ -0,0 +1 @@ +^.*$ diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake index 3c8b2c6ee2..a2acf8be3a 100644 --- a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake +++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake @@ -1,63 +1,70 @@ include(RunCMake) set(RunCMake_TEST_NO_CLEAN TRUE) -set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build") -# start by cleaning up because we don't clean up along the way -file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") -# configure the AutoExport test -run_cmake(AutoExport) -unset(RunCMake_TEST_OPTIONS) -# don't run this test on Watcom or Borland make as it is not supported -if(RunCMake_GENERATOR MATCHES "Watcom WMake|Borland Makefiles") - return() -endif() -if(CMAKE_CXX_COMPILER_ID STREQUAL "OrangeC") - return() -endif() -if(RunCMake_GENERATOR MATCHES "Ninja|Visual Studio" AND - CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(EXPORTS TRUE) -endif() -# we build debug so the say.exe will be found in Debug/say.exe for -# Visual Studio generators -if(RunCMake_GENERATOR_IS_MULTI_CONFIG) - set(INTDIR "Debug/") -endif() -# build AutoExport -run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build - ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first) -# save the current timestamp of exports.def -if(EXPORTS) - set(EXPORTS_DEF "${RunCMake_TEST_BINARY_DIR}/say.dir/${INTDIR}exports.def") - if(NOT EXISTS "${EXPORTS_DEF}") - set(EXPORTS_DEF - "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/say.dir/${INTDIR}exports.def") + +function (run_cmake_AutoExport name dir) + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${name}-build") + # start by cleaning up because we don't clean up along the way + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + # configure the AutoExport test + run_cmake(${name}) + unset(RunCMake_TEST_OPTIONS) + # don't run this test on Watcom or Borland make as it is not supported + if(RunCMake_GENERATOR MATCHES "Watcom WMake|Borland Makefiles") + return() endif() - file(TIMESTAMP "${EXPORTS_DEF}" timestamp) - if(NOT timestamp) - message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + if(CMAKE_CXX_COMPILER_ID STREQUAL "OrangeC") + return() endif() -endif() -# run the executable that uses symbols from the dll -if(WIN32) - set(EXE_EXT ".exe") -endif() -run_cmake_command(AutoExportRun - ${RunCMake_TEST_BINARY_DIR}/bin/${INTDIR}say${EXE_EXT}) -# build AutoExport again without modification -run_cmake_command(AutoExportBuildAgain ${CMAKE_COMMAND} --build - ${RunCMake_TEST_BINARY_DIR} --config Debug) -# compare timestamps of exports.def to make sure it has not been updated -if(EXPORTS) - file(TIMESTAMP "${EXPORTS_DEF}" timestamp_after) - if(NOT timestamp_after) - message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + if(RunCMake_GENERATOR MATCHES "Ninja|Visual Studio" AND + CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(EXPORTS TRUE) endif() - if (timestamp_after STREQUAL timestamp) - message(STATUS "AutoExportTimeStamp - PASSED") - else() - message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.") + # we build debug so the say.exe will be found in Debug/say.exe for + # Visual Studio generators + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(INTDIR "Debug/") endif() -endif() + # build AutoExport + run_cmake_command(${name}Build ${CMAKE_COMMAND} --build + ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first) + # save the current timestamp of exports.def + if(EXPORTS) + set(EXPORTS_DEF "${RunCMake_TEST_BINARY_DIR}/${dir}/${INTDIR}exports.def") + if(NOT EXISTS "${EXPORTS_DEF}") + set(EXPORTS_DEF + "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${dir}/${INTDIR}exports.def") + endif() + file(TIMESTAMP "${EXPORTS_DEF}" timestamp) + if(NOT timestamp) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() + endif() + # run the executable that uses symbols from the dll + if(WIN32) + set(EXE_EXT ".exe") + endif() + run_cmake_command(${name}Run + ${RunCMake_TEST_BINARY_DIR}/bin/${INTDIR}say${EXE_EXT}) + # build AutoExport again without modification + run_cmake_command(${name}BuildAgain ${CMAKE_COMMAND} --build + ${RunCMake_TEST_BINARY_DIR} --config Debug) + # compare timestamps of exports.def to make sure it has not been updated + if(EXPORTS) + file(TIMESTAMP "${EXPORTS_DEF}" timestamp_after) + if(NOT timestamp_after) + message(SEND_ERROR "Could not get timestamp for \"${EXPORTS_DEF}\"") + endif() + if (timestamp_after STREQUAL timestamp) + message(STATUS "AutoExportTimeStamp - PASSED") + else() + message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.") + endif() + endif() +endfunction () +run_cmake_AutoExport(AutoExport "say.dir") +if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") + run_cmake_AutoExport(AutoExportShort ".o/0cb3d702") +endif () function(run_AIXExportExplicit) set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AIXExportExplicit-build") diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake index 6169bc0e56..33aebe973c 100644 --- a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake +++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake @@ -91,6 +91,6 @@ function(run_Dependencies suffix) endfunction() run_Dependencies("") -if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles)") +if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") run_Dependencies(Short) endif () diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort-check.cmake new file mode 100644 index 0000000000..22182977c0 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort-check.cmake @@ -0,0 +1,17 @@ +if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + return() +endif() + +set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/4bcad702/Debug/cmake_pch.h") + +if (NOT EXISTS ${foo_pch_header}) + set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist") + return() +endif() + +file(STRINGS ${foo_pch_header} foo_pch_header_strings) + +if (NOT foo_pch_header_strings MATCHES ";#include \"[^\"]*PrecompileHeaders/include/foo.h\";#include (;|$)") + set(RunCMake_TEST_FAILED "Generated foo pch header\n ${foo_pch_header}\nhas bad content:\n ${foo_pch_header_strings}") + return() +endif() diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort.cmake new file mode 100644 index 0000000000..f6487406ad --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenexShort.cmake @@ -0,0 +1,10 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) + +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) +target_precompile_headers(foo PUBLIC + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/include/foo.h>" + +) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index aa106c438f..60e3ad3e76 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -17,8 +17,11 @@ endfunction() run_cmake(DisabledPch) run_cmake(PchDebugGenex) +if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") + run_cmake(PchDebugGenexShort) +endif () run_test(PchInterface) -if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles)") +if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") run_test(PchInterfaceShort) endif () run_test(PchInterfaceUnity) diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake index 709e369989..eab5abf214 100644 --- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake @@ -72,6 +72,6 @@ endfunction() run_test(unitybuild_runtest) run_test(unitybuild_object_library) -if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles)") +if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") run_build(unitybuild_cxx_short) endif () diff --git a/Tests/RunCMake/VS10Project/NoImpLib.cmake b/Tests/RunCMake/VS10Project/NoImpLib.cmake index 2c11eac60e..b1e5093a84 100644 --- a/Tests/RunCMake/VS10Project/NoImpLib.cmake +++ b/Tests/RunCMake/VS10Project/NoImpLib.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) set(CMAKE_IMPORT_LIBRARY_SUFFIX "") add_library(foo SHARED empty.c) diff --git a/Tests/RunCMake/VS10Project/NoImpLibShort-build-stdout.txt b/Tests/RunCMake/VS10Project/NoImpLibShort-build-stdout.txt new file mode 100644 index 0000000000..c7282bd447 --- /dev/null +++ b/Tests/RunCMake/VS10Project/NoImpLibShort-build-stdout.txt @@ -0,0 +1 @@ +.*-Fo.o\\75d55f79\\cf59cf.o.* diff --git a/Tests/RunCMake/VS10Project/NoImpLibShort.cmake b/Tests/RunCMake/VS10Project/NoImpLibShort.cmake new file mode 100644 index 0000000000..98f80dec0b --- /dev/null +++ b/Tests/RunCMake/VS10Project/NoImpLibShort.cmake @@ -0,0 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) +set(CMAKE_IMPORT_LIBRARY_SUFFIX "") +add_library(foo SHARED empty.c) diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 8ea38c89bb..df36a7b971 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -43,6 +43,7 @@ run_cmake(VsDpiAware) run_cmake(VsDpiAwareBadParam) run_cmake(VsForceInclude) run_cmake(VsPrecompileHeaders) +run_cmake(VsPrecompileHeadersShort) run_cmake(VsDeployEnabled) run_cmake(VsSettings) run_cmake(VsSourceSettingsTool) @@ -72,11 +73,13 @@ if (RunCMake_GENERATOR MATCHES "Visual Studio 1[0-4] 201[0-5]" OR run_cmake(UnityBuildPre2017) else() run_cmake(UnityBuildNative) + run_cmake(UnityBuildNativeShort) run_cmake(UnityBuildNativeGrouped) + run_cmake(UnityBuildNativeGroupedShort) - function(run_UnityBuildPCH) - set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/UnityBuildPCH-build) - run_cmake(UnityBuildPCH) + function(run_UnityBuildPCH suffix) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/UnityBuildPCH${suffix}-build) + run_cmake(UnityBuildPCH${suffix}) set(RunCMake_TEST_NO_CLEAN 1) set(vcxproj "${RunCMake_TEST_BINARY_DIR}/UnityBuildPCH.vcxproj") if(EXISTS "${vcxproj}") @@ -84,10 +87,11 @@ else() endif() if(vcxproj_strings MATCHES "Include=\"([^\"]+)\"") set(src "${CMAKE_MATCH_1}") - run_cmake_command(UnityBuildPCH-build ${CMAKE_COMMAND} --build . --config Debug --target UnityBuildPCH -- -t:ClCompile -p:SelectedFiles=${src}) + run_cmake_command(UnityBuildPCH${suffix}-build ${CMAKE_COMMAND} --build . --config Debug --target UnityBuildPCH -- -t:ClCompile -p:SelectedFiles=${src}) endif() endfunction() - run_UnityBuildPCH() + run_UnityBuildPCH("") + run_UnityBuildPCH(Short) endif() run_cmake(VsDotnetStartupObject) @@ -103,3 +107,6 @@ run_cmake(VsFrameworkReference) if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20) run_cmake(VsCLRNetcore) endif() + +run_cmake(NoImpLibShort) +run_cmake(RuntimeLibraryShort) diff --git a/Tests/RunCMake/VS10Project/RuntimeLibrary.cmake b/Tests/RunCMake/VS10Project/RuntimeLibrary.cmake index d7787c8f86..a779bc9a89 100644 --- a/Tests/RunCMake/VS10Project/RuntimeLibrary.cmake +++ b/Tests/RunCMake/VS10Project/RuntimeLibrary.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + set(CMAKE_CONFIGURATION_TYPES Debug) cmake_policy(SET CMP0091 NEW) enable_language(C) diff --git a/Tests/RunCMake/VS10Project/RuntimeLibraryShort-build-stdout.txt b/Tests/RunCMake/VS10Project/RuntimeLibraryShort-build-stdout.txt new file mode 100644 index 0000000000..c7282bd447 --- /dev/null +++ b/Tests/RunCMake/VS10Project/RuntimeLibraryShort-build-stdout.txt @@ -0,0 +1 @@ +.*-Fo.o\\75d55f79\\cf59cf.o.* diff --git a/Tests/RunCMake/VS10Project/RuntimeLibraryShort.cmake b/Tests/RunCMake/VS10Project/RuntimeLibraryShort.cmake new file mode 100644 index 0000000000..2f6797da4e --- /dev/null +++ b/Tests/RunCMake/VS10Project/RuntimeLibraryShort.cmake @@ -0,0 +1,22 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +set(CMAKE_CONFIGURATION_TYPES Debug) +cmake_policy(SET CMP0091 NEW) +enable_language(C) +enable_language(CXX) + +add_library(default-C empty.c) +add_library(default-CXX empty.cxx) + +set(CMAKE_MSVC_RUNTIME_LIBRARY "") +add_library(empty-C empty.c) +add_library(empty-CXX empty.cxx) + +set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug") +add_library(MTd-C empty.c) +add_library(MTd-CXX empty.cxx) + +add_library(MT-C empty.c) +set_property(TARGET MT-C PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded") +add_library(MT-CXX empty.cxx) +set_property(TARGET MT-CXX PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded") diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort-check.cmake new file mode 100644 index 0000000000..b56cf3bb4e --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort-check.cmake @@ -0,0 +1,56 @@ +set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/9bc0d702/Unity/unity_poolA_c.c") +if(NOT EXISTS "${unitybuild_c0}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.") + return() +endif() + +set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/9bc0d702/Unity/unity_poolB_c.c") +if(NOT EXISTS "${unitybuild_c1}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.") + return() +endif() + +set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj") +if (NOT EXISTS "${tgt_project}") + set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.") + return() +endif() + +file(STRINGS ${tgt_project} tgt_projects_strings) + +foreach(line IN LISTS tgt_projects_strings) + if (line MATCHES "true") + set(have_unity_support ON) + endif() + + if (line MATCHES " block.") + return() +endif() + +string(REPLACE "\\" "/" unity_source_lines "${unity_source_lines}") +string(FIND "${unity_source_lines}" "CMakeFiles/9bc0d702/Unity/unity_poolA_c.c" unity_source_file_position) +if (unity_source_file_position EQUAL "-1") + set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolA'.") + return() +endif() +string(FIND "${unity_source_lines}" "CMakeFiles/9bc0d702/Unity/unity_poolB_c.c" unity_source_file_position) +if (unity_source_file_position EQUAL "-1") + set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolB'.") + return() +endif() + +list(LENGTH sources_list number_of_sources) +if(NOT number_of_sources EQUAL 7) + set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort.cmake new file mode 100644 index 0000000000..e347448e3c --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGroupedShort.cmake @@ -0,0 +1,22 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +project(unitybuild_c C) + +set(srcs "") +foreach(s RANGE 1 8) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE GROUP) + +set_source_files_properties(s1.c s2.c s3.c s4.c + PROPERTIES UNITY_GROUP "poolA" + ) + +set_source_files_properties(s5.c s6.c s7.c + PROPERTIES UNITY_GROUP "poolB" + ) diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeShort-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeShort-check.cmake new file mode 100644 index 0000000000..941c60f66d --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildNativeShort-check.cmake @@ -0,0 +1,45 @@ +set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/9bc0d702/Unity/unity_0_c.c") +if(NOT EXISTS "${unitybuild_c0}") + set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.") + return() +endif() + +set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj") +if (NOT EXISTS "${tgt_project}") + set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.") + return() +endif() + +file(STRINGS ${tgt_project} tgt_projects_strings) + +foreach(line IN LISTS tgt_projects_strings) + if (line MATCHES "true") + set(have_unity_support ON) + endif() + + if (line MATCHES " block.") + return() +endif() + +string(REPLACE "\\" "/" unity_source_line "${unity_source_line}") +string(FIND "${unity_source_line}" "CMakeFiles/9bc0d702/Unity/unity_0_c.c" unity_source_file_position) +if (unity_source_file_position EQUAL "-1") + set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.") + return() +endif() + +list(LENGTH sources_list number_of_sources) +if(NOT number_of_sources EQUAL 8) + set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeShort.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeShort.cmake new file mode 100644 index 0000000000..404b44554b --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildNativeShort.cmake @@ -0,0 +1,14 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +project(unitybuild_c C) + +set(srcs "") +foreach(s RANGE 1 8) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON) diff --git a/Tests/RunCMake/VS10Project/UnityBuildPCHShort-build-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildPCHShort-build-check.cmake new file mode 100644 index 0000000000..8399a179cb --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildPCHShort-build-check.cmake @@ -0,0 +1,10 @@ +set(obj "${RunCMake_TEST_BINARY_DIR}/.o/30e3d702/Debug/3c809d37.obj") +if(NOT EXISTS "${obj}") + set(RunCMake_TEST_FAILED "Expected object file does not exist:\n ${obj}") + return() +endif() +set(lib "${RunCMake_TEST_BINARY_DIR}/Debug/UnityBuildPCH.lib") +if(EXISTS "${lib}") + set(RunCMake_TEST_FAILED "Unexpected library file exists:\n ${lib}") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/UnityBuildPCHShort.cmake b/Tests/RunCMake/VS10Project/UnityBuildPCHShort.cmake new file mode 100644 index 0000000000..085d3fa152 --- /dev/null +++ b/Tests/RunCMake/VS10Project/UnityBuildPCHShort.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) +add_library(UnityBuildPCH STATIC UnityBuildPCH.c) +target_precompile_headers(UnityBuildPCH PRIVATE UnityBuildPCH.h) +set_property(TARGET UnityBuildPCH PROPERTY UNITY_BUILD ON) diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort-check.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort-check.cmake new file mode 100644 index 0000000000..df5c319801 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort-check.cmake @@ -0,0 +1,66 @@ +set(pch_header "CMakeFiles/9bc0d702/Debug/cmake_pch.hxx") +set(pch_source [=[CMakeFiles\\9bc0d702\\cmake_pch.cxx]=]) + +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_header}") + set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.") + return() +endif() +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_source}") + set(RunCMake_TEST_FAILED "Generated PCH header ${pch_source} does not exist.") + return() +endif() + +set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj") +if (NOT EXISTS "${tgt_project}") + set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.") + return() +endif() + +file(STRINGS ${tgt_project} tgt_projects_strings) + +foreach(line IN LISTS tgt_projects_strings) + if (line MATCHES "Use") + set(have_pch_use ON) + endif() + + if (line MATCHES "Create") + set(have_pch_create ON) + endif() + + if (line MATCHES ".*${pch_header}") + set(have_pch_header ON) + endif() + + if (line MATCHES ".*${pch_header}.*") + set(have_force_pch_header ON) + endif() + + if (line MATCHES "") + set(have_pch_source_compile ON) + endif() +endforeach() + +if (NOT have_pch_use) + set(RunCMake_TEST_FAILED "Generated project should have the Use block.") + return() +endif() + +if (NOT have_pch_create) + set(RunCMake_TEST_FAILED "Generated project should have the Create block.") + return() +endif() + +if (NOT have_pch_header) + set(RunCMake_TEST_FAILED "Generated project should have the ${pch_header} block.") + return() +endif() + +if (NOT have_force_pch_header) + set(RunCMake_TEST_FAILED "Generated project should have the ${pch_header} block.") + return() +endif() + +if (NOT have_pch_source_compile) + set(RunCMake_TEST_FAILED "Generated project should have the block.") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort.cmake new file mode 100644 index 0000000000..c7b056c7de --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsPrecompileHeadersShort.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +project(VsPrecompileHeaders CXX) + +add_library(tgt SHARED empty.cxx) +target_precompile_headers(tgt PRIVATE stdafx.h)