check if gcc requires memcpy or memset and add them to crt-less builds
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@4007 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
84c1ce2084
commit
db43f63346
1 changed files with 111 additions and 1 deletions
112
SCons/Config/gnu
112
SCons/Config/gnu
|
@ -94,6 +94,116 @@ util_env.Append(LINKFLAGS = '-s') # strip
|
|||
util_env.Append(LINKFLAGS = '-mwindows') # build windows executables
|
||||
util_env.Append(LINKFLAGS = '$ALIGN_FLAG') # 512 bytes align
|
||||
|
||||
# return
|
||||
|
||||
### weird GCC requirements
|
||||
|
||||
#
|
||||
# GCC requires some functions from the CRT to be present, if certain
|
||||
# operations are done. For example, if a small string is assigned to
|
||||
# a larger buffer, GCC 3.4+ uses memset to fill the remaining of the
|
||||
# buffer with zeros.
|
||||
#
|
||||
|
||||
funcs_file = None
|
||||
funcs_obj = None
|
||||
|
||||
def check_requirement(ctx, func, trigger):
|
||||
ctx.Message('Checking for %s requirement... ' % func)
|
||||
|
||||
ctx.env.Append(LINKFLAGS = '$NODEFLIBS_FLAG')
|
||||
ctx.env.Append(LINKFLAGS = '-Wl,-e,___main')
|
||||
|
||||
test = """
|
||||
int __main() {
|
||||
%s
|
||||
return 0;
|
||||
}
|
||||
""" % trigger
|
||||
|
||||
ret = not ctx.TryLink(test, '.c')
|
||||
ctx.Result(ret)
|
||||
|
||||
return ret
|
||||
|
||||
def replace_emitter(env, builder_name):
|
||||
builder = env['BUILDERS'][builder_name]
|
||||
|
||||
def new_emitter(target, source, env):
|
||||
global funcs_file, funcs_obj
|
||||
res = builder.emitter(target, source, env)
|
||||
if not funcs_obj:
|
||||
funcs_obj = env.SharedObject(funcs_file)
|
||||
res[1].append(funcs_obj)
|
||||
return res
|
||||
|
||||
env['BUILDERS'][builder_name] = Builder(
|
||||
action = builder.action,
|
||||
prefix = builder.prefix,
|
||||
suffix = builder.suffix,
|
||||
src_suffix = builder.src_suffix,
|
||||
target_scanner = builder.target_scanner,
|
||||
source_scanner = builder.source_scanner,
|
||||
target_factory = builder.target_factory,
|
||||
source_factory = builder.source_factory,
|
||||
emitter = new_emitter, # only thing being replaced
|
||||
src_builder = builder.src_builder,
|
||||
single_source = builder.single_source
|
||||
)
|
||||
|
||||
def add_func(func):
|
||||
global funcs_file
|
||||
|
||||
if not funcs_file:
|
||||
import os
|
||||
funcs_file = File('#.sconf_temp/funcs.c')
|
||||
try:
|
||||
os.unlink(funcs_file.abspath)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
f = file(funcs_file.abspath, 'a')
|
||||
f.write(func)
|
||||
f.write('\n')
|
||||
f.close()
|
||||
|
||||
conf = defenv.Configure(custom_tests = { 'CheckRequirement' : check_requirement })
|
||||
|
||||
if conf.CheckRequirement('memcpy', 'struct s { char c[128]; } t = { "test" };'):
|
||||
add_func("""
|
||||
#include <stdlib.h> // for size_t
|
||||
void *memcpy(void *out, const void *in, size_t len)
|
||||
{
|
||||
char *c_out=(char*)out;
|
||||
char *c_in=(char *)in;
|
||||
while (len-- > 0)
|
||||
{
|
||||
*c_out++=*c_in++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
""")
|
||||
|
||||
if conf.CheckRequirement('memset', 'char c[128] = "test";'):
|
||||
add_func("""
|
||||
#include <stdlib.h> // for size_t
|
||||
void *memset(void *mem, int c, size_t len)
|
||||
{
|
||||
char *p=(char*)mem;
|
||||
while (len-- > 0)
|
||||
{
|
||||
*p++=c;
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
""")
|
||||
|
||||
if funcs_file:
|
||||
replace_emitter(stub_env, 'Program')
|
||||
replace_emitter(plugin_env, 'SharedLibrary')
|
||||
replace_emitter(util_env, 'Program')
|
||||
|
||||
conf.Finish()
|
||||
|
||||
### return
|
||||
|
||||
Return('stub_env makensis_env plugin_env util_env')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue