--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
Visit this group at https://groups.google.com/group/eiffel-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/24b9cc57-4ed6-4516-8a04-20ee0c4abc3a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/CAFq%2Bd4599GcQh1-rot5ajME%3DLtO_Mxx7ubXuvES1WmnOmwJLsw%40mail.gmail.com.
Perhaps a third, simpler, and common (perhaps too common to mention) option:Create a cluster, not a library, and place the reusable class in it.Just add the shared cluster to your projects' ecf files.Good organization, and some "library-think" up front will help in the long run. You have the option to create a library at a later date, of course.R
--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
Visit this group at https://groups.google.com/group/eiffel-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/ef843da1-a590-4bd8-9f5b-3534ccbea7a5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I am sure I am forgetting a few points, but for me, it is really about better control of dependency and improving reusability without pain.I hope, now, you are less confused about cluster/libraries.
Yes, thank you for that nice explanation! I had a "dependency hell" experience this Sunday, as I started to manually import Eiffel Loop's EL_PLAIN_TEXT_FILE (in order to avoid the Python-required steps - because, well, let's just avoid non-Eiffel stuff if we can, right?)
SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])
import os, sys, ftplib, codecs
from distutils import dir_util
from distutils import file_util
from os import path
from subprocess import call
from optparse import OptionParser
from eiffel_loop.xml.xpath import XPATH_CONTEXT
from eiffel_loop.eiffel import project
from eiffel_loop.eiffel.ecf import EIFFEL_CONFIG_FILE, FINALIZED_BUILD
global g_project_dir, g_translations_xml_path, g_signer
class CODE_SIGNER (object):
# Initialization
def __init__ (self, cert_path, pfx_phrase):
self.cert_path = cert_path
self.pfx_phrase = pfx_phrase
self.time_stamp_url = 'http://timestamp.comodoca.com'
def sign (self, exe_path):
base_cmd = ['signtool', 'sign', '/f', self.cert_path, '/p', self.pfx_phrase]
call (base_cmd + self.middle_args () + ['/v', exe_path])
# Implementation
def middle_args (self):
pass
class SHA_256_SIGNER (CODE_SIGNER):
# Implementation
def middle_args (self):
result = ['/fd', 'sha256', '/tr', self.time_stamp_url + '/?td=sha256', '/td', 'sha256', '/as']
return result
class SHA_1_SIGNER (CODE_SIGNER):
# Implementation
def middle_args (self):
result = ['/t', self.time_stamp_url]
return result
def sha_sign (exe_path, dual_sign):
if path.exists (exe_path):
g_signer.get (256).sign (exe_path)
if dual_sign:
g_signer.get (1).sign (exe_path)
def write_ksign (file_list, dual_sign):
# Obsolete, use `sha_sign' instead
variables = {
'256_pfx_pass' : '',
'256_pfx_file' : '433A5C55736572735C66696E6E69616E5C446F63756D656E74735C4D79204368696E675C5369676E696E675C436F6D6F646F2E703132',
'256_Description' : '4D79204368696E67',
'256_DescriptionURL' : '687474703A2F2F6D796368696E672E736F667477617265',
'1_pfx_pass' : '',
'1_pfx_file' : '',
'1_Description' : '',
'1_DescriptionURL' : '',
'files_to_sign': '|'.join (file_list)
}
path_template = r'KSign\Hex11Software%s.ksign'
if dual_sign:
variables ['1_pfx_file'] = '433A5C55736572735C66696E6E69616E5C446F63756D656E74735C4D79204368696E675C5369676E696E675C436F6D6F646F2D736861312E706678'
variables ['1_Description'] = '4D79204368696E67'
variables ['1_DescriptionURL'] = '687474703A2F2F6D796368696E672E736F667477617265'
ksign_path = path_template % '-dual-sign'
else:
ksign_path = path_template % ''
f = open (ksign_path, 'w')
f.write ('[Settings]\n')
for key in sorted (variables.keys ()):
f.write ('%s=%s\n' % (key, variables [key]))
f.close ()
def build_version ():
f = open (path.join ('build', 'version.txt'), 'r')
result = f.read ().rstrip ()
f.close ()
return result
def convert_pyxis_to_xml (pyxis_path, xml_path=None):
xml_dir = path.dirname (xml_path)
if not path.exists (xml_dir):
dir_util.mkpath (xml_dir)
print 'curdir:', path.abspath (os.curdir)
cmd = ['el_toolkit', '-pyxis_to_xml', '-in', pyxis_path]
if xml_path:
cmd.extend (['-out', xml_path])
print cmd
call (cmd)
class LOCALE (object):
# Initialization
def __init__ (self, xml_path, write_encoding, lang = 'en'):
self.translations_ctx = XPATH_CONTEXT (xml_path)
self.write_encoding = write_encoding
self.lang = lang
def languages (self):
result = self.translations_ctx.node_list ("//translations/item[1]/translation/@lang")
return result
def translation (self, item_id):
result = self.translations_ctx.text (
"/translations/item[@id='%s']/translation[@lang='%s']" % (item_id, self.lang)
)
return result
def write_translation (self, item_id, file_path):
file_out = open (file_path, 'w')
file_out.write (self.translation (item_id).encode (self.write_encoding))
file_out.close ()
def set_lang (self, lang):
self.lang = lang
def create_installer (archive_zip, locale):
archive_exe = path.splitext (archive_zip)[0] + '.exe'
words = path.basename (archive_exe).split ('-')
words.insert (1, locale.lang)
locale_archive_exe = path.join (path.dirname (archive_zip), '-'.join (words))
for exe in [archive_exe, locale_archive_exe]:
if path.exists (exe):
os.remove (exe)
locale.write_translation ('{installer-dialog-box}', 'dialog-box.txt')
locale.write_translation ('{unzip-installation}', 'installation.txt')
if locale.lang == 'de':
language_option = '-lg'
else:
language_option = '-le'
make_installer_cmd = [
'wzipse32', archive_zip, '-Setup', '-le', '-auto', '-runasadmin', language_option,
# Message
'-myesno', "installation.txt",
# Icon
'-i', r"resources\desktop-icons\package.ico",
# Title
'-st', locale.translation ('{installer-title}'),
# Dialog message
'-t', "dialog-box.txt",
# Installation command
'-o', '-c', r"package\bin\myching.exe", '-install', '-silent'
]
print
print 'Creating self extracting exe "%s"' % locale_archive_exe
print make_installer_cmd
call (make_installer_cmd)
os.rename (archive_exe, locale_archive_exe)
# cleanup files
for file_path in ['dialog-box.txt', 'installation.txt']:
if path.exists (file_path):
os.remove (file_path)
return locale_archive_exe
def platform_name (bit_count):
ise_names = {32 : 'windows', 64 : 'win64'}
return ise_names [bit_count]
def architecture (bit_count):
names = {32 : 'x86', 64 : 'x64'}
result = names [bit_count]
return result
def scons_build (args=[]):
scons_py = path.join (os.path.dirname (os.path.realpath (sys.executable)), 'scons.py')
cmd = ['python', scons_py]
if args:
cmd.extend (args)
call (cmd)
def yes_no (is_true):
if is_true:
result = 'yes'
else:
result = 'no'
return result
def build_exe (bit_count, is_xp_compatible):
# Build package for architecture
scons_py = path.join (os.path.dirname (os.path.realpath (sys.executable)), 'scons.py')
cmd = ['python', scons_py, 'cpu=' + architecture (bit_count), 'action=finalize']
# Don't do an Eiffel compile if any of the following (we use the F_code tar to do a C compile)
src_root = "source\\application_root.%s"
compile_eiffel = not (bit_count == 32 or is_xp_compatible or os.environ ['ISE_C_COMPILER'] == 'msc_vc140')
if compile_eiffel:
# Excluded unwanted sub applications for release
os.rename (src_root % "e", src_root % "developer")
os.rename (src_root % "release", src_root % "e")
cmd.extend (['compile_eiffel=%s' % yes_no (compile_eiffel), 'project=myching.ecf'])
call (cmd)
if compile_eiffel:
os.rename (src_root % "e", src_root % "release")
os.rename (src_root % "developer", src_root % "e")
def build_C_library (lib):
print 'Building', lib
# 11 Dec 2016
# For some reason this will not work to build elimageutils.dll even though it builds from the command line
# and using the Sconscript from top level build.
scons_dir = os.sep.join (lib.split (os.sep) [0:-3])
print 'cd', scons_dir
os.chdir (scons_dir)
scons_build ()
os.chdir (g_project_dir)
def build_installers (download_path, bit_count, is_xp_compatible):
# build installer for each of locales
print 'is_xp_compatible:', is_xp_compatible
inserts = (bit_count, build_version ())
if is_xp_compatible:
zip_name = 'MyChing-win%d-xp-%s.zip' % inserts
else:
zip_name = 'MyChing-win%d-%s.zip' % inserts
archive_zip = path.join (download_path, zip_name)
locale = LOCALE (g_translations_xml_path, 'latin-1')
os.chdir (path.join ('build', platform_name (bit_count)))
# In directory build/win64
winzip_cmd = ['wzzip', '-a', '-rP', archive_zip, r'package\*']
call (winzip_cmd)
os.chdir (g_project_dir)
# In directory build
result = []
for lang in locale.languages ():
locale.set_lang (lang)
result.append (create_installer (archive_zip, locale))
# cleanup files
if path.exists (archive_zip):
os.remove (archive_zip)
return result
# SCRIPT START
# assign globals
g_project_dir = path.abspath (os.curdir)
# Word around for bug "LookupError: unknown encoding: cp65001"
codecs.register (lambda name: codecs.lookup ('utf-8') if name == 'cp65001' else None)
usage = "usage: python build [--x86] [--upload]"
parser = OptionParser(usage=usage)
parser.add_option (
"-x", "--x86", action="store_true", dest="build_x86", default=False, help="Create a 32 bit version"
)
parser.add_option (
"-a", "--all", action="store_true", dest="build_all", default=False, help="Create both a 32 bit and 64 bit version"
)
parser.add_option (
"-i", "--installer", action="store_true", dest="build_installer", default=False, help="Create an installer package"
)
parser.add_option (
"-e", "--exe", action="store_true", dest="build_exe", default=False, help="Build package directory with executable"
)
parser.add_option (
"-p", "--xp", action="store_true", dest="is_xp_compatible", default=False, help="Build XP compatible executable"
)
(options, args) = parser.parse_args()
if options.build_all:
architecture_bits = [64, 32]
elif options.build_x86:
architecture_bits = [32]
else:
architecture_bits = [64]
if options.build_exe or options.build_installer:
pfx_phrase = raw_input ("Comodo pass phrase: ")
cert_dir = path.expanduser (r'~\Documents\My Ching\Signing')
g_signer = {
1 : SHA_1_SIGNER (path.join (cert_dir, 'Comodo-sha1.pfx'), pfx_phrase),
256 : SHA_256_SIGNER (path.join (cert_dir, 'Comodo.p12'), pfx_phrase)
}
else:
g_signer = {}
if options.build_exe:
# Update project.py build_number for `source/build_info.e'
if 64 in architecture_bits and not options.is_xp_compatible:
project.increment_build_number ()
for bit_count in architecture_bits:
myching_exe_path = r'build\%s\package\bin\myching.exe' % platform_name (bit_count)
if options.is_xp_compatible and path.exists (myching_exe_path):
os.remove (myching_exe_path)
build_exe (bit_count, options.is_xp_compatible)
sha_sign (myching_exe_path, options.is_xp_compatible)
if options.build_installer:
g_translations_xml_path = r'workarea\Installer-translations.xml'
convert_pyxis_to_xml (r'localization\installer.pyx', g_translations_xml_path)
download_path = path.normpath (path.dirname (g_project_dir) + "/myching-server/www/download")
exe_list = []
for bit_count in architecture_bits:
installer_versions = build_installers (download_path, bit_count, options.is_xp_compatible)
for install_exe in installer_versions:
sha_sign (install_exe, options.is_xp_compatible)
os.remove (g_translations_xml_path)
s = raw_input ('Return to finish')
> This is a Python script to build a code signed install package for 8
> permutations of Windows platform, architecture and self-extracting exe
> localized language (English or German) The system ensures that you only
> have to do 1 Eiffel compile and then 4 C builds. I can't imagine
> writing this with a batch script
Would you imagine writing this in Eiffel (apart from the fact that
Eiffel is compiled and not interpreted)?
class
APPLICATION_ROOT
inherit
EL_MULTI_APPLICATION_ROOT [BUILD_INFO]
redefine
Select_first
end
create
make
feature {NONE} -- Implementation
Application_types: ARRAY [TYPE [EL_SUB_APPLICATION]]
--
once
Result := <<
-- Release apps
{MY_CHING_APP},
{INSTALLER_APP},
{UNINSTALL_APP},
-- Development apps
{ACTIVATOR_TEST_APP},
{AUTOTEST_DEVELOPMENT_APP},
{CREATE_SAMPLE_JOURNALS_APP},
{COMPILE_CHINESE_NAMES_APP},
{HELP_VIEWER_TEST_APP},
{MIGRATE_128_TO_256_APP},
-- Testing
{TEST_APP},
{UI_TEST_APP},
{REGRESSION_TEST_APP},
{HTML_FORECAST_APP},
{VERIFY_ONLINE_RESOURCES_APP}
>>
end
feature {NONE} -- Constants
Select_first: BOOLEAN = True
end
> This is a Python script to build a code signed install package for 8
> permutations of Windows platform, architecture and self-extracting exe
> localized language (English or German) The system ensures that you only
> have to do 1 Eiffel compile and then 4 C builds. I can't imagine
> writing this with a batch script
Would you imagine writing this in Eiffel (apart from the fact that
Eiffel is compiled and not interpreted)?
For anyone who is reluctant to learn how to use Python or Scons, I think this is a pity, because for very little effort it will pay handsome dividends.
The TIOBE index doesn't mean much IMHO (it does for jobs).
I don't really care. As I said, I'm not a professional programmer,
Understood, but in any case it's not necessary to know how to program in Python in order to use Eiffel-Loop. It's just something there in the background as a facilitator, the same as the C compiler.
-------- Original Message --------
Subject: [eiffel-users] Re: Newbie question on code reuse - using a
previous project
--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/c6aa483b-0bc9-4f29-8d11-c6797c921f2e%40googlegroups.com.
At the moment I do this by creating a new project and umpteen classes and have to copy and paste the contents of each from the original. It is a considerable pain, and there ought to be an easier way.
I'd also like to produce installable packages...have you tried e.g. CMake (its
syntax is not, I agree, very pretty.)? :-)
Sincerely,
Saša