Skip to content

Commit d4638cb

Browse files
committed
Make paths in generated llvm-lit relative as well.
This builds on top of D77184. With this, I can rename my build directory to a different name and `bin/llvm-lit ../llvm-project/clang/test ../llvm-project/llvm/test` still succeeds. I haven't tried copying the build dir to a different machine to run tests there yet, but I tried something like it a few months ago and it worked back then. Changes: - Make configure_lit_site_cfg() store the main / generated config pair interleaved in the LLVM_LIT_CONFIG_FILES list and postpone converting it to python code to llvm-lit's CMakeList. - Pull the relpath code into a new function make_paths_relative() and call that in llvm-lit's CMakeList, prior to converting the list to python code. - Pull the path() function into a variable and use that in llvm-lit's CMakeList too. Differential Revision: https://reviews.llvm.org/D77496
1 parent a41cd6b commit d4638cb

File tree

2 files changed

+75
-39
lines changed

2 files changed

+75
-39
lines changed

llvm/cmake/modules/AddLLVM.cmake

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,52 @@ macro(set_llvm_build_mode)
13911391
endif ()
13921392
endmacro()
13931393

1394+
# Takes a list of path names in pathlist and a base directory, and returns
1395+
# a list of paths relative to the base directory in out_pathlist.
1396+
# Paths that are on a different drive than the basedir (on Windows) or that
1397+
# contain symlinks are returned absolute.
1398+
# Use with LLVM_LIT_PATH_FUNCTION below.
1399+
function(make_paths_relative out_pathlist basedir pathlist)
1400+
# Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip
1401+
# empty list entries. So escape the ;s in the list and do the splitting
1402+
# outselves. cmake has no relpath function, so use Python for that.
1403+
string(REPLACE ";" "\\;" pathlist_escaped "${pathlist}")
1404+
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "\n
1405+
import os, sys\n
1406+
base = sys.argv[1]
1407+
def haslink(p):\n
1408+
if not p or p == os.path.dirname(p): return False\n
1409+
return os.path.islink(p) or haslink(os.path.dirname(p))\n
1410+
def relpath(p):\n
1411+
if not p: return ''\n
1412+
if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n
1413+
if haslink(p) or haslink(base): return p\n
1414+
return os.path.relpath(p, base).replace(os.sep, '/')\n
1415+
sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"
1416+
${basedir}
1417+
${pathlist_escaped}
1418+
OUTPUT_VARIABLE pathlist_relative)
1419+
set(${out_pathlist} "${pathlist_relative}" PARENT_SCOPE)
1420+
endfunction()
1421+
1422+
# Converts a file that's relative to the current python file to an absolute
1423+
# path. Since this uses __file__, it has to be emitted into python files that
1424+
# use it and can't be in a lit module. Use with make_paths_relative().
1425+
string(CONCAT LLVM_LIT_PATH_FUNCTION
1426+
# Lit converts config paths to lower case in discovery.py, before
1427+
# loading the config. This causes __file__ to be all lower-case (including
1428+
# the drive letter), but several clang tests pass -include %s and a
1429+
# clang warning checks that passed case matches on-disk cache. So it's
1430+
# important that this restores the on-disk case of the prefix.
1431+
"# Allow generated file to be relocatable.\n"
1432+
"def path(p):\n"
1433+
" if not p: return ''\n"
1434+
" p = os.path.join(os.path.dirname(os.path.abspath(__file__)), p)\n"
1435+
" p = os.path.normpath(p).replace(os.sep, '/')\n"
1436+
" if os.name == 'nt' and os.path.isabs(p): return p[0].upper() + p[1:]\n"
1437+
" return p\n"
1438+
)
1439+
13941440
# This function provides an automatic way to 'configure'-like generate a file
13951441
# based on a set of common and custom variables, specifically targeting the
13961442
# variables needed for the 'lit.site.cfg' files. This function bundles the
@@ -1453,20 +1499,9 @@ function(configure_lit_site_cfg site_in site_out)
14531499
set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
14541500
set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}")
14551501

