diff options
author | Brad King <brad.king@kitware.com> | 2019-09-10 14:54:39 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-09-10 14:54:55 (GMT) |
commit | bbf48c494ad28d1c8ac5aa6e4cecb35c2cbf1b84 (patch) | |
tree | 15f339e1582ed553aa10f9a3299a7473df844c53 | |
parent | 05d5c66ff853f88e6dbe43bbddd18dd8babaa427 (diff) | |
parent | ff5028c5318c5d404390d8114d9453fc81fa9a33 (diff) | |
download | CMake-bbf48c494ad28d1c8ac5aa6e4cecb35c2cbf1b84.zip CMake-bbf48c494ad28d1c8ac5aa6e4cecb35c2cbf1b84.tar.gz CMake-bbf48c494ad28d1c8ac5aa6e4cecb35c2cbf1b84.tar.bz2 |
Merge topic 'windows-auto-export-incremental-build'
ff5028c531 Windows: Prevent auto exports to be regenerated on every build
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3750
-rw-r--r-- | Help/release/dev/windows-auto-export-incremental-build.rst | 6 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 33 | ||||
-rw-r--r-- | Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake | 35 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 2 |
4 files changed, 65 insertions, 11 deletions
diff --git a/Help/release/dev/windows-auto-export-incremental-build.rst b/Help/release/dev/windows-auto-export-incremental-build.rst new file mode 100644 index 0000000..3126329 --- /dev/null +++ b/Help/release/dev/windows-auto-export-incremental-build.rst @@ -0,0 +1,6 @@ +windows-auto-export-incremental-build +------------------------------------- + +* On Windows, existing auto generated exports are now only updated if the + modified time stamp of the exports is not newer than any modified time stamp + of the input files. diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index a79a2ff..e6dd99a 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -562,19 +562,36 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) "objlistfile [-nm=nm-path]\n"; return 1; } - FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); - if (!fout) { - std::cerr << "could not open output .def file: " << args[2].c_str() - << "\n"; - return 1; - } cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); if (!fin) { std::cerr << "could not open object list file: " << args[3].c_str() << "\n"; return 1; } - std::string file; + std::vector<std::string> files; + { + std::string file; + cmFileTime outTime; + bool outValid = outTime.Load(args[2]); + while (cmSystemTools::GetLineFromStream(fin, file)) { + files.push_back(file); + if (outValid) { + cmFileTime inTime; + outValid = inTime.Load(file) && inTime.Older(outTime); + } + } + if (outValid) { + // The def file already exists and all input files are older than the + // existing def file. + return 0; + } + } + FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); + if (!fout) { + std::cerr << "could not open output .def file: " << args[2].c_str() + << "\n"; + return 1; + } bindexplib deffile; if (args.size() >= 5) { auto a = args[4]; @@ -585,7 +602,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) std::cerr << "unknown argument: " << a << "\n"; } } - while (cmSystemTools::GetLineFromStream(fin, file)) { + for (auto const& file : files) { std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); if (cmSystemTools::LowerCase(ext) == ".def") { if (!deffile.AddDefinitionFile(file.c_str())) { diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake index 27a609d..6c9be4b 100644 --- a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake +++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake @@ -7,9 +7,13 @@ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") 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") +if(RunCMake_GENERATOR MATCHES "Watcom WMake|Borland Makefiles") 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) @@ -18,9 +22,36 @@ 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") + 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(AutoExportRun - ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT}) + ${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}\"") + endif() + if (timestamp_after STREQUAL timestamp) + message(STATUS "AutoExportTimeStamp - PASSED") + else() + message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.") + endif() +endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 8fd5234..c663484 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -543,7 +543,7 @@ set(cpack_tests add_RunCMake_test_group(CPack "${cpack_tests}") # add a test to make sure symbols are exported from a shared library # for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used -add_RunCMake_test(AutoExportDll) +add_RunCMake_test(AutoExportDll -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}) add_RunCMake_test(AndroidMK) |