summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--Modules/CMakeCInformation.cmake6
-rw-r--r--Modules/CMakeCXXInformation.cmake6
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake2
-rw-r--r--Modules/CMakeFortranCompilerABI.F5
-rw-r--r--Modules/CMakeFortranInformation.cmake6
-rw-r--r--Modules/CMakeTestCCompiler.cmake6
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake6
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake6
-rw-r--r--Modules/Platform/GNUtoMS_lib.bat.in3
-rw-r--r--Modules/Platform/GNUtoMS_lib.cmake10
-rw-r--r--Modules/Platform/Windows-GNU-C-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-CXX-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-Fortran-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-Fortran.cmake3
-rw-r--r--Modules/Platform/Windows-GNU.cmake54
-rw-r--r--Source/cmDocumentVariables.cxx11
-rw-r--r--Source/cmExportBuildFileGenerator.cxx2
-rw-r--r--Source/cmInstallTargetGenerator.cxx26
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx10
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx9
-rw-r--r--Source/cmMakefileTargetGenerator.cxx17
-rw-r--r--Source/cmMakefileTargetGenerator.h3
-rw-r--r--Source/cmTarget.cxx38
-rw-r--r--Source/cmTarget.h8
-rw-r--r--Tests/ExportImport/CMakeLists.txt5
-rw-r--r--Tests/ExportImport/InitialCache.cmake.in1
27 files changed, 242 insertions, 5 deletions
diff --git a/.gitattributes b/.gitattributes
index d9d64d6..d21f1dd 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,6 +8,7 @@ configure crlf=input
*.sh.in crlf=input
*.bat -crlf
+*.bat.in -crlf
*.dsp -crlf
*.dsptemplate -crlf
*.dsw -crlf
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 9285fef..6b5efba 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -68,6 +68,12 @@ IF (NOT _INCLUDED_FILE)
INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
ENDIF (NOT _INCLUDED_FILE)
+IF(CMAKE_C_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_C_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_C_ABI_FILES)
+ENDIF()
# This should be included before the _INIT variables are
# used to initialize the cache. Since the rule variables
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 620de63..b97a69c 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -67,6 +67,12 @@ IF (NOT _INCLUDED_FILE)
INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
ENDIF (NOT _INCLUDED_FILE)
+IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_CXX_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_CXX_ABI_FILES)
+ENDIF()
# This should be included before the _INIT variables are
# used to initialize the cache. Since the rule variables
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index a808a28..1c9899e 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -57,6 +57,8 @@ FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
IF(ABI_SIZEOF_DPTR)
SET(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
+ ELSEIF(CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT)
+ SET(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE)
ENDIF(ABI_SIZEOF_DPTR)
IF(ABI_NAME)
diff --git a/Modules/CMakeFortranCompilerABI.F b/Modules/CMakeFortranCompilerABI.F
index b8efb42..7e24553 100644
--- a/Modules/CMakeFortranCompilerABI.F
+++ b/Modules/CMakeFortranCompilerABI.F
@@ -15,6 +15,11 @@
PRINT *, 'INFO:sizeof_dptr[4]'
#elif defined(_M_IX86)
PRINT *, 'INFO:sizeof_dptr[4]'
+
+#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
+ PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4
+ PRINT *, 'INFO:sizeof_dptr[4]'
#endif
#if 0
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index dc15e55..aed1fd2 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -44,6 +44,12 @@ IF (NOT _INCLUDED_FILE)
INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
ENDIF (NOT _INCLUDED_FILE)
+IF(CMAKE_Fortran_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_Fortran_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_Fortran_ABI_FILES)
+ENDIF()
# This should be included before the _INIT variables are
# used to initialize the cache. Since the rule variables
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 038c2fd..4d4e35f 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -76,5 +76,11 @@ ELSE(NOT CMAKE_C_COMPILER_WORKS)
)
INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake)
ENDIF(CMAKE_C_COMPILER_FORCED)
+ IF(CMAKE_C_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_C_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_C_ABI_FILES)
+ ENDIF()
ENDIF(NOT CMAKE_C_COMPILER_WORKS)
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index c1a3b3a..494add3 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -69,4 +69,10 @@ ELSE(NOT CMAKE_CXX_COMPILER_WORKS)
)
INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake)
ENDIF(CMAKE_CXX_COMPILER_FORCED)
+ IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_CXX_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_CXX_ABI_FILES)
+ ENDIF()
ENDIF(NOT CMAKE_CXX_COMPILER_WORKS)
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index 33f62eb..b4dcea6 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -92,4 +92,10 @@ ELSE(NOT CMAKE_Fortran_COMPILER_WORKS)
)
INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeFortranCompiler.cmake)
ENDIF(CMAKE_Fortran_COMPILER_FORCED)
+ IF(CMAKE_Fortran_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_Fortran_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_Fortran_ABI_FILES)
+ ENDIF()
ENDIF(NOT CMAKE_Fortran_COMPILER_WORKS)
diff --git a/Modules/Platform/GNUtoMS_lib.bat.in b/Modules/Platform/GNUtoMS_lib.bat.in
new file mode 100644
index 0000000..2da920a
--- /dev/null
+++ b/Modules/Platform/GNUtoMS_lib.bat.in
@@ -0,0 +1,3 @@
+@echo off
+call "@CMAKE_GNUtoMS_BAT@"
+lib /machine:"@CMAKE_GNUtoMS_ARCH@" %*
diff --git a/Modules/Platform/GNUtoMS_lib.cmake b/Modules/Platform/GNUtoMS_lib.cmake
new file mode 100644
index 0000000..ca9b0f8
--- /dev/null
+++ b/Modules/Platform/GNUtoMS_lib.cmake
@@ -0,0 +1,10 @@
+# Usage: cmake -Dlib=lib.bat -Ddef=out.def -Ddll=out.dll -Dimp=out.dll.a -P GNUtoMS_lib.cmake
+get_filename_component(name ${dll} NAME) # .dll file name
+string(REGEX REPLACE "\\.dll\\.a$" ".lib" out "${imp}") # .dll.a -> .lib
+execute_process(
+ COMMAND ${lib} /def:${def} /name:${name} /out:${out}
+ RESULT_VARIABLE res
+ )
+if(res)
+ message(FATAL_ERROR "lib failed: ${res}")
+endif()
diff --git a/Modules/Platform/Windows-GNU-C-ABI.cmake b/Modules/Platform/Windows-GNU-C-ABI.cmake
new file mode 100644
index 0000000..1189263
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-C-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(C)
diff --git a/Modules/Platform/Windows-GNU-CXX-ABI.cmake b/Modules/Platform/Windows-GNU-CXX-ABI.cmake
new file mode 100644
index 0000000..f3c701c
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-CXX-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(CXX)
diff --git a/Modules/Platform/Windows-GNU-Fortran-ABI.cmake b/Modules/Platform/Windows-GNU-Fortran-ABI.cmake
new file mode 100644
index 0000000..179280b
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-Fortran-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(Fortran)
diff --git a/Modules/Platform/Windows-GNU-Fortran.cmake b/Modules/Platform/Windows-GNU-Fortran.cmake
index c66feed..b81b796 100644
--- a/Modules/Platform/Windows-GNU-Fortran.cmake
+++ b/Modules/Platform/Windows-GNU-Fortran.cmake
@@ -1,2 +1,5 @@
include(Platform/Windows-GNU)
__windows_compiler_gnu(Fortran)
+
+# gfortran on 64-bit MinGW defines __SIZEOF_POINTER__
+set(CMAKE_Fortran_SIZEOF_DATA_PTR_DEFAULT 4)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 1d3e4b5..c255d6b 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -108,6 +108,8 @@ macro(__windows_compiler_gnu lang)
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+ list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
+
# Support very long lists of object files.
if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@")
foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE)
@@ -125,3 +127,55 @@ macro(__windows_compiler_gnu lang)
endforeach()
endif()
endmacro()
+
+macro(__windows_compiler_gnu_abi lang)
+ if(CMAKE_NO_GNUtoMS)
+ set(CMAKE_GNUtoMS 0)
+ else()
+ option(CMAKE_GNUtoMS "Convert GNU import libraries to MS format (requires Visual Studio)" OFF)
+ endif()
+
+ if(CMAKE_GNUtoMS AND NOT CMAKE_GNUtoMS_LIB)
+ # Find MS development environment setup script for this architecture.
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
+ find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat
+ DOC "Visual Studio vcvars32.bat"
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++;ProductDir]/bin"
+ )
+ set(CMAKE_GNUtoMS_ARCH x86)
+ elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvarsamd64.bat
+ DOC "Visual Studio vcvarsamd64.bat"
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin/amd64"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin/amd64"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin/amd64"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/bin/amd64"
+ )
+ set(CMAKE_GNUtoMS_ARCH amd64)
+ endif()
+ set_property(CACHE CMAKE_GNUtoMS_VCVARS PROPERTY ADVANCED 1)
+ if(CMAKE_GNUtoMS_VCVARS)
+ # Create helper script to run lib.exe from MS environment.
+ string(REPLACE "/" "\\" CMAKE_GNUtoMS_BAT "${CMAKE_GNUtoMS_VCVARS}")
+ set(CMAKE_GNUtoMS_LIB ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeGNUtoMS_lib.bat)
+ configure_file(${CMAKE_ROOT}/Modules/Platform/GNUtoMS_lib.bat.in ${CMAKE_GNUtoMS_LIB})
+ else()
+ message(WARNING "Disabling CMAKE_GNUtoMS option because CMAKE_GNUtoMS_VCVARS is not set.")
+ set(CMAKE_GNUtoMS 0)
+ endif()
+ endif()
+
+ if(CMAKE_GNUtoMS)
+ # Teach CMake how to create a MS import library at link time.
+ set(CMAKE_${lang}_GNUtoMS_RULE " -Wl,--output-def,<TARGET_NAME>.def"
+ "<CMAKE_COMMAND> -Dlib=\"${CMAKE_GNUtoMS_LIB}\" -Ddef=\"<TARGET_NAME>.def\" -Ddll=\"<TARGET>\" -Dimp=\"<TARGET_IMPLIB>\" -P \"${CMAKE_ROOT}/Modules/Platform/GNUtoMS_lib.cmake\""
+ )
+ endif()
+endmacro()
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index ed303c9..c8c83b9 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1112,6 +1112,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Variables that Control the Build");
cm->DefineProperty
+ ("CMAKE_GNUtoMS", cmProperty::VARIABLE,
+ "Convert GNU import libraries (.dll.a) to MS format (.lib).",
+ "This variable is used to initialize the GNUtoMS property on targets "
+ "when they are created. "
+ "See that target property for additional information.",
+ false,
+ "Variables that Control the Build");
+
+ cm->DefineProperty
("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE,
"See variable CMAKE_<CONFIG>_POSTFIX.",
"This variable is a special case of the more-general "
@@ -1515,6 +1524,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_COMPILER_ID_RUN",
cmProperty::VARIABLE,0,0);
+ cm->DefineProperty("CMAKE_<LANG>_ABI_FILES",
+ cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_CREATE_ASSEMBLY_SOURCE",
cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_CREATE_PREPROCESSED_SOURCE",
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 7e73e36..32595ee 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -125,6 +125,8 @@ cmExportBuildFileGenerator
std::string prop = "IMPORTED_IMPLIB";
prop += suffix;
std::string value = target->GetFullPath(config, true);
+ target->GetImplibGNUtoMS(value, value,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
properties[prop] = value;
}
}
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 33ffbfb..ac1c949 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -101,6 +101,13 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string to1 = toDir + targetNameImport;
filesFrom.push_back(from1);
filesTo.push_back(to1);
+ std::string targetNameImportLib;
+ if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ targetNameImportLib))
+ {
+ filesFrom.push_back(fromDirConfig + targetNameImportLib);
+ filesTo.push_back(toDir + targetNameImportLib);
+ }
// An import library looks like a static library.
type = cmTarget::STATIC_LIBRARY;
@@ -157,6 +164,13 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string to1 = toDir + targetNameImport;
filesFrom.push_back(from1);
filesTo.push_back(to1);
+ std::string targetNameImportLib;
+ if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ targetNameImportLib))
+ {
+ filesFrom.push_back(fromDirConfig + targetNameImportLib);
+ filesTo.push_back(toDir + targetNameImportLib);
+ }
// An import library looks like a static library.
type = cmTarget::STATIC_LIBRARY;
@@ -314,7 +328,11 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
if(nameType == NameImplib)
{
// Use the import library name.
- fname = targetNameImport;
+ if(!target->GetImplibGNUtoMS(targetNameImport, fname,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
+ {
+ fname = targetNameImport;
+ }
}
else if(nameType == NameReal)
{
@@ -339,7 +357,11 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
if(nameType == NameImplib)
{
// Use the import library name.
- fname = targetNameImport;
+ if(!target->GetImplibGNUtoMS(targetNameImport, fname,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
+ {
+ fname = targetNameImport;
+ }
}
else if(nameType == NameSO)
{
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index cd75d79..78278cb 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -241,6 +241,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
exeCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
+ std::string implib;
+ if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ {
+ exeCleanFiles.push_back(this->Convert(implib.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
}
// List the PDB for cleaning only when the whole target is
@@ -270,8 +277,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_LINK_EXECUTABLE";
- std::string linkRule =
- this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
+ std::string linkRule = this->GetLinkRule(linkRuleVar.c_str());
std::vector<std::string> commands1;
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
if(this->Target->IsExecutableWithExports())
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 31f7be5..b4174cc 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -512,6 +512,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
+ std::string implib;
+ if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ {
+ libCleanFiles.push_back(this->Convert(implib.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
}
// List the PDB for cleaning only when the whole target is
@@ -772,7 +779,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
else
{
// Get the set of commands.
- std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
+ std::string linkRule = this->GetLinkRule(linkRuleVar);
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
// Expand placeholders.
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 8b91194..a3a832b 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1634,6 +1634,23 @@ void cmMakefileTargetGenerator
}
//----------------------------------------------------------------------------
+std::string cmMakefileTargetGenerator::GetLinkRule(const char* linkRuleVar)
+{
+ std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
+ if(this->Target->HasImplibGNUtoMS())
+ {
+ std::string ruleVar = "CMAKE_";
+ ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ ruleVar += "_GNUtoMS_RULE";
+ if(const char* rule = this->Makefile->GetDefinition(ruleVar.c_str()))
+ {
+ linkRule += rule;
+ }
+ }
+ return linkRule;
+}
+
+//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::CloseFileStreams()
{
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 674cd13..8fba13f 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -120,6 +120,9 @@ protected:
// Append link rule dependencies (objects, etc.).
void AppendLinkDepends(std::vector<std::string>& depends);
+ // Lookup the link rule for this target.
+ std::string GetLinkRule(const char* linkRuleVar);
+
/** In order to support parallel builds for custom commands with
multiple outputs the outputs are given a serial order, and only
the first output actually has the build rule. Other outputs
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7e02a39..87f8c5e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -972,6 +972,23 @@ void cmTarget::DefineProperties(cmake *cm)
"is created its value is used to initialize this property.");
cm->DefineProperty
+ ("GNUtoMS", cmProperty::TARGET,
+ "Convert GNU import library (.dll.a) to MS format (.lib).",
+ "When linking a shared library or executable that exports symbols "
+ "using GNU tools on Windows (MinGW/MSYS) with Visual Studio installed "
+ "convert the import library (.dll.a) from GNU to MS format (.lib). "
+ "Both import libraries will be installed by install(TARGETS) and "
+ "exported by install(EXPORT) and export() to be linked by applications "
+ "with either GNU- or MS-compatible tools."
+ "\n"
+ "If the variable CMAKE_GNUtoMS is set when a target "
+ "is created its value is used to initialize this property. "
+ "The variable must be set prior to the first command that enables "
+ "a language such as project() or enable_language(). "
+ "CMake provides the variable as an option to the user automatically "
+ "when configuring on Windows with GNU tools.");
+
+ cm->DefineProperty
("XCODE_ATTRIBUTE_<an-attribute>", cmProperty::TARGET,
"Set Xcode target attributes directly.",
"Tell the Xcode generator to set '<an-attribute>' to a given value "
@@ -1210,6 +1227,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("Fortran_FORMAT", 0);
this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
+ this->SetPropertyDefault("GNUtoMS", 0);
this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
this->SetPropertyDefault("AUTOMOC", 0);
this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
@@ -3472,6 +3490,26 @@ void cmTarget::GetExecutableNames(std::string& name,
}
//----------------------------------------------------------------------------
+bool cmTarget::HasImplibGNUtoMS()
+{
+ return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::GetImplibGNUtoMS(std::string const& gnuName,
+ std::string& out, const char* newExt)
+{
+ if(this->HasImplibGNUtoMS() &&
+ gnuName.size() > 6 && gnuName.substr(gnuName.size()-6) == ".dll.a")
+ {
+ out = gnuName.substr(0, gnuName.size()-6);
+ out += newExt? newExt : ".lib";
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
void cmTarget::GenerateTargetManifest(const char* config)
{
cmMakefile* mf = this->Makefile;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 0abdddb..09fee6c 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -369,6 +369,14 @@ public:
std::string& impName,
std::string& pdbName, const char* config);
+ /** Does this target have a GNU implib to convert to MS format? */
+ bool HasImplibGNUtoMS();
+
+ /** Convert the given GNU import library name (.dll.a) to a name with a new
+ extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */
+ bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
+ const char* newExt = 0);
+
/** Add the target output files to the global generator manifest. */
void GenerateTargetManifest(const char* config);
diff --git a/Tests/ExportImport/CMakeLists.txt b/Tests/ExportImport/CMakeLists.txt
index 2e01c50..ccfb894 100644
--- a/Tests/ExportImport/CMakeLists.txt
+++ b/Tests/ExportImport/CMakeLists.txt
@@ -22,6 +22,11 @@ else(CMAKE_CONFIGURATION_TYPES)
endif(CMAKE_BUILD_TYPE)
endif(CMAKE_CONFIGURATION_TYPES)
+if(MINGW OR MSYS)
+ # Test CMAKE_GNUtoMS whether we have VS or not.
+ set(ExportImport_GNUtoMS 1)
+endif()
+
configure_file(${ExportImport_SOURCE_DIR}/InitialCache.cmake.in
${ExportImport_BINARY_DIR}/InitialCache.cmake @ONLY)
diff --git a/Tests/ExportImport/InitialCache.cmake.in b/Tests/ExportImport/InitialCache.cmake.in
index f920b1f..4893f70 100644
--- a/Tests/ExportImport/InitialCache.cmake.in
+++ b/Tests/ExportImport/InitialCache.cmake.in
@@ -12,3 +12,4 @@ SET(CMAKE_CXX_FLAGS_MINSIZEREL "@CMAKE_CXX_FLAGS_MINSIZEREL@" CACHE STRING "C++
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRING "C++ Flags")
SET(CMAKE_INSTALL_PREFIX "@ExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
SET(CMAKE_SKIP_RPATH ON CACHE BOOL "No RPATH")
+SET(CMAKE_GNUtoMS "@ExportImport_GNUtoMS@" CACHE BOOL "CMAKE_GNUtoMS")