提交 b9797157 编写于 作者: I ikrylov

6812297: update project creation for Visual Studio 2005-2008

Summary: Add 2 news classes to create VC8 and VC9 projects
Reviewed-by: apetrusenko, xlu
上级 e3ae90a5
...@@ -52,6 +52,19 @@ CAT="$MKS_HOME/cat.exe" ...@@ -52,6 +52,19 @@ CAT="$MKS_HOME/cat.exe"
RM="$MKS_HOME/rm.exe" RM="$MKS_HOME/rm.exe"
DUMPBIN="link.exe /dump" DUMPBIN="link.exe /dump"
# When called from IDE the first param should contain the link version, otherwise may be nill
if [ "x$1" != "x" ]; then
LINK_VER="$1"
fi
if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" ]; then
$DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def $DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
else
# Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def
$DUMPBIN /OUT:vm3.def /symbols *.obj
"$CAT" vm3.def | "$GREP" "??_7.*@@6B@" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
"$RM" -f vm3.def
fi
"$CAT" vm1.def vm2.def > vm.def "$CAT" vm1.def vm2.def > vm.def
"$RM" -f vm1.def vm2.def "$RM" -f vm1.def vm2.def
...@@ -72,12 +72,20 @@ REM figure out MSC version ...@@ -72,12 +72,20 @@ REM figure out MSC version
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
echo ************************************************************** echo **************************************************************
set ProjectFile=vm.vcproj
if "%MSC_VER%" == "1200" ( if "%MSC_VER%" == "1200" (
set ProjectFile=vm.dsp set ProjectFile=vm.dsp
echo Will generate VC6 project {unsupported} echo Will generate VC6 project {unsupported}
) else ( ) else (
set ProjectFile=vm.vcproj if "%MSC_VER%" == "1400" (
echo Will generate VC7 project echo Will generate VC8 {Visual Studio 2005}
) else (
if "%MSC_VER%" == "1500" (
echo Will generate VC9 {Visual Studio 2008}
) else (
echo Will generate VC7 project {Visual Studio 2003 .NET}
)
)
) )
echo %ProjectFile% echo %ProjectFile%
echo ************************************************************** echo **************************************************************
......
...@@ -46,6 +46,7 @@ ADLCFLAGS=-q -T -D_LP64 ...@@ -46,6 +46,7 @@ ADLCFLAGS=-q -T -D_LP64
ADLCFLAGS=-q -T -U_LP64 ADLCFLAGS=-q -T -U_LP64
!endif !endif
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
CPP_INCLUDE_DIRS=\ CPP_INCLUDE_DIRS=\
/I "..\generated" \ /I "..\generated" \
......
...@@ -170,8 +170,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) ...@@ -170,8 +170,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
# Manifest Tool - used in VS2005 and later to adjust manifests stored # Manifest Tool - used in VS2005 and later to adjust manifests stored
# as resources inside build artifacts. # as resources inside build artifacts.
MT=mt.exe MT=mt.exe
# VS2005 and later restricts the use of certain libc functions without this
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
!endif !endif
!if "$(COMPILER_NAME)" == "VS2008" !if "$(COMPILER_NAME)" == "VS2008"
...@@ -183,8 +181,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS) ...@@ -183,8 +181,6 @@ LINK_FLAGS = /manifest $(LINK_FLAGS)
# Manifest Tool - used in VS2005 and later to adjust manifests stored # Manifest Tool - used in VS2005 and later to adjust manifests stored
# as resources inside build artifacts. # as resources inside build artifacts.
MT=mt.exe MT=mt.exe
# VS2005 and later restricts the use of certain libc functions without this
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
!endif !endif
# Compile for space above time. # Compile for space above time.
......
...@@ -48,6 +48,8 @@ MakeDepsSources=\ ...@@ -48,6 +48,8 @@ MakeDepsSources=\
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatform.java \ $(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatform.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC6.java \ $(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC6.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC7.java \ $(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC7.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC8.java \
$(WorkSpace)\src\share\tools\MakeDeps\WinGammaPlatformVC9.java \
$(WorkSpace)\src\share\tools\MakeDeps\Util.java \ $(WorkSpace)\src\share\tools\MakeDeps\Util.java \
$(WorkSpace)\src\share\tools\MakeDeps\BuildConfig.java \ $(WorkSpace)\src\share\tools\MakeDeps\BuildConfig.java \
$(WorkSpace)\src\share\tools\MakeDeps\ArgsParser.java $(WorkSpace)\src\share\tools\MakeDeps\ArgsParser.java
...@@ -121,7 +123,7 @@ MakeDepsIDEOptions=\ ...@@ -121,7 +123,7 @@ MakeDepsIDEOptions=\
-additionalFile includeDB_gc_shared \ -additionalFile includeDB_gc_shared \
-additionalFile includeDB_gc_serial \ -additionalFile includeDB_gc_serial \
-additionalGeneratedFile $(HOTSPOTBUILDSPACE)\%f\%b vm.def \ -additionalGeneratedFile $(HOTSPOTBUILDSPACE)\%f\%b vm.def \
-prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh" \ -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
$(MakeDepsIncludesPRIVATE) $(MakeDepsIncludesPRIVATE)
# Add in build-specific options # Add in build-specific options
......
...@@ -42,10 +42,23 @@ COMPILE_RMIC=rmic ...@@ -42,10 +42,23 @@ COMPILE_RMIC=rmic
BOOT_JAVA_HOME= BOOT_JAVA_HOME=
!endif !endif
ProjectFile=vm.vcproj
!if "$(MSC_VER)" == "1200" !if "$(MSC_VER)" == "1200"
VcVersion=VC6 VcVersion=VC6
ProjectFile=vm.dsp ProjectFile=vm.dsp
!elseif "$(MSC_VER)" == "1400"
VcVersion=VC8
!elseif "$(MSC_VER)" == "1500"
VcVersion=VC9
!else !else
VcVersion=VC7 VcVersion=VC7
ProjectFile=vm.vcproj
!endif !endif
...@@ -27,6 +27,8 @@ import java.util.*; ...@@ -27,6 +27,8 @@ import java.util.*;
public class WinGammaPlatformVC7 extends WinGammaPlatform { public class WinGammaPlatformVC7 extends WinGammaPlatform {
String projectVersion() {return "7.10";};
public void writeProjectFile(String projectFileName, String projectName, public void writeProjectFile(String projectFileName, String projectName,
Vector allConfigs) throws IOException { Vector allConfigs) throws IOException {
System.out.println(); System.out.println();
...@@ -40,7 +42,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform { ...@@ -40,7 +42,7 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
"VisualStudioProject", "VisualStudioProject",
new String[] { new String[] {
"ProjectType", "Visual C++", "ProjectType", "Visual C++",
"Version", "7.10", "Version", projectVersion(),
"Name", projectName, "Name", projectName,
"ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}", "ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}",
"SccProjectName", "", "SccProjectName", "",
...@@ -417,7 +419,9 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform { ...@@ -417,7 +419,9 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
new String[] { new String[] {
"Name", "VCPreLinkEventTool", "Name", "VCPreLinkEventTool",
"Description", BuildConfig.getFieldString(null, "PrelinkDescription"), "Description", BuildConfig.getFieldString(null, "PrelinkDescription"),
"CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace('\t', '\n')) //Caution: String.replace(String,String) is available from JDK5 onwards only
"CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace
("\t", "
"))
} }
); );
...@@ -542,25 +546,41 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform { ...@@ -542,25 +546,41 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
} }
class CompilerInterfaceVC7 extends CompilerInterface { class CompilerInterfaceVC7 extends CompilerInterface {
Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) { void getBaseCompilerFlags_common(Vector defines, Vector includes, String outDir,Vector rv) {
Vector rv = new Vector();
// advanced M$ IDE (2003) can only recognize name if it's first or // advanced M$ IDE (2003) can only recognize name if it's first or
// second attribute in the tag - go guess // second attribute in the tag - go guess
addAttr(rv, "Name", "VCCLCompilerTool"); addAttr(rv, "Name", "VCCLCompilerTool");
addAttr(rv, "AdditionalIncludeDirectories", Util.join(",", includes)); addAttr(rv, "AdditionalIncludeDirectories", Util.join(",", includes));
addAttr(rv, "PreprocessorDefinitions", Util.join(";", defines).replace("\"",""")); addAttr(rv, "PreprocessorDefinitions",
addAttr(rv, "UsePrecompiledHeader", "3"); Util.join(";", defines).replace("\"","""));
addAttr(rv, "PrecompiledHeaderThrough", "incls"+Util.sep+"_precompiled.incl"); addAttr(rv, "PrecompiledHeaderThrough",
"incls"+Util.sep+"_precompiled.incl");
addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch"); addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch");
addAttr(rv, "AssemblerListingLocation", outDir); addAttr(rv, "AssemblerListingLocation", outDir);
addAttr(rv, "ObjectFile", outDir+Util.sep); addAttr(rv, "ObjectFile", outDir+Util.sep);
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"vm.pdb"); addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"vm.pdb");
// Set /nologo optin
addAttr(rv, "SuppressStartupBanner", "TRUE"); addAttr(rv, "SuppressStartupBanner", "TRUE");
// Surpass the default /Tc or /Tp. 0 is compileAsDefault
addAttr(rv, "CompileAs", "0"); addAttr(rv, "CompileAs", "0");
// Set /W3 option. 3 is warningLevel_3
addAttr(rv, "WarningLevel", "3"); addAttr(rv, "WarningLevel", "3");
// Set /WX option,
addAttr(rv, "WarnAsError", "TRUE"); addAttr(rv, "WarnAsError", "TRUE");
// Set /GS option
addAttr(rv, "BufferSecurityCheck", "FALSE"); addAttr(rv, "BufferSecurityCheck", "FALSE");
// Set /Zi option. 3 is debugEnabled
addAttr(rv, "DebugInformationFormat", "3");
}
Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
Vector rv = new Vector();
getBaseCompilerFlags_common(defines,includes, outDir, rv);
// Set /Yu option. 3 is pchUseUsingSpecific
// Note: Starting VC8 pchUseUsingSpecific is 2 !!!
addAttr(rv, "UsePrecompiledHeader", "3");
// Set /EHsc- option
addAttr(rv, "ExceptionHandling", "FALSE"); addAttr(rv, "ExceptionHandling", "FALSE");
return rv; return rv;
...@@ -579,27 +599,39 @@ class CompilerInterfaceVC7 extends CompilerInterface { ...@@ -579,27 +599,39 @@ class CompilerInterfaceVC7 extends CompilerInterface {
"/export:jio_vsnprintf "); "/export:jio_vsnprintf ");
addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib"); addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
addAttr(rv, "OutputFile", outDll); addAttr(rv, "OutputFile", outDll);
// Set /INCREMENTAL option. 1 is linkIncrementalNo
addAttr(rv, "LinkIncremental", "1"); addAttr(rv, "LinkIncremental", "1");
addAttr(rv, "SuppressStartupBanner", "TRUE"); addAttr(rv, "SuppressStartupBanner", "TRUE");
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"vm.pdb"); addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"vm.pdb");
// Set /SUBSYSTEM option. 2 is subSystemWindows
addAttr(rv, "SubSystem", "2"); addAttr(rv, "SubSystem", "2");
addAttr(rv, "BaseAddress", "0x8000000"); addAttr(rv, "BaseAddress", "0x8000000");
addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
// Set /MACHINE option. 1 is machineX86
addAttr(rv, "TargetMachine", "1"); addAttr(rv, "TargetMachine", "1");
return rv; return rv;
} }
Vector getDebugCompilerFlags(String opt) { void getDebugCompilerFlags_common(String opt,Vector rv) {
Vector rv = new Vector();
// Set /On option
addAttr(rv, "Optimization", opt); addAttr(rv, "Optimization", opt);
addAttr(rv, "OptimizeForProcessor", "1"); // Set /FR option. 1 is brAllInfo
addAttr(rv, "DebugInformationFormat", "3");
addAttr(rv, "RuntimeLibrary", "2");
addAttr(rv, "BrowseInformation", "1"); addAttr(rv, "BrowseInformation", "1");
addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep); addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep);
// Set /MD option. 2 is rtMultiThreadedDLL
addAttr(rv, "RuntimeLibrary", "2");
// Set /Oy- option
addAttr(rv, "OmitFramePointers", "FALSE");
}
Vector getDebugCompilerFlags(String opt) {
Vector rv = new Vector();
getDebugCompilerFlags_common(opt,rv);
return rv; return rv;
} }
...@@ -607,18 +639,29 @@ class CompilerInterfaceVC7 extends CompilerInterface { ...@@ -607,18 +639,29 @@ class CompilerInterfaceVC7 extends CompilerInterface {
Vector getDebugLinkerFlags() { Vector getDebugLinkerFlags() {
Vector rv = new Vector(); Vector rv = new Vector();
addAttr(rv, "GenerateDebugInformation", "TRUE"); addAttr(rv, "GenerateDebugInformation", "TRUE"); // == /DEBUG option
return rv; return rv;
} }
void getProductCompilerFlags_common(Vector rv) {
// Set /O2 option. 2 is optimizeMaxSpeed
addAttr(rv, "Optimization", "2");
// Set /Oy- option
addAttr(rv, "OmitFramePointers", "FALSE");
}
Vector getProductCompilerFlags() { Vector getProductCompilerFlags() {
Vector rv = new Vector(); Vector rv = new Vector();
addAttr(rv, "Optimization", "2"); getProductCompilerFlags_common(rv);
// Set /Ob option. 1 is expandOnlyInline
addAttr(rv, "InlineFunctionExpansion", "1"); addAttr(rv, "InlineFunctionExpansion", "1");
// Set /GF option.
addAttr(rv, "StringPooling", "TRUE"); addAttr(rv, "StringPooling", "TRUE");
// Set /MD option. 2 is rtMultiThreadedDLL
addAttr(rv, "RuntimeLibrary", "2"); addAttr(rv, "RuntimeLibrary", "2");
// Set /Gy option
addAttr(rv, "EnableFunctionLevelLinking", "TRUE"); addAttr(rv, "EnableFunctionLevelLinking", "TRUE");
return rv; return rv;
...@@ -627,7 +670,9 @@ class CompilerInterfaceVC7 extends CompilerInterface { ...@@ -627,7 +670,9 @@ class CompilerInterfaceVC7 extends CompilerInterface {
Vector getProductLinkerFlags() { Vector getProductLinkerFlags() {
Vector rv = new Vector(); Vector rv = new Vector();
// Set /OPT:REF option. 2 is optReferences
addAttr(rv, "OptimizeReferences", "2"); addAttr(rv, "OptimizeReferences", "2");
// Set /OPT:optFolding option. 2 is optFolding
addAttr(rv, "EnableCOMDATFolding", "2"); addAttr(rv, "EnableCOMDATFolding", "2");
return rv; return rv;
......
/*
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
import java.io.*;
import java.util.*;
public class WinGammaPlatformVC8 extends WinGammaPlatformVC7 {
String projectVersion() {return "8.00";};
}
class CompilerInterfaceVC8 extends CompilerInterfaceVC7 {
Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
Vector rv = new Vector();
getBaseCompilerFlags_common(defines,includes, outDir, rv);
// Set /Yu option. 2 is pchUseUsingSpecific
addAttr(rv, "UsePrecompiledHeader", "2");
// Set /EHsc- option. 0 is cppExceptionHandlingNo
addAttr(rv, "ExceptionHandling", "0");
return rv;
}
Vector getDebugCompilerFlags(String opt) {
Vector rv = new Vector();
getDebugCompilerFlags_common(opt,rv);
return rv;
}
Vector getProductCompilerFlags() {
Vector rv = new Vector();
getProductCompilerFlags_common(rv);
return rv;
}
}
/*
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
import java.io.*;
import java.util.*;
public class WinGammaPlatformVC9 extends WinGammaPlatformVC8 {
String projectVersion() {return "9.00";};
}
class CompilerInterfaceVC9 extends CompilerInterfaceVC8 {
}
...@@ -153,14 +153,6 @@ const jlong max_jlong = CONST64(0x7fffffffffffffff); ...@@ -153,14 +153,6 @@ const jlong max_jlong = CONST64(0x7fffffffffffffff);
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Miscellaneous // Miscellaneous
inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
// If number of characters written == count, Windows doesn't write a
// terminating NULL, so we do it ourselves.
int ret = _vsnprintf(buf, count, fmt, argptr);
if (count > 0) buf[count-1] = '\0';
return ret;
}
// Visual Studio 2005 deprecates POSIX names - use ISO C++ names instead // Visual Studio 2005 deprecates POSIX names - use ISO C++ names instead
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
#define open _open #define open _open
...@@ -180,6 +172,17 @@ inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) { ...@@ -180,6 +172,17 @@ inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
#pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union (needed in windows.h) #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union (needed in windows.h)
#pragma warning( disable : 4511 ) // copy constructor could not be generated #pragma warning( disable : 4511 ) // copy constructor could not be generated
#pragma warning( disable : 4291 ) // no matching operator delete found; memory will not be freed if initialization thows an exception #pragma warning( disable : 4291 ) // no matching operator delete found; memory will not be freed if initialization thows an exception
#if _MSC_VER >= 1400
#pragma warning( disable : 4996 ) // unsafe string functions. Same as define _CRT_SECURE_NO_WARNINGS/_CRT_SECURE_NO_DEPRICATE
#endif
inline int vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
// If number of characters written == count, Windows doesn't write a
// terminating NULL, so we do it ourselves.
int ret = _vsnprintf(buf, count, fmt, argptr);
if (count > 0) buf[count-1] = '\0';
return ret;
}
// Portability macros // Portability macros
#define PRAGMA_INTERFACE #define PRAGMA_INTERFACE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册