Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Similar to llvm-config, gets command-line flags that are needed to build applications linking against StreamExecutor. Reviewers: jprice, jlebar Subscribers: beanz, parallel_libs-commits Differential Revision: https://reviews.llvm.org/D24302 llvm-svn: 280955
- Loading branch information
Showing
4 changed files
with
215 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
parallel-libs/streamexecutor/tools/streamexecutor-config/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
find_package(PythonInterp REQUIRED) | ||
configure_file(streamexecutor-config.in streamexecutor-config) | ||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/streamexecutor-config DESTINATION bin) |
206 changes: 206 additions & 0 deletions
206
parallel-libs/streamexecutor/tools/streamexecutor-config/streamexecutor-config.in
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
#!@PYTHON_EXECUTABLE@ | ||
# | ||
#===- streamexecutor-config - Build config script for SE -----*- python -*--===# | ||
# | ||
# The LLVM Compiler Infrastructure | ||
# | ||
# This file is distributed under the University of Illinois Open Source | ||
# License. See LICENSE.TXT for details. | ||
# | ||
#===------------------------------------------------------------------------===# | ||
|
||
r""" | ||
Get configuration info needed to compile programs which use StreamExecutor. | ||
Runs llvm-config and adds StreamExecutor-specific flags to the output. Supports | ||
only the subset of llvm-config flags that are relevant for applications | ||
compiling against StreamExecutor. | ||
This utility will typically be used to construct a compile command line for an | ||
application which depends on the StreamExecutor library. | ||
For example: | ||
c++ example.cpp -o example \ | ||
$(streamexecutor-config \ | ||
--cppflags --cxxflags --ldflags --libs --system-libs) | ||
""" | ||
|
||
import argparse | ||
import errno | ||
import os | ||
import shlex | ||
import subprocess | ||
import sys | ||
|
||
def get_llvm_config_dir(): | ||
"""Gets the path to the llvm-config executable. | ||
Surrounding the cmake replacement with triple quotes should allow for paths | ||
that contain quotes.""" | ||
return r"""@LLVM_BINARY_DIR@/bin""" | ||
|
||
def get_cmake_install_prefix(): | ||
"""Gets the value of the cmake variable CMAKE_INSTALL_PREFIX. | ||
Surrounding the cmake replacement with triple quotes should allow for paths | ||
that contain quotes.""" | ||
return r"""@CMAKE_INSTALL_PREFIX@""" | ||
|
||
def cuddle_flag(flag, tokens): | ||
"""If flag appears by itself in tokens, combines it with the next token. | ||
>>> tokens = ['-I', '/usr/include'] | ||
>>> cuddle_flag('-I', tokens) | ||
>>> tokens | ||
['-I/usr/include'] | ||
>>> tokens = ['-L', '/usr/lib'] | ||
>>> cuddle_flag('-L', tokens) | ||
>>> tokens | ||
['-L/usr/lib'] | ||
>>> tokens = ['-I'] | ||
>>> cuddle_flag('-I', tokens) | ||
>>> tokens | ||
['-I'] | ||
>>> tokens = ['-I', '/usr/include', '-I', '/usr/local/include'] | ||
>>> cuddle_flag('-I', tokens) | ||
>>> tokens | ||
['-I/usr/include', '-I/usr/local/include'] | ||
""" | ||
start = 0 | ||
while True: | ||
try: | ||
index = tokens.index(flag, start) | ||
except ValueError: | ||
return | ||
if index + 1 < len(tokens): | ||
follower = tokens.pop(index + 1) | ||
tokens[index] = flag + follower | ||
start = index + 1 | ||
|
||
def get_llvm_config_output_for_dir(llvm_config_dir, flags_string): | ||
"""Calls llvm-config at the given path and returns the output with -I and -L | ||
flags cuddled.""" | ||
output = subprocess.check_output( | ||
['%s/llvm-config' % llvm_config_dir] + flags_string.split()).strip() | ||
tokens = shlex.split(output) | ||
cuddle_flag('-I', tokens) | ||
cuddle_flag('-L', tokens) | ||
return ' '.join(tokens) | ||
|
||
def has_token(token, string): | ||
"""Checks if the given token appears in the string. | ||
The token argument must be a single shell token. | ||
>>> string = '-I/usr/include -L"/usr/lib"' | ||
>>> has_token('-I/usr/include', string) | ||
True | ||
>>> has_token('-I/usr/local/include', string) | ||
False | ||
>>> has_token('-I"/usr/include"', string) | ||
True | ||
>>> has_token('-L"/usr/lib"', string) | ||
True | ||
>>> has_token('-L/usr/lib', string) | ||
True | ||
""" | ||
split_token = shlex.split(token) | ||
if len(split_token) > 1: | ||
raise ValueError('has_token called with a multi-token token: ' + token) | ||
escaped_token = split_token[0] | ||
return escaped_token in shlex.split(string) | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser( | ||
prog='streamexecutor-config', | ||
formatter_class=argparse.RawDescriptionHelpFormatter, | ||
description=__doc__) | ||
|
||
parser.add_argument( | ||
'--cppflags', | ||
action='store_true', | ||
help= | ||
'C preprocessor flags for files that include StreamExecutor headers.') | ||
|
||
parser.add_argument( | ||
'--cxxflags', | ||
action='store_true', | ||
help='C++ compiler flags for files that include StreamExecutor headers.') | ||
|
||
parser.add_argument( | ||
'--ldflags', | ||
action='store_true', | ||
help='Print linker flags.') | ||
|
||
parser.add_argument( | ||
'--libs', | ||
action='store_true', | ||
help='Libraries needed to link against StreamExecutor.') | ||
|
||
parser.add_argument( | ||
'--system-libs', | ||
action='store_true', | ||
help='System libraries needed to link against StreamExecutor.') | ||
|
||
parser.add_argument( | ||
'--llvm-config-dir', | ||
default=get_llvm_config_dir(), | ||
help='Directory containing the llvm-config executable. '\ | ||
'If not specified, defaults to the cmake-configured location') | ||
|
||
args = parser.parse_args() | ||
|
||
# Print the help message if the user did not pass any flag arguments. | ||
if not any( | ||
getattr(args, flag) | ||
for flag in ('cppflags', 'cxxflags', 'ldflags', 'libs', 'system_libs')): | ||
parser.print_help() | ||
sys.exit(1) | ||
|
||
# Check for the presence of the llvm-config executable. | ||
if not os.path.isfile('%s/llvm-config' % args.llvm_config_dir): | ||
sys.exit('llvm-config not found in: ' + args.llvm_config_dir) | ||
if not os.access('%s/llvm-config' % args.llvm_config_dir, os.X_OK): | ||
sys.exit('llvm-config not executable in: ' + args.llvm_config_dir) | ||
|
||
# We will always use args.llvm_config_dir as the second argument to | ||
# get_llvm_config_output_for_path. | ||
get_llvm_config_output = lambda flags : get_llvm_config_output_for_dir( | ||
args.llvm_config_dir, flags) | ||
|
||
all_flags = [] | ||
|
||
if args.cppflags: | ||
llvm_flags = get_llvm_config_output('--cppflags') | ||
all_flags.append(llvm_flags) | ||
se_flag = "-I%s/include" % get_cmake_install_prefix() | ||
if not has_token(token=se_flag, string=llvm_flags): | ||
all_flags.append(se_flag) | ||
|
||
if args.cxxflags: | ||
all_flags.append(get_llvm_config_output('--cxxflags')) | ||
|
||
if args.ldflags: | ||
llvm_flags = get_llvm_config_output('--ldflags') | ||
all_flags.append(llvm_flags) | ||
se_flag = "-L%s/lib" % get_cmake_install_prefix() | ||
if not has_token(token=se_flag, string=llvm_flags): | ||
all_flags.append(se_flag) | ||
|
||
if args.libs: | ||
llvm_flags = get_llvm_config_output('--libs support symbolize') | ||
se_flag = '-lstreamexecutor' | ||
if not has_token(token=se_flag, string=llvm_flags): | ||
all_flags.append(se_flag) | ||
all_flags.append(llvm_flags) | ||
|
||
if args.system_libs: | ||
all_flags.append(get_llvm_config_output('--system-libs')) | ||
|
||
print(' '.join(all_flags)) | ||
|
||
if __name__ == '__main__': | ||
main() |