From 13caaa3eb74a11dbf067409ea129321718d34dfe Mon Sep 17 00:00:00 2001 From: David Cole Date: Tue, 4 Jan 2011 18:51:15 -0500 Subject: [PATCH 1/3] VS10: Finish Midl support (#11461) This commit addresses all of the following: http://public.kitware.com/Bug/view.php?id=8165 http://public.kitware.com/Bug/view.php?id=10687 http://public.kitware.com/Bug/view.php?id=11311 http://public.kitware.com/Bug/view.php?id=11461 With this commit, the midl support for VS10 is as complete as midl support ever was for VS9 and earlier. The VSMidl test should run on all Visual Studio generator based dashboards. CMake no longer sends C++ compiler /D flag values to the midl compiler in Visual Studio generated projects. I think if we want to add that in the future, we should add a way to pass midl compiler specific flags and perhaps an optional way to add in the C++ definitions, too. For now, not sending them along gets past the immediate problem wherein idl files in a CMake VS generated project just didn't work at all. The VSMidl test added in this commit was inspired by the patch attached to 8165. The test had to be modified such that it will run in a directory whose name contains no spaces. There is an existing bug filed against VS10's midl asking Microsoft to fix that problem. But for now, the test added in this commit works by copying the source directory to a location that avoids spaces in the directory names. Inspired-By: Robert Lenhardt --- Source/cmLocalVisualStudio7Generator.cxx | 1 - Source/cmVisualStudio10TargetGenerator.cxx | 26 +++++++- Tests/CMakeLists.txt | 11 +++ Tests/VSMidl/CMakeLists.txt | 78 ++++++++++++++++++++++ Tests/VSMidl/src/CMakeLists.txt | 5 ++ Tests/VSMidl/src/main.cpp | 17 +++++ Tests/VSMidl/src/test.idl | 30 +++++++++ 7 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 Tests/VSMidl/CMakeLists.txt create mode 100644 Tests/VSMidl/src/CMakeLists.txt create mode 100644 Tests/VSMidl/src/main.cpp create mode 100644 Tests/VSMidl/src/test.idl diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index b22c429d5..dfaa7a645 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -797,7 +797,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, tool = "VFMIDLTool"; } fout << "\t\t\tPlatformName == "x64" ) { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 20ed5a85f..8438d166c 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -436,6 +436,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() std::vector customBuild; std::vector none; std::vector headers; + std::vector idls; std::vector resource; for(std::vector::const_iterator s = classes.begin(); @@ -458,7 +459,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { clCompile.push_back(sf); } - if(strcmp(lang, "RC") == 0) + else if(strcmp(lang, "RC") == 0) { resource.push_back(sf); } @@ -470,6 +471,10 @@ void cmVisualStudio10TargetGenerator::WriteGroups() { headers.push_back(sf); } + else if(sf->GetExtension() == "idl") + { + idls.push_back(sf); + } else { none.push_back(sf); @@ -498,6 +503,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() this->WriteGroupSources("ClCompile", clCompile, sourceGroups); this->WriteGroupSources("ClInclude", headers, sourceGroups); this->WriteGroupSources("ResourceCompile", resource, sourceGroups); + this->WriteGroupSources("Midl", idls, sourceGroups); this->WriteGroupSources("CustomBuild", customBuild, sourceGroups); this->WriteString("\n", 1); @@ -670,6 +676,7 @@ void cmVisualStudio10TargetGenerator::WriteCLSources() const char* lang = (*source)->GetLanguage(); bool cl = lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0); bool rc = lang && (strcmp(lang, "RC") == 0); + bool idl = (*source)->GetExtension() == "idl"; std::string sourceFile = (*source)->GetFullPath(); sourceFile = cmSystemTools::RelativePath( this->Makefile->GetCurrentOutputDirectory(), @@ -688,6 +695,10 @@ void cmVisualStudio10TargetGenerator::WriteCLSources() { this->WriteString("WriteString("WriteString("WriteString("\n", 2); this->OutputIncludes(includes); + this->WriteString("$(IntDir)\n", 3); + this->WriteString("%(Filename).h\n", 3); + this->WriteString( + "%(Filename).tlb\n", 3); + this->WriteString( + "" + "%(Filename)_i.c\n", 3); + this->WriteString("%(Filename)_p.c\n",3); this->WriteString("\n", 2); } - + + void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() -{ +{ std::vector *configs = static_cast (this->GlobalGenerator)->GetConfigurations(); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 289e6327a..0c973dafb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1075,6 +1075,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --test-command VSExternalInclude) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExternalInclude") + + ADD_TEST(VSMidl ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/VSMidl" + "${CMake_BINARY_DIR}/Tests/VSMidl" + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project VSMidl + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --test-command VSMidl) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl") ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio") IF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) diff --git a/Tests/VSMidl/CMakeLists.txt b/Tests/VSMidl/CMakeLists.txt new file mode 100644 index 000000000..7dd2b4dee --- /dev/null +++ b/Tests/VSMidl/CMakeLists.txt @@ -0,0 +1,78 @@ +# This CMakeLists.txt file exists solely to drive the one found in the "src" +# subdir as an ExternalProject build. The project in "src" cannot build when +# there is a space in the directory name, so we copy that directory to a place +# guaranteed not to have a space in the name, build it there, and then copy the +# resulting output directory back up here into this CMake test's build tree. +# +if(NOT DEFINED CMAKE_BUILDNAME) + string(REGEX REPLACE "^.*/([^/]+)/[^/]+/([^/]+)$" "\\1" CMAKE_BUILDNAME "${CMAKE_CURRENT_BINARY_DIR}") + string(REGEX REPLACE "^.*/([^/]+)/[^/]+/([^/]+)$" "\\2" THIS_TESTNAME "${CMAKE_CURRENT_BINARY_DIR}") + string(REPLACE " " "_" CMAKE_BUILDNAME "${CMAKE_BUILDNAME}") +endif() +message(STATUS "CMAKE_BUILDNAME='${CMAKE_BUILDNAME}'") +message(STATUS "THIS_TESTNAME='${THIS_TESTNAME}'") + +cmake_minimum_required(VERSION 2.8) +project(${THIS_TESTNAME}) + +include(ExternalProject) + +if(NOT DEFINED HOME) + if(DEFINED ENV{CTEST_REAL_HOME}) + set(HOME "$ENV{CTEST_REAL_HOME}") + else() + set(HOME "$ENV{HOME}") + endif() + + if(NOT HOME AND WIN32) + # Try for USERPROFILE as HOME equivalent: + string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}") + + # But just use root of SystemDrive if USERPROFILE contains any spaces: + # (Default on XP and earlier...) + if(HOME MATCHES " ") + string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}") + endif() + endif() +endif() +message(STATUS "HOME='${HOME}'") + +if(NOT DEFINED url) + set(url "${CMAKE_CURRENT_SOURCE_DIR}/src") +endif() +message(STATUS "url='${url}'") + +set(base_dir "${HOME}/.cmake/Dashboards/${CMAKE_BUILDNAME}/${THIS_TESTNAME}") +set(binary_dir "${base_dir}/build") +set(source_dir "${base_dir}/src") + +# Source dir for this project exists in the CMake source tree, but we cannot +# use it in-place since there might be a space in its directory name. +# Source dir is therefore copied under a '.cmake/Dashboards' +# dir in your HOME directory to give it a name with no spaces. +# +ExternalProject_Add(clean-${PROJECT_NAME} + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E remove_directory "${source_dir}" + BUILD_COMMAND ${CMAKE_COMMAND} -E remove_directory "${binary_dir}" + INSTALL_COMMAND "" + ) + +ExternalProject_Add(download-${PROJECT_NAME} + URL "${url}" + SOURCE_DIR "${source_dir}" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + DEPENDS clean-${PROJECT_NAME} + ) + +ExternalProject_Add(build-${PROJECT_NAME} + DOWNLOAD_COMMAND "" + SOURCE_DIR "${source_dir}" + BINARY_DIR "${binary_dir}" + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory + "${binary_dir}/${CMAKE_CFG_INTDIR}" + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" + DEPENDS download-${PROJECT_NAME} + ) diff --git a/Tests/VSMidl/src/CMakeLists.txt b/Tests/VSMidl/src/CMakeLists.txt new file mode 100644 index 000000000..28bb1205d --- /dev/null +++ b/Tests/VSMidl/src/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.8) +project(VSMidl) + +include_directories("${CMAKE_CURRENT_BINARY_DIR}/\$(IntDir)") +add_executable(VSMidl main.cpp test.idl) diff --git a/Tests/VSMidl/src/main.cpp b/Tests/VSMidl/src/main.cpp new file mode 100644 index 000000000..6b78fcc7f --- /dev/null +++ b/Tests/VSMidl/src/main.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +int main(int argc, char** argv) +{ + IID libid = LIBID_CMakeMidlTestLib; + CLSID clsid = CLSID_CMakeMidlTest; + IID iid = IID_ICMakeMidlTest; + + printf("Running '%s'\n", argv[0]); + printf(" libid starts with '0x%08lx'\n", (long) libid.Data1); + printf(" clsid starts with '0x%08lx'\n", (long) clsid.Data1); + printf(" iid starts with '0x%08lx'\n", (long) iid.Data1); + + return 0; +} diff --git a/Tests/VSMidl/src/test.idl b/Tests/VSMidl/src/test.idl new file mode 100644 index 000000000..fd755c789 --- /dev/null +++ b/Tests/VSMidl/src/test.idl @@ -0,0 +1,30 @@ +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(258CCEBE-8EE4-4A48-B78C-AC53BCD59E28), + dual, + nonextensible, + helpstring("ICMakeTest Interface"), + pointer_default(unique) +] +interface ICMakeMidlTest : IUnknown +{ + [id(1), helpstring("method Method")] HRESULT Method(); +} + +[ + uuid(0537BA59-7EEC-48F8-BD4B-369BC7D9807E), +] +library CMakeMidlTestLib +{ + [ + uuid(D2A90807-019A-46E5-BF47-FF4FA4352D2A), + helpstring("CMakeMidlTest Class") + ] + coclass CMakeMidlTest + { + [default] interface ICMakeMidlTest; + }; +} From 262da91e26e7641192549028fee40b4c62e25266 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 5 Jan 2011 11:30:12 -0500 Subject: [PATCH 2/3] Prohibit space in HOME value for VSMidl test. Some Windows machines actually define HOME in their environment. And some of them actually put a directory with a space in the name as the value. Make sure the HOME value (CMake variable) in this CMakeLists file does not contain a space. --- Tests/VSMidl/CMakeLists.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Tests/VSMidl/CMakeLists.txt b/Tests/VSMidl/CMakeLists.txt index 7dd2b4dee..432506c3b 100644 --- a/Tests/VSMidl/CMakeLists.txt +++ b/Tests/VSMidl/CMakeLists.txt @@ -27,12 +27,15 @@ if(NOT DEFINED HOME) if(NOT HOME AND WIN32) # Try for USERPROFILE as HOME equivalent: string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}") + endif() - # But just use root of SystemDrive if USERPROFILE contains any spaces: - # (Default on XP and earlier...) - if(HOME MATCHES " ") - string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}") - endif() + # But just use root of SystemDrive if HOME contains any spaces: + # (Default on XP and earlier...) + if(HOME MATCHES " " AND WIN32) + string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}") + endif() + if(HOME MATCHES " ") + set(HOME "") endif() endif() message(STATUS "HOME='${HOME}'") From e33cbda5c459e10bcbfc1f407951f9deaffe8fdf Mon Sep 17 00:00:00 2001 From: David Cole Date: Thu, 6 Jan 2011 09:10:35 -0500 Subject: [PATCH 3/3] VSMidl Test: Use correct include_directories with VS6 (#11461) VS6 builds put midl output directly in CMAKE_CURRENT_BINARY_DIR. Adjust test include_directories to match. Fixes test failure on dashboard machine DASH3. --- Tests/VSMidl/src/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Tests/VSMidl/src/CMakeLists.txt b/Tests/VSMidl/src/CMakeLists.txt index 28bb1205d..86c04ed98 100644 --- a/Tests/VSMidl/src/CMakeLists.txt +++ b/Tests/VSMidl/src/CMakeLists.txt @@ -1,5 +1,12 @@ cmake_minimum_required(VERSION 2.8) project(VSMidl) -include_directories("${CMAKE_CURRENT_BINARY_DIR}/\$(IntDir)") +if(MSVC_VERSION GREATER 1200) + include_directories("${CMAKE_CURRENT_BINARY_DIR}/\$(IntDir)") +else() + # midl generated headers end up directly in CMAKE_CURRENT_BINARY_DIR with + # VS6 builds. + include_directories("${CMAKE_CURRENT_BINARY_DIR}") +endif() + add_executable(VSMidl main.cpp test.idl)