1456-
set(LIT_SITE_CFG_IN_HEADER "# Autogenerated from ${site_in}\n# Do not edit!")
1457-
1458-
# Lit converts config paths to lower case in discovery.py, before
1459-
# loading the config. This causes __file__ to be all lower-case (including
1460-
# the drive letter), but several clang tests pass -include %s and a
1461-
# clang warning checks that passed case matches on-disk cache. So it's
1462-
# important that this restores the on-disk case of the prefix.
1463-
string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n"
1464-
"# Allow generated lit.site.cfg.py to be relocatable.\n"
1465-
"def path(p):\n"
1466-
" if not p: return ''\n"
1467-
" p = os.path.normpath(os.path.join(os.path.dirname(__file__), p)).replace(os.sep, '/')\n"
1468-
" if os.name == 'nt' and os.path.isabs(p): return p[0].upper() + p[1:]\n"
1469-
" return p\n"
1502+
string(CONCAT LIT_SITE_CFG_IN_HEADER
1503+
"# Autogenerated from ${site_in}\n# Do not edit!\n\n"
1504+
"${LLVM_LIT_PATH_FUNCTION}"
14701505
)
14711506

14721507
# Override config_target_triple (and the env)
@@ -1493,27 +1528,9 @@ function(configure_lit_site_cfg site_in site_out)
14931528
endforeach()
14941529
list(REMOVE_AT ARG_PATH_VALUES 0)
14951530

1496-
# Compute paths relative to the directory containing output lit.site.cfg.py.
1497-
# Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip
1498-
# empty list entries. So escape the ;s in the list and do the splitting
1499-
# outselves. cmake has no relpath function, so use Python for that.
1500-
string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}")
15011531
get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY)
1502-
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "\n
1503-
import os, sys\n
1504-
base = sys.argv[1]
1505-
def haslink(p):\n
1506-
if not p or p == os.path.dirname(p): return False\n
1507-
return os.path.islink(p) or haslink(os.path.dirname(p))\n
1508-
def relpath(p):\n
1509-
if not p: return ''\n
1510-
if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n
1511-
if haslink(p) or haslink(base): return p\n
1512-
return os.path.relpath(p, base).replace(os.sep, '/')\n
1513-
sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"
1514-
${OUTPUT_DIR}
1515-
${ARG_PATH_VALUES_ESCAPED}
1516-
OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE)
1532+
make_paths_relative(
1533+
ARG_PATH_VALUES_RELATIVE "${OUTPUT_DIR}" "${ARG_PATH_VALUES}")
15171534

15181535
list(LENGTH ARG_PATHS len_paths)
15191536
list(LENGTH ARG_PATH_VALUES len_path_values)
@@ -1537,10 +1554,10 @@ sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"
15371554
configure_file(${site_in} ${site_out} @ONLY)
15381555

15391556
if (EXISTS "${ARG_MAIN_CONFIG}")
1540-
set(PYTHON_STATEMENT "map_config('${ARG_MAIN_CONFIG}', '${site_out}')")
1541-
get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP)
1542-
set(LLVM_LIT_CONFIG_MAP "${LLVM_LIT_CONFIG_MAP}\n${PYTHON_STATEMENT}")
1543-
set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP ${LLVM_LIT_CONFIG_MAP})
1557+
# Remember main config / generated site config for llvm-lit.in.
1558+
get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES)
1559+
list(APPEND LLVM_LIT_CONFIG_FILES "${ARG_MAIN_CONFIG}" "${site_out}")
1560+
set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES ${LLVM_LIT_CONFIG_FILES})
15441561
endif()
15451562
endfunction()
15461563

llvm/utils/llvm-lit/CMakeLists.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP)
1+
get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES)
2+
list(LENGTH LLVM_LIT_CONFIG_FILES file_len)
3+
math(EXPR file_last "${file_len} - 1")
24

35
get_llvm_lit_path(LIT_BASE_DIR LIT_FILE_NAME)
46

7+
# LLVM_LIT_CONFIG_FILES contains interleaved main config (in the source tree)
8+
# and site config (in the build tree) pairs. Make them relative to
9+
# llvm-lit and then convert them to map_config() calls.
10+
if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
11+
make_paths_relative(
12+
LLVM_LIT_CONFIG_FILES "${LIT_BASE_DIR}" "${LLVM_LIT_CONFIG_FILES}")
13+
endif()
14+
15+
set(LLVM_LIT_CONFIG_MAP "${LLVM_LIT_PATH_FUNCTION}\n")
16+
foreach(i RANGE 0 ${file_last} 2)
17+
list(GET LLVM_LIT_CONFIG_FILES ${i} main_config)
18+
math(EXPR i1 "${i} + 1")
19+
list(GET LLVM_LIT_CONFIG_FILES ${i1} site_out)
20+
set(map "map_config(path('${main_config}'), path('${site_out}'))")
21+
set(LLVM_LIT_CONFIG_MAP "${LLVM_LIT_CONFIG_MAP}\n${map}")
22+
endforeach()
23+
524
set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
625

726
if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")

0 commit comments

Comments
 (0)