Visual Studio: support shortened object filenames

This commit is contained in:
John Parent
2025-05-21 23:14:57 +02:00
committed by Ben Boeckel
parent a3a190c006
commit f97d1bf7d8
29 changed files with 453 additions and 73 deletions

View File

@@ -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.

View File

@@ -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();

View File

@@ -184,6 +184,8 @@ public:
bool IsMsBuildRestoreSupported() const;
bool IsBuildInParallelSupported() const;
bool SupportsShortObjectNames() const override;
protected:
cmGlobalVisualStudio10Generator(cmake* cm, std::string const& name);

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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 $<TARGET_OBJECTS:objlib>)
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)

View File

@@ -0,0 +1 @@
^.*$

View File

@@ -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")

View File

@@ -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 ()

View File

@@ -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 <stdio.h>(;|$)")
set(RunCMake_TEST_FAILED "Generated foo pch header\n ${foo_pch_header}\nhas bad content:\n ${foo_pch_header_strings}")
return()
endif()

View File

@@ -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
"$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/include/foo.h>"
<stdio.h>
)

View File

@@ -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)

View File

@@ -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 ()

View File

@@ -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)

View File

@@ -0,0 +1 @@
.*-Fo.o\\75d55f79\\cf59cf.o.*

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -0,0 +1 @@
.*-Fo.o\\75d55f79\\cf59cf.o.*

View File

@@ -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")

View File

@@ -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 "<EnableUnitySupport>true</EnableUnitySupport>")
set(have_unity_support ON)
endif()
if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"false\" CustomUnityFile=\"true\"")
list(APPEND unity_source_lines ${line})
endif()
if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"true\" CustomUnityFile=\"true\"")
list(APPEND sources_list ${line})
endif()
endforeach()
if (NOT have_unity_support)
set(RunCMake_TEST_FAILED "Generated project should include the <EnableUnitySupport> 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()

View File

@@ -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"
)

View File

@@ -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 "<EnableUnitySupport>true</EnableUnitySupport>")
set(have_unity_support ON)
endif()
if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"false\" CustomUnityFile=\"true\"")
set(unity_source_line ${line})
endif()
if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"true\" CustomUnityFile=\"true\"")
list(APPEND sources_list ${line})
endif()
endforeach()
if (NOT have_unity_support)
set(RunCMake_TEST_FAILED "Generated project should include the <EnableUnitySupport> 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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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 "<PrecompiledHeader.*>Use</PrecompiledHeader>")
set(have_pch_use ON)
endif()
if (line MATCHES "<PrecompiledHeader.*>Create</PrecompiledHeader>")
set(have_pch_create ON)
endif()
if (line MATCHES "<PrecompiledHeaderFile.*>.*${pch_header}</PrecompiledHeaderFile>")
set(have_pch_header ON)
endif()
if (line MATCHES "<ForcedIncludeFiles.*>.*${pch_header}.*</ForcedIncludeFiles>")
set(have_force_pch_header ON)
endif()
if (line MATCHES "<ClCompile Include=.*${pch_source}\">")
set(have_pch_source_compile ON)
endif()
endforeach()
if (NOT have_pch_use)
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Use</PrecompiledHeader> block.")
return()
endif()
if (NOT have_pch_create)
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Create</PrecompiledHeader> block.")
return()
endif()
if (NOT have_pch_header)
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeaderFile>${pch_header}</PrecompiledHeaderFile> block.")
return()
endif()
if (NOT have_force_pch_header)
set(RunCMake_TEST_FAILED "Generated project should have the <ForcedIncludeFiles>${pch_header}</ForcedIncludeFiles> block.")
return()
endif()
if (NOT have_pch_source_compile)
set(RunCMake_TEST_FAILED "Generated project should have the <ClCompile Include=\"${pch_source}\"> block.")
return()
endif()

View File

@@ -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)