• Linux 下编译openjdk


    操作系统ubuntu14.04

    openjdk版本 7u4

    openjdk7u4可以在https://jdk7.java.net/source.html下载

    一.构建编译环境

    sudo apt-get install build-essential gawk m4 openjdk-6-jdk
    libasound2-dev libcups2-dev libxrender-dev xorg-dev xutils-dev
    x11proto-print-dev binutils libmotif3 libmotif-dev ant

    二.设置环境变量

    export LANG=C
    
    #编译openjdk7所需要的jdk目录,注意jdk的版本
    #试过jdk1.8和1.7的其他版本,在运行时就出现bug
    export ALT_BOOTDIR=/home/foreverenjoy/Program/jdk1.7.0_04
    
    export ALLOW_DOWNLOADS=true
    export USE_PRECOMPILED_HEADER=true
    export SKIP_DEBUG_BUILD=false
    export SKIP_FASTDEBUG_BUILD=true
    export DEBUG_NAME=debug
    
    unset CLASSPATH
    unset JAVA_HOME

    三.检查设置是否正确

    在终端输入make sanity

      1 ( cd  ./jdk/make && 
      2       make sanity HOTSPOT_IMPORT_CHECK=false JDK_TOPDIR=/home/foreverenjoy/Program/openjdk/jdk JDK_MAKE_SHARED_DIR=/home/foreverenjoy/Program/openjdk/jdk/make/common/shared EXTERNALSANITYCONTROL=true SOURCE_LANGUAGE_VERSION=7 TARGET_CLASS_VERSION=7 MILESTONE=internal BUILD_NUMBER=b00 JDK_BUILD_NUMBER=b00 FULL_VERSION=1.7.0-internal-debug-foreverenjoy_2016_07_03_19_04-b00 PREVIOUS_JDK_VERSION=1.6.0 JDK_VERSION=1.7.0 JDK_MKTG_VERSION=7 JDK_MAJOR_VERSION=1 JDK_MINOR_VERSION=7 JDK_MICRO_VERSION=0 PREVIOUS_MAJOR_VERSION=1 PREVIOUS_MINOR_VERSION=6 PREVIOUS_MICRO_VERSION=0 ARCH_DATA_MODEL=64 VARIANT=DBG DEBUG_CLASSFILES=true COOKED_BUILD_NUMBER=0 ALT_OUTPUTDIR=/home/foreverenjoy/Program/openjdk/build/linux-amd64 ALT_LANGTOOLS_DIST=/home/foreverenjoy/Program/openjdk/build/linux-amd64/langtools/dist ALT_CORBA_DIST=/home/foreverenjoy/Program/openjdk/build/linux-amd64/corba/dist ALT_JAXP_DIST=/home/foreverenjoy/Program/openjdk/build/linux-amd64/jaxp/dist ALT_JAXWS_DIST=/home/foreverenjoy/Program/openjdk/build/linux-amd64/jaxws/dist ALT_HOTSPOT_IMPORT_PATH=/home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/import BUILD_HOTSPOT=true ; )
      3 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1
      4 INFO: /usr/bin/objcopy cmd found so will create .debuginfo files.
      5 INFO: STRIP_POLICY=min_strip
      6 INFO: ZIP_DEBUGINFO_FILES=1
      7 make[1]: Entering directory `/home/foreverenjoy/Program/openjdk/jdk/make'
      8 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1
      9 INFO: /usr/bin/objcopy cmd found so will create .debuginfo files.
     10 INFO: STRIP_POLICY=min_strip
     11 INFO: ZIP_DEBUGINFO_FILES=1
     12 make[1]: Leaving directory `/home/foreverenjoy/Program/openjdk/jdk/make'
     13 
     14 Build Machine Information:
     15    build machine = foreverenjoy
     16 
     17 Build Directory Structure:
     18    CWD = /home/foreverenjoy/Program/openjdk
     19    TOPDIR = .
     20    LANGTOOLS_TOPDIR = ./langtools
     21    JAXP_TOPDIR = ./jaxp
     22    JAXWS_TOPDIR = ./jaxws
     23    CORBA_TOPDIR = ./corba
     24    HOTSPOT_TOPDIR = ./hotspot
     25    JDK_TOPDIR = ./jdk
     26 
     27 Build Directives:
     28    BUILD_LANGTOOLS = true 
     29    BUILD_JAXP = true 
     30    BUILD_JAXWS = true 
     31    BUILD_CORBA = true 
     32    BUILD_HOTSPOT = true 
     33    BUILD_JDK    = true 
     34    DEBUG_CLASSFILES =  
     35    DEBUG_BINARIES =  
     36 
     37 Hotspot Settings: 
     38       HOTSPOT_BUILD_JOBS  =  
     39       HOTSPOT_OUTPUTDIR   = /home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/outputdir 
     40       HOTSPOT_EXPORT_PATH = /home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/import 
     41  
     42 
     43 
     44 
     45 Bootstrap Settings:
     46   BOOTDIR = /usr/lib/jvm/java-6-openjdk-amd64
     47     ALT_BOOTDIR = /usr/lib/jvm/java-6-openjdk-amd64
     48   BOOT_VER = 1.6.0 [requires at least 1.6]
     49   OUTPUTDIR = /home/foreverenjoy/Program/openjdk/build/linux-amd64
     50     ALT_OUTPUTDIR = /home/foreverenjoy/Program/openjdk/build/linux-amd64
     51   ABS_OUTPUTDIR = /home/foreverenjoy/Program/openjdk/build/linux-amd64
     52  
     53 Build Tool Settings:
     54   SLASH_JAVA = /NOT-SET
     55     ALT_SLASH_JAVA = 
     56   VARIANT = DBG
     57   JDK_DEVTOOLS_DIR = /NOT-SET/devtools
     58     ALT_JDK_DEVTOOLS_DIR = 
     59   ANT_HOME = 
     60   UNIXCOMMAND_PATH = /bin/
     61     ALT_UNIXCOMMAND_PATH = 
     62   COMPILER_PATH = /usr/bin/
     63     ALT_COMPILER_PATH = 
     64   DEVTOOLS_PATH = /usr/bin/
     65     ALT_DEVTOOLS_PATH = 
     66   UNIXCCS_PATH = /usr/ccs/bin/
     67     ALT_UNIXCCS_PATH = 
     68   USRBIN_PATH = /usr/bin/
     69     ALT_USRBIN_PATH = 
     70   COMPILER_NAME = GCC4
     71   COMPILER_VERSION = GCC4
     72   CC_VER = 4.8 [requires at least 4.3.0]
     73   ZIP_VER = 3.0 [requires at least 2.2]
     74   UNZIP_VER = 6.00 [requires at least 5.12]
     75   ANT_VER = 1.9.3 [requires at least 1.7.1]
     76   TEMPDIR = /home/foreverenjoy/Program/openjdk/build/linux-amd64/tmp
     77  
     78 Build Directives:
     79   OPENJDK = true
     80   USE_HOTSPOT_INTERPRETER_MODE = 
     81   PEDANTIC = 
     82   DEV_ONLY = 
     83   NO_DOCS = 
     84   NO_IMAGES = 
     85   TOOLS_ONLY = 
     86   INSANE = 
     87   COMPILE_APPROACH = parallel
     88   PARALLEL_COMPILE_JOBS = 2
     89     ALT_PARALLEL_COMPILE_JOBS = 
     90   FASTDEBUG = 
     91   COMPILER_WARNINGS_FATAL = false
     92   COMPILER_WARNING_LEVEL = 
     93   SHOW_ALL_WARNINGS = 
     94   INCREMENTAL_BUILD = false
     95   CC_HIGHEST_OPT = 
     96   CC_HIGHER_OPT = 
     97   CC_LOWER_OPT = 
     98   CXXFLAGS =  -g -fPIC -DCC_NOEX -W -Wall  -Wno-unused -Wno-parentheses -fno-omit-frame-pointer -D_LITTLE_ENDIAN  
     99   CFLAGS =  -g   -fno-strict-aliasing -fPIC -W -Wall  -Wno-unused -Wno-parentheses -pipe -fno-omit-frame-pointer -D_LITTLE_ENDIAN  
    100   BOOT_JAVA_CMD = /usr/lib/jvm/java-6-openjdk-amd64/bin/java -XX:-PrintVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-LogVMOutput -Xmx512m -Xms512m -XX:PermSize=32m -XX:MaxPermSize=160m
    101   BOOT_JAVAC_CMD = /usr/lib/jvm/java-6-openjdk-amd64/bin/javac  -J-XX:ThreadStackSize=1536 -J-XX:-PrintVMOptions -J-XX:+UnlockDiagnosticVMOptions -J-XX:-LogVMOutput -J-Xmx512m -J-Xms512m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -encoding ascii -source 6 -target 6 -XDignore.symbol.file=true
    102   BOOT_JAR_CMD = /usr/lib/jvm/java-6-openjdk-amd64/bin/jar
    103   BOOT_JARSIGNER_CMD = /usr/lib/jvm/java-6-openjdk-amd64/bin/jarsigner
    104   JAVAC_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-amd64/bin/javac  -J-XX:ThreadStackSize=1536 -J-XX:-PrintVMOptions -J-XX:+UnlockDiagnosticVMOptions -J-XX:-LogVMOutput -J-Xmx512m -J-Xms512m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m  -g -source 7 -target 7 -encoding ascii -Xbootclasspath:/home/foreverenjoy/Program/openjdk/build/linux-amd64/classes 
    105   JAVAH_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-amd64/bin/javah -bootclasspath /home/foreverenjoy/Program/openjdk/build/linux-amd64/classes
    106   JAVADOC_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-amd64/bin/javadoc -J-XX:-PrintVMOptions -J-XX:+UnlockDiagnosticVMOptions -J-XX:-LogVMOutput -J-Xmx512m -J-Xms512m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -bootclasspath /home/foreverenjoy/Program/openjdk/build/linux-amd64/classes
    107  
    108 Build Platform Settings:
    109   USER = foreverenjoy
    110   PLATFORM = linux
    111   ARCH = amd64
    112   LIBARCH = amd64
    113   ARCH_FAMILY = amd64
    114   ARCH_DATA_MODEL = 64
    115   ARCHPROP = amd64
    116   ALSA_VERSION = 1.0.27.2
    117   OS_VERSION = 3.19.0-59-generic [requires at least 2.6]
    118   OS_VARIANT_NAME = Ubuntu
    119   OS_VARIANT_VERSION = 14.04
    120   MB_OF_MEMORY = 7555
    121  
    122 GNU Make Settings:
    123   MAKE = make
    124   MAKE_VER = 3.81 [requires at least 3.81]
    125   MAKECMDGOALS = sanity
    126   MAKEFLAGS = w
    127   SHELL = /bin/sh
    128  
    129 Target Build Versions:
    130   JDK_VERSION = 1.7.0
    131   MILESTONE = internal
    132   RELEASE = 1.7.0-internal-debug
    133   FULL_VERSION = 1.7.0-internal-debug-foreverenjoy_2016_07_03_19_04-b00
    134   BUILD_NUMBER = b00
    135  
    136 External File/Binary Locations:
    137   USRJDKINSTANCES_PATH = /opt/java
    138   BUILD_JDK_IMPORT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries
    139     ALT_BUILD_JDK_IMPORT_PATH = 
    140   JDK_IMPORT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-amd64
    141     ALT_JDK_IMPORT_PATH = 
    142   LANGTOOLS_DIST = 
    143     ALT_LANGTOOLS_DIST = /home/foreverenjoy/Program/openjdk/build/linux-amd64/langtools/dist
    144   CORBA_DIST = 
    145     ALT_CORBA_DIST = /home/foreverenjoy/Program/openjdk/build/linux-amd64/corba/dist
    146   JAXP_DIST = 
    147     ALT_JAXP_DIST = /home/foreverenjoy/Program/openjdk/build/linux-amd64/jaxp/dist
    148   JAXWS_DIST = 
    149     ALT_JAXWS_DIST = /home/foreverenjoy/Program/openjdk/build/linux-amd64/jaxws/dist
    150   HOTSPOT_DOCS_IMPORT_PATH = /NO_DOCS_DIR
    151     ALT_HOTSPOT_DOCS_IMPORT_PATH = 
    152   HOTSPOT_IMPORT_PATH = /home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/import
    153     ALT_HOTSPOT_IMPORT_PATH = /home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/import
    154   HOTSPOT_SERVER_PATH = /home/foreverenjoy/Program/openjdk/build/linux-amd64/hotspot/import/jre/lib/amd64/server
    155     ALT_HOTSPOT_SERVER_PATH = 
    156   CACERTS_FILE = ./../src/share/lib/security/cacerts
    157     ALT_CACERTS_FILE = 
    158   CUPS_HEADERS_PATH = /usr/include
    159     ALT_CUPS_HEADERS_PATH = 
    160  
    161 OpenJDK-specific settings:
    162   FREETYPE_HEADERS_PATH = /usr/include
    163     ALT_FREETYPE_HEADERS_PATH = 
    164   FREETYPE_LIB_PATH = /usr/lib
    165     ALT_FREETYPE_LIB_PATH = 
    166  
    167 Previous JDK Settings:
    168   PREVIOUS_RELEASE_PATH = USING-PREVIOUS_RELEASE_IMAGE
    169     ALT_PREVIOUS_RELEASE_PATH = 
    170   PREVIOUS_JDK_VERSION = 1.6.0
    171     ALT_PREVIOUS_JDK_VERSION = 
    172   PREVIOUS_JDK_FILE = 
    173     ALT_PREVIOUS_JDK_FILE = 
    174   PREVIOUS_JRE_FILE = 
    175     ALT_PREVIOUS_JRE_FILE = 
    176   PREVIOUS_RELEASE_IMAGE = /usr/lib/jvm/java-6-openjdk-amd64
    177     ALT_PREVIOUS_RELEASE_IMAGE = 
    178 
    179 
    180 Sanity check passed.
    View Code

    如果看到"Sanity check passend.",说明检查通过。

    四.开始编译

    在终端输入make

    等一段时间

    #-- Build times ----------
    Target debug_build
    Start 2016-07-03 19:25:12
    End   2016-07-03 19:41:06
    00:01:19 corba
    00:05:24 hotspot
    00:00:15 jaxp
    00:00:18 jaxws
    00:08:11 jdk
    00:00:27 langtools
    00:15:54 TOTAL
    -------------------------
    编译完成

    在OpenJDK目录下有个build文件夹是编译的output文件夹 

    foreverenjoy@foreverenjoy:~/Program/openjdk$ cd build/
    foreverenjoy@foreverenjoy:~/Program/openjdk/build$ ls -l
    total 8
    drwxrwxr-x 29 foreverenjoy foreverenjoy 4096  7月  3 19:41 linux-amd64
    drwxrwxr-x 28 foreverenjoy foreverenjoy 4096  7月  3 19:25 linux-amd64-debug
    foreverenjoy@foreverenjoy:~/Program/openjdk/build$ cd linux-amd64/bin/
    foreverenjoy@foreverenjoy:~/Program/openjdk/build/linux-amd64/bin$ ./java -version
    openjdk version "1.7.0-internal-debug"
    OpenJDK Runtime Environment (build 1.7.0-internal-debug-foreverenjoy_2016_07_03_19_19-b00)
    OpenJDK 64-Bit Server VM (build 24.0-b56-jvmg, mixed mode)
    编译结果

    五.遇到的问题

    1.

    make[6]: Leaving directory /usr/local/openjdk/build/linux-amd64-debug/hotspot/outputdir/linux_amd64_compiler2/jvmg'
    cd linux_amd64_compiler2/jvmg && ./test_gamma
    Using java runtime at: /usr/lib/jvm/java-1.6.0-openjdk.x86_64/jre
    ./gamma: relocation error: /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.33.x86_64/jre/lib/amd64/libjava.so: symbol JVM_FindClassFromCaller, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference
    make[5]: *** [jvmg] Error 127
    make[5]: Leaving directory/usr/local/openjdk/build/linux-amd64-debug/hotspot/outputdir' make[4]: * [generic_build2] Error 2 make[4]: Leaving directory /usr/local/openjdk/hotspot/make'
    make[3]: *** [jvmg] Error 2
    make[3]: Leaving directory/usr/local/openjdk/hotspot/make' make[2]: * [hotspot-build] Error 2 make[2]: Leaving directory /usr/local/openjdk'
    make[1]: *** [generic_debug_build] Error 2
    make[1]: Leaving directory/usr/local/openjdk'
    symbol JVM_FindClassFromCaller, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference

    删除hotspot/make/linux/Makefile中所有的test_gamma ( 即删掉所有的&& ./test_gamma)

    2.

    m -XX:MaxPermSize=160m -jar /home/foreverenjoy/Program/openjdk/build/linux-amd64/../linux-amd64-debug/btjars/generatecurrencydata.jar -o /home/foreverenjoy/Program/openjdk/build/linux-amd64/../linux-amd64-debug/lib/currency.data.temp 
            < ../../../src/share/classes/java/util/CurrencyData.properties
    Error: time is more than 10 years from present: 1136059200000
    java.lang.RuntimeException: time is more than 10 years from present: 1136059200000
        at build.tools.generatecurrencydata.GenerateCurrencyData.makeSpecialCaseEntry(GenerateCurrencyData.java:285)
        at build.tools.generatecurrencydata.GenerateCurrencyData.buildMainAndSpecialCaseTables(GenerateCurrencyData.java:225)
        at build.tools.generatecurrencydata.GenerateCurrencyData.main(GenerateCurrencyData.java:154)
    make[5]: *** [/home/foreverenjoy/Program/openjdk/build/linux-amd64/../linux-amd64-debug/lib/currency.data] Error 1
    make[5]: Leaving directory `/home/foreverenjoy/Program/openjdk/jdk/make/java/java'
    make[4]: *** [all] Error 1
    make[4]: Leaving directory `/home/foreverenjoy/Program/openjdk/jdk/make/java'
    make[3]: *** [all] Error 1
    make[3]: Leaving directory `/home/foreverenjoy/Program/openjdk/jdk/make'
    make[2]: *** [jdk-build] Error 2
    make[2]: Leaving directory `/home/foreverenjoy/Program/openjdk'
    make[1]: *** [generic_debug_build] Error 2
    make[1]: Leaving directory `/home/foreverenjoy/Program/openjdk'
    make: *** [build_debug_image] Error 2
    time is more than 10 years from present: 1136059200000

    将CurrencyData.properties内的时间改为10年内

    六.在NetBeans编译运行HotSpot

    NetBeans下载地址:http://netbeans.org/   下载时选择支持C/C++开发的版本。

    首先新建项目,选择 基于现有源代码的C/C++选项

    在 源码文件夹中填入OpenJDK目录下hotspot目录的路径,在下面的单选按钮中选择“定制”,点击下一步

    预构建模块中的设置如下:

    进入下一步,在Build Comman中输入

    #当前目录为hotspot,make后加参数-C make/ -f Makefile,make会在读取Makefile之前改变到目录hotspot/make/
    ${MAKE} -C make/ -f Makefile clean jvmg  ALT_BOOTDIR=/home/foreverenjoy/Program/jdk1.7.0_04 ARCH_DATA_MODEL=64 LANG=C

    然后一直点击下一步,结束后右击项目,点击Build。

    Build成功之后,右击项目,选择项目属性。

    修改Run Cammand,Run Directory和添加Environment(环境变量)

     

    Run Cammand:
    #运行ClaA类
    /home/foreverenjoy/Program/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg/gamma ClaA
    
    Run Directory:
    /home/foreverenjoy/Program/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg
    
    ClASSPATH:
    #/home/foreverenjoy/Program/javaProject是ClaA的目录
    .:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/jre/lib/i18n.jar:/home/foreverenjoy/Program/javaProject
    
    JAVA_HOME:
    /home/foreverenjoy/Program/jdk1.7.0_04
    
    LD_LIBRARY_PATH:
    .:${JAVA_HOME}/jre/lib/amd64/native_threads:${JAVA_HOME}/jre/lib/amd64:

    最后点击Run就可以了

    最后附上hotspot的源码结构

    ├─agent                    Serviceability Agent的客户端实现
    ├─make                     用来build出HotSpot的各种配置文件
    ├─src                          HotSpot VM的源代码
    │  ├─cpu                       CPU相关代码(汇编器、模板解释器、ad文件、部分runtime函数在这里实现)
    │  ├─os                        操作系相关代码
    │  ├─os_cpu                    操作系统+CPU的组合相关的代码
    │  └─share                     平台无关的共通代码
    │      ├─tools                    工具
    │      │  ├─hsdis                    反汇编插件
    │      │  ├─IdealGraphVisualizer     将server编译器的中间代码可视化的工具
    │      │  ├─launcher                 启动程序“Java”
    │      │  ├─LogCompilation           将-XX:+LogCompilation输出的日志(hotspot.log)整理成更容易阅读的格式的工具
    │      │  └─ProjectCreator           生成Visual Studio的project文件的工具
    │      └─vm                       HotSpot VM的核心代码
    │          ├─adlc                    平台描述文件(上面的cpu或os_cpu里的*.ad文件)的编译器
    │          ├─asm                     汇编器接口
    │          ├─c1                      client编译器(又称“C1”)
    │          ├─ci                      动态编译器的公共服务/从动态编译器到VM的接口
    │          ├─classfile               类文件的处理(包括类加载和系统符号表等)
    │          ├─code                    动态生成的代码的管理
    │          ├─compiler                从VM调用动态编译器的接口
    │          ├─gc_implementation       GC的实现
    │          │  ├─concurrentMarkSweep      Concurrent Mark Sweep GC的实现
    │          │  ├─g1                       Garbage-First GC的实现(不使用老的分代式GC框架)
    │          │  ├─parallelScavenge         ParallelScavenge GC的实现(server VM默认,不使用老的分代式GC框架)
    │          │  ├─parNew                   ParNew GC的实现
    │          │  └─shared                   GC的共通实现
    │          ├─gc_interface            GC的接口
    │          ├─interpreter             解释器,包括“模板解释器”(官方版在用)和“C++解释器”(官方版不在用)
    │          ├─libadt                  一些抽象数据结构
    │          ├─memory                  内存管理相关(老的分代式GC框架也在这里)
    │          ├─oops                    HotSpot VM的对象系统的实现
    │          ├─opto                    server编译器(又称“C2”或“Opto”)
    │          ├─prims                   HotSpot VM的对外接口,包括部分标准库的native部分和JVMTI实现
    │          ├─runtime                 运行时支持库(包括线程管理、编译器调度、锁、反射等)
    │          ├─services                主要是用来支持JMX之类的管理功能的接口
    │          ├─shark                   基于LLVM的JIT编译器(官方版里没有使用)
    │          └─utilities               一些基本的工具类
    └─test                         单元测试
    HotSpot源码结构

      

    博客园(FOREVER_ENJOY):http://www.cnblogs.com/zyx1314/p/5638596.html
    本文版权归作者所有;欢迎转载!请注明文章作者和原文连接

  • 相关阅读:
    Java 注解
    java 编码设计细节
    快捷键大全
    java 常用方法
    用SelectSingleNode()方法查找xml节点一直返回null
    未能加载文件或程序集“microsoft.Build.Engine, Version=3.5.0.0,...”或它的摸一个依赖项。
    引用dll出现了黄色感叹号
    保持控件和容器之间的相对位置
    DataGridView中EnditCommit()调用之后,单元格的内容被全选了,每次输入都要鼠标点击定位到最后才能继续输入
    访问DataGridView的Rows报了OutOfIndexRangeException错误
  • 原文地址:https://www.cnblogs.com/zyx1314/p/5638596.html
Copyright © 2020-2023  润新知