34 '''Installs GEDLIB and its dependencies.''' 36 from subprocess
import call
42 def append_ged_env_hpp(identifier, node_id_type, node_label_type, edge_label_type):
44 append = append +
"\n";
45 append = append +
"#ifdef " + identifier.upper() +
"_GEDLIB_SHARED\n" 46 append = append +
"#ifndef SRC_ENV_GED_ENV_" + identifier.upper() +
"_CPP_\n" 47 append = append +
"extern template class GEDEnv<" + node_id_type +
", " + node_label_type +
", " + edge_label_type +
">;\n" 48 append = append +
"#endif /* SRC_ENV_GED_ENV_" + identifier.upper() +
"_CPP_ */\n" 49 append = append +
"#endif /*" + identifier.upper() +
"_GEDLIB_SHARED */\n" 51 temp = open(
"temp",
"wb")
52 with open(
"src/env/ged_env.hpp",
"r") as f: for line
in f:
53 if line.startswith(
"#ifdef ")
and not line.startswith(
"#ifdef GXL_GEDLIB_SHARED"):
55 if line.startswith(
"#endif /* GXL_GEDLIB_SHARED */"):
59 delete_line = delete_line - 1
61 shutil.move(
"temp",
"src/env/ged_env.hpp")
63 def append_cmake_lists(identifier):
65 append = append +
"\n" 66 append = append +
"add_library(" + identifier.lower() +
"gedlib SHARED env/ged_env." + identifier.lower() +
".cpp)\n" 67 append = append +
"set_target_properties(" + identifier.lower() +
"gedlib PROPERTIES SUFFIX \".so\")\n" 68 append = append +
"target_link_libraries(" + identifier.lower() +
"gedlib nomad doublefann svm)\n" 69 append = append +
"if(APPLE)\n" 70 append = append +
" add_custom_command(TARGET " + identifier.lower() +
"gedlib POST_BUILD COMMAND install_name_tool -change libnomad.so ${NOMAD_HOME}/lib/libnomad.so ${LIBRARY_OUTPUT_PATH}/lib" + identifier.lower() +
"gedlib.so)\n" 71 append = append +
" add_custom_command(TARGET " + identifier.lower() +
"gedlib POST_BUILD COMMAND install_name_tool -change libdoublefann.2.dylib ${FANN_HOME}/lib/libdoublefann.2.dylib ${LIBRARY_OUTPUT_PATH}/lib" + identifier.lower() +
"gedlib.so)\n" 72 append = append +
"add_custom_command(TARGET " + identifier.lower() +
"gedlib POST_BUILD COMMAND install_name_tool -change libsvm.so ${LIBSVM_HOME}/libsvm.so ${LIBRARY_OUTPUT_PATH}/lib" + identifier.lower() +
"gedlib.so)\n" 73 append = append +
"endif()\n" 75 temp = open(
"temp",
"wb")
76 with open(
"src/CMakeLists.txt",
"r") as f: 78 if line.startswith(
"add_library(")
and not line.startswith(
"add_library(gxlgedlib"):
80 if line.startswith(
"endif()"):
84 delete_line = delete_line - 1
86 shutil.move(
"temp",
"src/CMakeLists.txt")
88 def create_template_instantiation(identifier, node_id_type, node_label_type, edge_label_type):
89 with open(
"src/env/ged_env." + identifier.lower() +
".cpp",
"w")
as f:
91 f.write(
" * @file ged_env." + identifier.lower() +
".cpp\n")
92 f.write(
" * @brief ged::GEDEnv<" + node_id_type +
", " + node_label_type +
", " + edge_label_type +
"> template instantiation.\n")
95 f.write(
"#ifndef SRC_ENV_GED_ENV_" + identifier.upper() +
"_CPP_\n")
96 f.write(
"#define SRC_ENV_GED_ENV_" + identifier.upper() +
"_CPP_\n")
98 f.write(
"#include \"ged_env.hpp\"\n")
100 f.write(
"namespace ged {\n")
102 f.write(
"template class GEDEnv<" + node_id_type +
", " + node_label_type +
", " + edge_label_type +
">;\n")
106 f.write(
"#endif /* SRC_ENV_GED_ENV_" + identifier.upper() +
"_CPP_ */\n")
108 def parse_custom_types(custom_types):
109 if len(custom_types.split(
",")) != 4:
110 raise Exception(
"Invalid argument \"" + args.lib +
"\" for option lib. Usage: python install.py [--lib gxl|<indentifier-different-from-'gxl'>,<node-ID-type>,<node-label-type>,<edge-label-type>] [...]")
111 return custom_types.split(
",")
113 def create_directories():
114 print(
"\n***** Create directories for shared libraries, executables and output. *****")
115 commands =
"mkdir -p lib; mkdir -p tests/tkde2019/bin; mkdir -p tests/tkde2019/output; mkdir -p tests/vldbj2019/bin; mkdir -p tests/vldbj2019/ini; mkdir -p tests/vldbj2019/results; median/bin; mkdir -p median/output; mkdir -p tests/sspr2018/bin; mkdir -p tests/sspr2018/output; mkdir -p tests/unit_tests/bin; mkdir -p tests/unit_tests/output" 116 call(commands, shell=
True)
118 def build_external_libraries():
119 if os.path.isfile(
"ext/.INSTALLED"):
120 print(
"\n***** External libraries already installed. *****")
122 print(
"\n***** Install external libraries. *****")
123 commands =
"cd ext/fann.2.2.0; mkdir -p build; cd build; rm -rf *; cmake -DCMAKE_INSTALL_PREFIX=.. ..; make install; cd ..; rm -rf build" 124 call(commands, shell=
True)
125 commands =
"cd ext/nomad.3.8.1; mkdir -p lib; mkdir -p bin; cd src; make clean; make all; make clean; rm -rf ../bin" 126 call(commands, shell=
True)
127 commands =
"cd ext/libsvm.3.22; make lib; rm -f svm.o" 128 call(commands, shell=
True)
129 f = open(
"ext/.INSTALLED",
"w")
132 def determine_gurobi_version(gurobi_root):
133 if not os.path.isdir(gurobi_root):
134 raise Exception(
"Invalid argument \"" + gurobi_root +
"\" for option gurobi: not a directory. Usage: python install.py [--gurobi <path-to-root-directory-of-Gurobi>] [...]")
135 gurobi_shared_lib = glob.glob(gurobi_root +
"*/lib/libgurobi*.so")[0]
136 return gurobi_shared_lib[len(gurobi_shared_lib)-5:len(gurobi_shared_lib)-3]
139 def build_gedlib(args):
140 if not os.path.isdir(args.boost):
141 raise Exception(
"Invalid argument \"" + args.boost +
"\" for option boost: not a directory. Usage: python install.py [--boost <path-to-directory-containing-Boost-sources>] [...]")
143 if args.lib
and args.lib !=
"gxl":
144 identifier, node_id_type, node_label_type, edge_label_type = parse_custom_types(args.lib)
145 if identifier.lower() ==
"gxl":
146 raise Exception(
"Invalid argument \"" + args.lib +
"\" for option lib. Usage: python install.py [--lib gxl|<indentifier-different-from-'gxl'>,<node-ID-type>,<node-label-type>,<edge-label-type>] [...]")
147 print(
"\n***** Modify sources for building user-defined shared library. *****")
148 create_template_instantiation(identifier, node_id_type, node_label_type, edge_label_type)
149 append_ged_env_hpp(identifier, node_id_type, node_label_type, edge_label_type)
150 append_cmake_lists(identifier)
153 print(
"\n***** Clean build directory. *****")
154 commands =
"rm -rf build" 155 call(commands, shell=
True)
157 print(
"\n***** Goto build directory. *****")
158 commands =
"mkdir -p build" 159 call(commands, shell=
True)
161 if (
not os.path.isfile(
"build/Makefile")):
162 print(
"\n***** Run CMake. *****")
163 commands =
"cd build; rm -rf *; cmake .. -DBOOST_ROOT=" + args.boost +
" -DCMAKE_BUILD_TYPE=" 165 commands = commands +
"Debug" 167 commands = commands +
"Release" 169 commands = commands +
" -DGUROBI_ROOT=" + args.gurobi +
" -DGUROBI_VERSION=" + determine_gurobi_version(args.gurobi)
170 call(commands, shell=
True)
173 print(
"\n***** Generate documentation. *****")
174 commands =
"cd build; make doc" 175 call(commands, shell=
True)
178 print(
"\n***** Build shared library. *****")
179 commands =
"cd build; make " + identifier.lower() +
"gedlib" 180 call(commands, shell=
True)
183 print(
"\n***** Build test executables. *****")
184 if args.tests ==
"all":
185 commands =
"cd build; make tests" 186 call(commands, shell=
True)
188 commands =
"cd build; make " + args.tests
189 call(commands, shell=
True)
192 print(
"\n***** Build executable for median graph computation on LETTER graphs. *****")
193 commands =
"cd build; make median_letter" 194 call(commands, shell=
True)
197 print(
"**************************************************")
198 print(
" GEDLIB 1.0 ")
199 print(
" Installation Script ")
200 print(
"**************************************************")
202 parser = argparse.ArgumentParser(description=
"Installs GEDLIB and its dependencies unless they have already been installed.", epilog=
"If called without arguments, only the dependencies are installed.")
203 parser.add_argument(
"--doc", help=
"build documentation; requires --boost <BOOST_ROOT>", action=
"store_true")
204 parser.add_argument(
"--lib", help=
"build shared library; requires --boost <BOOST_ROOT>", metavar=
"gxl|<indentifier>,<UserNodeID>,<UserNodeLabel>,<UserEdgeLabel>")
205 parser.add_argument(
"--tests", help=
"build test executables; requires --boost <BOOST_ROOT>", metavar=
"all|unit_tests|ged_env_tests|lsap_solver_tests|pr2018|sspr2018|vldbj2019|vldbj_train_ml|vldbj_test_lsape_based_methods|vldbj_test_lp_based_methods|vldbj_test_ls_based_methods|vldbj_test_misc_methods", choices=[
"all",
"unit_tests",
"ged_env_tests",
"lsap_solver_tests",
"pr2018",
"sspr2018",
"vldbj2019",
"vldbj_train_ml",
"vldbj_test_lsape_based_methods",
"vldbj_test_lp_based_methods",
"vldbj_test_ls_based_methods",
"vldbj_test_misc_methods"])
206 parser.add_argument(
"--median", help=
"build binary for median graph computation on letter graphs", action=
"store_true")
207 parser.add_argument(
"--boost", metavar=
"<BOOST_ROOT>", help=
"specify path to directory containing Boost sources")
208 parser.add_argument(
"--gurobi", metavar=
"<GUROBI_ROOT>", help=
"specify path to directory containing Gurobi")
209 parser.add_argument(
"--debug", help=
"build in debug mode", action=
"store_true")
210 parser.add_argument(
"--clean", help=
"clean build directory and update makefile before build", action=
"store_true")
211 args = parser.parse_args()
212 if not args.boost
and (args.lib
or args.tests
or args.doc):
213 raise Exception(
"The argument --boost BOOST is required if the script is called with one of the options --lib, --tests or --doc.")
214 build_external_libraries()
216 if args.lib
or args.tests
or args.doc
or args.median:
218 print(
"\n***** Successfully installed GEDLIB. *****")