Skip to content
Snippets Groups Projects
Commit 50bbcde1 authored by David Hendriks's avatar David Hendriks
Browse files

made most code to compile the shared library for binaryc

parent c230691f
No related branches found
No related tags found
No related merge requests found
File added
#pragma push_macro("MAX")
#pragma push_macro("MIN")
#undef MAX
#undef MIN
#include "binary_c.h"
void custom_output_function(struct stardata_t * stardata);
void custom_output_function(struct stardata_t * stardata)
{
// struct stardata_t * stardata = (struct stardata_t *)x;
PRINTF("MY_STELLAR_DATA %g %g
",((double)stardata->model.time),((double)stardata->star[0].mass));
PRINTF("my_sss2 %g %g
",((double)stardata->model.time),((double)stardata->star[1].mass));;
}
#undef MAX
#undef MIN
#pragma pop_macro("MIN")
#pragma pop_macro("MAX")
\ No newline at end of file
import os
import textwrap
import subprocess
import socket
# Functions for the automatic logging of stuff
def autogen_C_logging_code(logging_dict):
# See example_perl.pm autologging
"""
Function that autogenerates PRINTF statements for binaryc
Input:
dictionary where the key is the header of that logging line and items which are lists of parameters that will be put in that logging line
example: {'MY_STELLAR_DATA':
[
'model.time',
'star[0].mass',
'model.probability',
'model.dt'
']}
"""
# Check if the input is of the correct form
if not type(logging_dict)==dict:
print("Error: please use a dictionary as input")
return None
code = ''
# Loop over dict keys
for key in logging_dict:
logging_dict_entry = logging_dict[key]
# Check if item is of correct type:
if type(logging_dict_entry)==list:
# Construct print statement
code += 'PRINTF("{}'.format(key)
code += ' {}'.format('%g '*len(logging_dict_entry))
code = code.strip()
code += '\n"'
# Add format keys
for param in logging_dict_entry:
code += ',((double)stardata->{})'.format(param)
code += ');\n'
else:
print('Error: please use a list for the list of parameters that you want to have logged')
code = code.strip()
# print("MADE AUTO CODE\n\n{}\n\n{}\n\n{}\n".format('*'*60, repr(code), '*'*60))
return code
####################################################################################
def binary_c_log_code(code):
"""
Function to construct the code to construct the custom logging function
# see example_perl.pm binary_c_log_code in perl
"""
custom_logging_function_string = """\
#pragma push_macro(\"MAX\")
#pragma push_macro(\"MIN\")
#undef MAX
#undef MIN
#include \"binary_c.h\"
void custom_output_function(struct stardata_t * stardata);
void custom_output_function(struct stardata_t * stardata)
{{
// struct stardata_t * stardata = (struct stardata_t *)x;
{};
}}
#undef MAX
#undef MIN
#pragma pop_macro(\"MIN\")
#pragma pop_macro(\"MAX\")\
""".format(code)
# print(repr(textwrap.dedent(custom_logging_function_string)))
return textwrap.dedent(custom_logging_function_string)
def binary_c_write_log_code(code, filename):
"""
Function to write the generated logging code to a file
"""
cwd = os.getcwd()
filePath = os.path.join(cwd, filename)
if os.path.exists(filePath):
try:
os.remove(filePath)
except:
print("Error while deleting file {}".format(filePath))
with open(filePath, 'w') as f:
f.write(code)
def from_binary_c_config(config_file, flag):
"""
Function to run the binaryc_config command with flags
"""
res = subprocess.check_output('{config_file} {flag}'.format(config_file=config_file, flag=flag),
shell=True, stderr=subprocess.STDOUT)
# convert and chop off newline
res = res.decode('utf').rstrip()
return res
def return_compilation_dict():
"""
Function to build the compile command for the shared library
inspired by binary_c_inline_config command in perl
TODO: this function still has some cleaning up to do wrt default values for the compile command
returns:
- string containing the command to build the shared library
"""
# use binary_c-config to get necessary flags
BINARY_C_DIR = os.getenv('BINARY_C')
if BINARY_C_DIR:
BINARY_C_CONFIG = os.path.join(BINARY_C_DIR, 'binary_c-config')
BINARY_C_SRC_DIR = os.path.join(BINARY_C_DIR, 'src')
# TODO: build in check to see whether the file exists
else:
raise NameError('Envvar BINARY_C doesnt exist')
return None
# TODO: make more options for the compiling
cc = from_binary_c_config(BINARY_C_CONFIG, 'cc')
# Check for binary_c
BINARY_C_EXE = os.path.join(BINARY_C_DIR, 'binary_c')
if not os.path.isfile(BINARY_C_EXE):
print("We require binary_c executable; have you built binary_c?")
raise NameError('BINARY_C executable doesnt exist')
# TODO: debug
binclibs = from_binary_c_config(BINARY_C_CONFIG, 'libs')
libdirs = "{} -L{}".format(from_binary_c_config(BINARY_C_CONFIG, 'libdirs'), BINARY_C_SRC_DIR)
bincflags = from_binary_c_config(BINARY_C_CONFIG, 'cflags')
bincincdirs = from_binary_c_config(BINARY_C_CONFIG, 'incdirs')
# combine
binclibs = ' {} {}'.format(libdirs, binclibs)
# setup defaults:
defaults = {
'cc': 'gcc', # default compiler
'ccflags': bincflags,
'ld': 'ld', # 'ld': $Config{ld}, # default linker
'debug': 0,
'inc': '{} -I{}'.format(bincincdirs, BINARY_C_SRC_DIR),
# inc => ' '.($Config{inc}//' ').' '.$bincincdirs." -I$srcdir ", # include the defaults plus # GSL and binary_c
# 'libname': libname, # libname is usually just binary_c corresponding to libbinary_c.so
'libs': binclibs,
}
# set values with defaults. TODO: make other input possile.
ld = defaults['ld']
debug = defaults['debug']
inc = defaults['inc'] # = ($ENV{BINARY_GRID2_INC} // $defaults{inc}).' '.($ENV{BINARY_GRID2_EXTRAINC} // '');
libs = defaults['libs'] # = ($ENV{BINARY_GRID2_LIBS} // $defaults{libs}).' '.($ENV{BINARY_GRID2_EXTRALIBS}//'');
ccflags = defaults['ccflags'] # = $ENV{BINARY_GRID2_CCFLAGS} // ($defaults{ccflags}) . ($ENV{BINARY_GRID2_EXTRACCFLAGS} // '');
# you must define _SEARCH_H to prevent it being loaded twice
ccflags += ' -D_SEARCH_H'
# ensure library paths to the front of the libs:
libs_content = libs.split(' ')
library_paths = [el for el in libs_content if el.startswith('-L')]
non_library_paths = [el for el in libs_content if (not el.startswith('-L') and not el=='')]
libs = "{} {}".format(' '.join(library_paths), ' '.join(non_library_paths))
print("Building shared library for custom logging with (binary_c.h) at {} on {}\n".format(BINARY_C_SRC_DIR, socket.gethostname()))
print("With options:\n\tcc = {cc}\n\tccflags = {ccflags}\n\tld = {ld}\n\tlibs = {libs}\n\tinc = {inc}\n\n".format(
cc=cc, ccflags=ccflags, ld=ld, libs=libs, inc=inc)
)
return {
'cc': cc,
'ld': ld,
'ccflags': ccflags,
'libs': libs,
'inc': inc
}
# compilation_dict = return_compilation_dict('libcustomlogging')
def compile_shared_lib(code, sourcefile_name, outfile_name):
"""
Function to write the custom logging code to a file and then compile it.
"""
# Write code to file
binary_c_write_log_code(code, sourcefile_name)
# create compilation command
compilation_dict = return_compilation_dict()
command = "{cc} {ccflags} {libs} -o {outfile_name} {sourcefile_name} {inc}".format(
cc=compilation_dict['cc'],
ccflags=compilation_dict['ccflags'],
libs=compilation_dict['libs'],
outfile_name=outfile_name,
sourcefile_name=sourcefile_name,
inc=compilation_dict['inc'])
# remove extra whitespaces:
command = ' '.join(command.split())
# Execute compilation
res = subprocess.check_output('{command}'.format(command=command),
shell=True, stderr=subprocess.STDOUT)
print(res)
# return command
# generate logging lines
logging_line = autogen_C_logging_code(
{
'MY_STELLAR_DATA': ['model.time', 'star[0].mass'],
'my_sss2': ['model.time', 'star[1].mass']
}
)
# Generate code around logging lines
created_code = binary_c_log_code(logging_line)
compile_shared_lib(created_code, sourcefile_name='custom_logging.c', outfile_name='lib_custom_logging.so')
\ No newline at end of file
from functions import autogen_C_logging_code, binary_c_log_code, binary_c_write_log_code
import textwrap
# generate logging lines
logging_line = autogen_C_logging_code(
{
'MY_STELLAR_DATA': ['model.time', 'star[0].mass'],
'my_sss2': ['model.time', 'star[1].mass']
}
)
# Generate code around logging lines
created_code = binary_c_log_code(logging_line)
binary_c_write_log_code(created_code)
# function for binaryc to work
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment