VB6 [IDE](https://ja.wikipedia.org/wiki/%E7%B5%B1%E5%90%88%E9%96%8B%E7%99%BA%E7%92%B0%E5 % A2% 83) ne se comporte pas comme make. En d'autres termes, même s'il n'y a pas de changement dans la série de code source, un nouveau fichier binaire sera généré lorsque vous exécutez la compilation. C'est bien, mais chaque fois que vous compilez, un fichier binaire différent est généré. Autrement dit, il est impossible de distinguer si les deux fichiers binaires sont fonctionnellement identiques ou ont été modifiés. C'est le premier problème.
Une autre configuration courante
\---Proj
+---Common
| CommonModule.bas
|
+---PreExe
| PreExe.vbp ←CommonModule.référencement bas
|
+---MainExe
| MainExe.vbp ←CommonModule.référencement bas
|
\---PostExe
PostExe.vbp ←CommonModule.bas non référencé
Il est courant de partager le code source au niveau du fichier physique comme celui-ci. Supposons maintenant que vous modifiez une méthode dans CommonModule.bas dans le dossier Common. Lequel doit être compilé parce que je l'ai changé? Lequel n'est pas nécessaire? Il est normal de tout compiler, mais si vous le compilez sans que vous en ayez besoin, un binaire différent sera généré même s'il n'y a pas de changements fonctionnels comme le premier problème.
Bien sûr, je pense que cela peut être réalisé en utilisant la commande make originale, mais j'écrirai ici un programme qui effectue un comportement de type make-like spécifique à vb dans Python 3 (make existe depuis plus de 40 ans, alors pourquoi ne pas le mettre dans l'environnement de développement VB6? Était-ce ...)
Reportez-vous au fichier de projet VB (.vbp) et exécutez la compilation si l'une des conditions suivantes est remplie.
Classe qui gère les fichiers de projet (.vbp)
projectfile.py
import child
import os
class ProjectFile:
__lines = []
__exe_name32 = ""
__children = []
def get_exe_name32(self):
line = [i for i in self.__lines if i.startswith("ExeName32=")]
if len(line) != 0:
(_, value) = line[0].split('=')
self.exe_name32 = value.replace('\"', '').replace('\n', '')
def get_children(self):
keys = ["Clas", "Form", "Modu"]
servived_lines = [i for i in self.__lines if i[0:4] in keys]
for line in servived_lines:
c = child.Child(line, os.path.dirname(self.fullpath))
self.__children.append(c)
@property
def exe_name32(self):
return self.__exe_name32
@exe_name32.setter
def exe_name32(self, value):
self.__exe_name32 = value
@property
def children(self):
return self.__children
def __init__(self, fullpath):
self.fullpath = fullpath
with open(fullpath, mode='r') as f:
self.__lines = f.readlines()
self.get_exe_name32()
self.get_children()
Classe qui gère les fichiers source (.bas, .cls, .frm) décrits dans le fichier projet
child.py
import os
import datetime
class Child:
__full_path = ""
__last_write_time = ""
@property
def full_path(self):
return self.__full_path
@property
def last_write_time(self):
return self.__last_write_time
def __init__(self, line, basepath):
(_, value) = line.split('=')
if (';' in value):
(_, item) = value.split(';')
filename = item.strip()
else:
filename = value.strip()
self.__full_path = os.path.join(basepath, filename)
self.__last_write_time = os.path.getmtime(self.__full_path)
Corps
vbmake.py
import projectfile
import sys
import os
import datetime
import subprocess
if __name__ == "__main__":
if (len(sys.argv) != 2):
print("vbmake.py vbpfullpath")
x = input()
exit
vbp_full_path = sys.argv[1]
vbp = projectfile.ProjectFile(vbp_full_path)
exe_full_path = os.path.join(os.path.dirname(vbp_full_path), vbp.exe_name32)
if os.path.exists(exe_full_path):
standard_time_stamp = os.path.getmtime(exe_full_path)
print(f"TimeStamp={datetime.datetime.fromtimestamp(standard_time_stamp)}")
exe_not_found = False
is_new_vbp = os.path.getmtime(vbp_full_path) > standard_time_stamp
are_new_sources = any([i.last_write_time > standard_time_stamp for i in vbp.children])
else:
exe_not_found = True
# 1)Le fichier d'exécution n'existe pas
# 2)Le fichier VBP est plus récent que le fichier exécutable
# 3)Il existe un fichier source plus récent que le fichier exécutable
if exe_not_found or is_new_vbp or are_new_sources:
compiler1 = "C:\\Program Files\\Microsoft Visual Studio\\VB98\\VB6.EXE"
compiler2 = "C:\\Program Files (x86)\\Microsoft Visual Studio\\VB98\\VB6.EXE"
option = "/make"
if os.path.exists(compiler1):
compiler = compiler1
else:
compiler = compiler2
print(f"{compiler} {option} {vbp_full_path}")
subprocess.run([compiler, option, vbp_full_path])
else:
print("Aucune compilation requise")
Il existe deux chemins complets pour le compilateur car la destination d'installation de VB6 est différente selon le système d'exploitation et x86 / X64. Il semble que le compilateur1 était W10 (x64) et le compilateur2 était W7 (x64).
Toujours utiliser des fichiers batch
make.bat
py vbmake.py %1
Je fais quelque chose comme ça, mais j'ai découvert ce qu'on appelle pyinstaller, donc je vais en faire un exe. Great est capable de fonctionner même dans un environnement sans Python.
>pip install pyinstaller
fais le
>pyinstaller vbmake.py
c'est tout. Effectivement, vbmake.exe sur 10 Mo a été généré (c'est vrai)
Recommended Posts