diff options
Diffstat (limited to 'indra/cmake')
-rw-r--r-- | indra/cmake/DeploySharedLibs.cmake | 67 | ||||
-rw-r--r-- | indra/cmake/LLSharedLibs.cmake | 31 | ||||
-rw-r--r-- | indra/cmake/run_build_test.py | 222 |
3 files changed, 209 insertions, 111 deletions
diff --git a/indra/cmake/DeploySharedLibs.cmake b/indra/cmake/DeploySharedLibs.cmake new file mode 100644 index 0000000000..a7e772bd75 --- /dev/null +++ b/indra/cmake/DeploySharedLibs.cmake @@ -0,0 +1,67 @@ +# DeploySharedLibs.cmake +# This is a script to be run at build time! Its not part of the cmake configuration! +# See indra/cmake/LLSharedLibs.cmake for a macro that simplifies adding a command to a target to run this script. + +# This script requires a few cmake variable to be set on the command line: +# BIN_NAME= The full path the the binary to search for dependecies. +# SEARCH_DIRS= The full paths to dirs to search for dependencies. +# DST_PATH= The full path where the dependecies will be copied. +include(GetPrerequisites) +message("Getting recursive dependencies for file: ${BIN_NAME}") +set(EXCLUDE_SYSTEM 1) +set(RECURSE 1) +get_filename_component(EXE_PATH ${BIN_NAME} PATH) + +get_prerequisites( ${BIN_NAME} RESULTS ${EXCLUDE_SYSTEM} ${RECURSE} "${EXE_PATH}" "${SEARCH_DIRS}" ) + +foreach(DEP ${RESULTS}) + Message("Processing dependency: ${DEP}") + get_filename_component(DEP_FILE ${DEP} NAME) + set(DEP_FILES ${DEP_FILES} ${DEP_FILE}) +endforeach(DEP) + +if(DEP_FILES) + list(REMOVE_DUPLICATES DEP_FILES) +endif(DEP_FILES) + +foreach(DEP_FILE ${DEP_FILES}) + if(FOUND_FILES) + list(FIND FOUND_FILES ${DEP_FILE} FOUND) + else(FOUND_FILES) + set(FOUND -1) + endif(FOUND_FILES) + + if(FOUND EQUAL -1) + find_path(DEP_PATH ${DEP_FILE} PATHS ${SEARCH_DIRS} NO_DEFAULT_PATH) + if(DEP_PATH) + set(FOUND_FILES ${FOUND_FILES} "${DEP_PATH}/${DEP_FILE}") + set(DEP_PATH NOTFOUND) #reset DEP_PATH for the next find_path call. + else(DEP_PATH) + set(MISSING_FILES ${MISSING_FILES} ${DEP_FILE}) + endif(DEP_PATH) + endif(FOUND EQUAL -1) +endforeach(DEP_FILE) + +if(MISSING_FILES) + message("Missing:") + foreach(FILE ${MISSING_FILES}) + message(" ${FILE}") + endforeach(FILE) + message("Searched in:") + foreach(SEARCH_DIR ${SEARCH_DIRS}) + message(" ${SEARCH_DIR}") + endforeach(SEARCH_DIR) + message(FATAL_ERROR "Failed") +endif(MISSING_FILES) + +if(FOUND_FILES) + foreach(FILE ${FOUND_FILES}) + get_filename_component(DST_FILE ${FILE} NAME) + set(DST_FILE "${DST_PATH}/${DST_FILE}") + message("Copying ${FILE} to ${DST_FILE}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE} ${DST_FILE} + ) + endforeach(FILE ${FOUND_FILES}) +endif(FOUND_FILES) +message("Success!") diff --git a/indra/cmake/LLSharedLibs.cmake b/indra/cmake/LLSharedLibs.cmake new file mode 100644 index 0000000000..a8c81609bb --- /dev/null +++ b/indra/cmake/LLSharedLibs.cmake @@ -0,0 +1,31 @@ +# ll_deploy_sharedlibs_command +# target_exe: the cmake target of the executable for which the shared libs will be deployed. +# search_dirs: a list of dirs to search for the dependencies +# dst_path: path to copy deps to, relative to the output location of the target_exe +macro(ll_deploy_sharedlibs_command target_exe search_dirs dst_path) + get_target_property(OUTPUT_LOCATION ${target_exe} LOCATION) + + if(DARWIN) + get_target_property(IS_BUNDLE ${target_exe} MACOSX_BUNDLE) + if(IS_BUNDLE) + get_filename_component(TARGET_FILE ${OUTPUT_LOCATION} NAME) + set(OUTPUT_PATH ${OUTPUT_LOCATION}.app/Contents/MacOS) + set(OUTPUT_LOCATION ${OUTPUT_PATH}/${TARGET_FILE}) + endif(IS_BUNDLE) + else(DARWIN) + message(FATAL_ERROR "Only darwin currently supported!") + endif(DARWIN) + + add_custom_command( + TARGET ${target_exe} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + "-DBIN_NAME=\"${OUTPUT_LOCATION}\"" + "-DSEARCH_DIRS=\"${search_dirs}\"" + "-DDST_PATH=\"${OUTPUT_PATH}/${dst_path}\"" + "-P" + "${CMAKE_SOURCE_DIR}/cmake/DeploySharedLibs.cmake" + ) + +endmacro(ll_deploy_sharedlibs_command) + diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 17bce6f434..fff78ecbe3 100644 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -1,111 +1,111 @@ -#!/usr/bin/python
-"""\
-@file run_build_test.py
-@author Nat Goodspeed
-@date 2009-09-03
-@brief Helper script to allow CMake to run some command after setting
- environment variables.
-
-CMake has commands to run an external program. But remember that each CMake
-command must be backed by multiple build-system implementations. Unfortunately
-it seems CMake can't promise that every target build system can set specified
-environment variables before running the external program of interest.
-
-This helper script is a workaround. It simply sets the requested environment
-variables and then executes the program specified on the rest of its command
-line.
-
-Example:
-
-python run_build_test.py -DFOO=bar myprog somearg otherarg
-
-sets environment variable FOO=bar, then runs:
-myprog somearg otherarg
-
-$LicenseInfo:firstyear=2009&license=internal$
-Copyright (c) 2009, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import subprocess
-
-def main(command, libpath=[], vars={}):
- """Pass:
- command is a sequence (e.g. a list) of strings. The first item in the list
- must be the command name, the rest are its arguments.
-
- libpath is a sequence of directory pathnames. These will be appended to
- the platform-specific dynamic library search path environment variable.
-
- vars is a dict of arbitrary (var, value) pairs to be added to the
- environment before running 'command'.
-
- This function runs the specified command, waits for it to terminate and
- returns its return code. This will be negative if the command terminated
- with a signal, else it will be the process's specified exit code.
- """
- # Handle platform-dependent libpath first.
- if sys.platform == "win32":
- lpvars = ["PATH"]
- elif sys.platform == "darwin":
- lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]
- elif sys.platform.startswith("linux"):
- lpvars = ["LD_LIBRARY_PATH"]
- else:
- # No idea what the right pathname might be! But only crump if this
- # feature is requested.
- if libpath:
- raise NotImplemented("run_build_test: unknown platform %s" % sys.platform)
- lpvars = []
- for var in lpvars:
- # Split the existing path. Bear in mind that the variable in question
- # might not exist; instead of KeyError, just use an empty string.
- dirs = os.environ.get(var, "").split(os.pathsep)
- # Append the sequence in libpath
-## print "%s += %r" % (var, libpath)
- dirs.extend(libpath)
- # Now rebuild the path string. This way we use a minimum of separators
- # -- and we avoid adding a pointless separator when libpath is empty.
- os.environ[var] = os.pathsep.join(dirs)
- # Now handle arbitrary environment variables. The tricky part is ensuring
- # that all the keys and values we try to pass are actually strings.
-## if vars:
-## print "Setting:"
-## for key, value in vars.iteritems():
-## print "%s=%s" % (key, value)
- os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
- # Run the child process.
-## print "Running: %s" % " ".join(command)
- return subprocess.call(command)
-
-if __name__ == "__main__":
- from optparse import OptionParser
- parser = OptionParser(usage="usage: %prog [options] command args...")
- # We want optparse support for the options we ourselves handle -- but we
- # DO NOT want it looking at options for the executable we intend to run,
- # rejecting them as invalid because we don't define them. So configure the
- # parser to stop looking for options as soon as it sees the first
- # positional argument (traditional Unix syntax).
- parser.disable_interspersed_args()
- parser.add_option("-D", "--define", dest="vars", default=[], action="append",
- metavar="VAR=value",
- help="Add VAR=value to the env variables defined")
- parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append",
- metavar="DIR",
- help="Add DIR to the platform-dependent DLL search path")
- opts, args = parser.parse_args()
- # What we have in opts.vars is a list of strings of the form "VAR=value"
- # or possibly just "VAR". What we want is a dict. We can build that dict by
- # constructing a list of ["VAR", "value"] pairs -- so split each
- # "VAR=value" string on the '=' sign (but only once, in case we have
- # "VAR=some=user=string"). To handle the case of just "VAR", append "" to
- # the list returned by split(), then slice off anything after the pair we
- # want.
- rc = main(command=args, libpath=opts.libpath,
- vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
- if rc not in (None, 0):
- print >>sys.stderr, "Failure running: %s" % " ".join(args)
- print >>sys.stderr, "Error: %s" % rc
- sys.exit((rc < 0) and 255 or rc)
+#!/usr/bin/python +"""\ +@file run_build_test.py +@author Nat Goodspeed +@date 2009-09-03 +@brief Helper script to allow CMake to run some command after setting + environment variables. + +CMake has commands to run an external program. But remember that each CMake +command must be backed by multiple build-system implementations. Unfortunately +it seems CMake can't promise that every target build system can set specified +environment variables before running the external program of interest. + +This helper script is a workaround. It simply sets the requested environment +variables and then executes the program specified on the rest of its command +line. + +Example: + +python run_build_test.py -DFOO=bar myprog somearg otherarg + +sets environment variable FOO=bar, then runs: +myprog somearg otherarg + +$LicenseInfo:firstyear=2009&license=internal$ +Copyright (c) 2009, Linden Research, Inc. +$/LicenseInfo$ +""" + +import os +import sys +import subprocess + +def main(command, libpath=[], vars={}): + """Pass: + command is a sequence (e.g. a list) of strings. The first item in the list + must be the command name, the rest are its arguments. + + libpath is a sequence of directory pathnames. These will be appended to + the platform-specific dynamic library search path environment variable. + + vars is a dict of arbitrary (var, value) pairs to be added to the + environment before running 'command'. + + This function runs the specified command, waits for it to terminate and + returns its return code. This will be negative if the command terminated + with a signal, else it will be the process's specified exit code. + """ + # Handle platform-dependent libpath first. + if sys.platform == "win32": + lpvars = ["PATH"] + elif sys.platform == "darwin": + lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"] + elif sys.platform.startswith("linux"): + lpvars = ["LD_LIBRARY_PATH"] + else: + # No idea what the right pathname might be! But only crump if this + # feature is requested. + if libpath: + raise NotImplemented("run_build_test: unknown platform %s" % sys.platform) + lpvars = [] + for var in lpvars: + # Split the existing path. Bear in mind that the variable in question + # might not exist; instead of KeyError, just use an empty string. + dirs = os.environ.get(var, "").split(os.pathsep) + # Append the sequence in libpath +## print "%s += %r" % (var, libpath) + dirs.extend(libpath) + # Now rebuild the path string. This way we use a minimum of separators + # -- and we avoid adding a pointless separator when libpath is empty. + os.environ[var] = os.pathsep.join(dirs) + # Now handle arbitrary environment variables. The tricky part is ensuring + # that all the keys and values we try to pass are actually strings. +## if vars: +## print "Setting:" +## for key, value in vars.iteritems(): +## print "%s=%s" % (key, value) + os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()])) + # Run the child process. +## print "Running: %s" % " ".join(command) + return subprocess.call(command) + +if __name__ == "__main__": + from optparse import OptionParser + parser = OptionParser(usage="usage: %prog [options] command args...") + # We want optparse support for the options we ourselves handle -- but we + # DO NOT want it looking at options for the executable we intend to run, + # rejecting them as invalid because we don't define them. So configure the + # parser to stop looking for options as soon as it sees the first + # positional argument (traditional Unix syntax). + parser.disable_interspersed_args() + parser.add_option("-D", "--define", dest="vars", default=[], action="append", + metavar="VAR=value", + help="Add VAR=value to the env variables defined") + parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append", + metavar="DIR", + help="Add DIR to the platform-dependent DLL search path") + opts, args = parser.parse_args() + # What we have in opts.vars is a list of strings of the form "VAR=value" + # or possibly just "VAR". What we want is a dict. We can build that dict by + # constructing a list of ["VAR", "value"] pairs -- so split each + # "VAR=value" string on the '=' sign (but only once, in case we have + # "VAR=some=user=string"). To handle the case of just "VAR", append "" to + # the list returned by split(), then slice off anything after the pair we + # want. + rc = main(command=args, libpath=opts.libpath, + vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars])) + if rc not in (None, 0): + print >>sys.stderr, "Failure running: %s" % " ".join(args) + print >>sys.stderr, "Error: %s" % rc + sys.exit((rc < 0) and 255 or rc) |