blob: cfd8d61d71e5bc3b8a854283783b4ab6770c2631 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
function(cpsc_homebrew_path input output)
set(path "${input}")
foreach(prefix "@@HOMEBREW_PREFIX@@" /opt/homebrew /usr/local)
string(REPLACE "${prefix}/" "${CPSC_DEPS_ROOT}/" path "${path}")
endforeach()
string(REPLACE "@@HOMEBREW_CELLAR@@" "${CPSC_DEPS_ROOT}/Cellar" path "${path}")
set(${output} "${path}" PARENT_SCOPE)
endfunction()
function(cpsc_prepare_homebrew_packages)
file(GLOB kegs LIST_DIRECTORIES TRUE "${CPSC_DEPS_ROOT}/Cellar/*/*")
file(MAKE_DIRECTORY "${CPSC_DEPS_ROOT}/opt")
foreach(keg IN LISTS kegs)
if(NOT IS_DIRECTORY "${keg}")
continue()
endif()
get_filename_component(rack "${keg}" DIRECTORY)
get_filename_component(formula "${rack}" NAME)
set(link "${CPSC_DEPS_ROOT}/opt/${formula}")
if(EXISTS "${link}")
message(FATAL_ERROR "Multiple versions of ${formula} in deps/packages; keep only one")
endif()
execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${keg}" "${link}"
RESULT_VARIABLE result)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot create local Homebrew prefix for ${formula}")
endif()
file(GLOB_RECURSE texts "${keg}/*.cmake" "${keg}/*.pc")
foreach(path IN LISTS texts)
file(READ "${path}" contents)
cpsc_homebrew_path("${contents}" contents)
file(WRITE "${path}" "${contents}")
endforeach()
endforeach()
# Bottles carry placeholder install names; extraction alone is insufficient.
cpsc_find_dependency(PROGRAM cpsc_otool NAMES otool REQUIRED)
cpsc_find_dependency(PROGRAM cpsc_install_name_tool NAMES install_name_tool REQUIRED)
cpsc_find_dependency(PROGRAM cpsc_codesign NAMES codesign REQUIRED)
cpsc_find_dependency(PROGRAM cpsc_brew NAMES brew)
if(cpsc_brew)
execute_process(COMMAND "${cpsc_brew}" --prefix
OUTPUT_VARIABLE system_prefix OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE result)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot determine the system Homebrew prefix")
endif()
endif()
foreach(keg IN LISTS kegs)
file(GLOB binaries "${keg}/bin/*")
file(GLOB_RECURSE libraries "${keg}/lib/*.dylib" "${keg}/lib/*.so")
foreach(binary IN LISTS binaries libraries)
if(IS_SYMLINK "${binary}" OR IS_DIRECTORY "${binary}")
continue()
endif()
execute_process(COMMAND "${cpsc_otool}" -L "${binary}"
OUTPUT_VARIABLE linkage ERROR_QUIET RESULT_VARIABLE result)
if(NOT result EQUAL 0)
continue() # Scripts and data files are not Mach-O binaries.
endif()
string(REGEX MATCHALL "\n[ \t]+[^ \t\n]+ \\(" references "${linkage}")
set(options)
foreach(reference IN LISTS references)
string(REGEX REPLACE "^\n[ \t]+([^ \t]+) \\($" "\\1" old "${reference}")
cpsc_homebrew_path("${old}" new)
if(NOT old STREQUAL new)
if(NOT EXISTS "${new}" AND system_prefix)
string(REPLACE "${CPSC_DEPS_ROOT}/" "${system_prefix}/" system "${new}")
if(EXISTS "${system}")
set(new "${system}")
endif()
endif()
list(APPEND options -change "${old}" "${new}")
endif()
endforeach()
execute_process(COMMAND "${cpsc_otool}" -l "${binary}"
OUTPUT_VARIABLE commands ERROR_QUIET RESULT_VARIABLE result)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot inspect Mach-O load commands in ${binary}")
endif()
string(REGEX MATCHALL "cmd LC_RPATH\n[^\n]*\n[ \t]*path [^\n]+" rpaths "${commands}")
foreach(rpath IN LISTS rpaths)
string(REGEX REPLACE
"^cmd LC_RPATH\n[^\n]*\n[ \t]*path (.*) \\(offset [0-9]+\\)$"
"\\1" old "${rpath}")
cpsc_homebrew_path("${old}" new)
if(NOT old STREQUAL new)
list(APPEND options -rpath "${old}" "${new}")
endif()
endforeach()
execute_process(COMMAND "${cpsc_otool}" -D "${binary}"
OUTPUT_VARIABLE identity ERROR_QUIET)
string(REGEX MATCH "\n([^\n]+)" match "${identity}")
if(match)
cpsc_homebrew_path("${CMAKE_MATCH_1}" new_identity)
list(APPEND options -id "${new_identity}")
endif()
if(options)
execute_process(COMMAND "${cpsc_install_name_tool}" ${options} "${binary}"
RESULT_VARIABLE result ERROR_VARIABLE error)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot relocate ${binary}: ${error}")
endif()
execute_process(COMMAND "${cpsc_codesign}" --force --sign - "${binary}"
RESULT_VARIABLE result ERROR_VARIABLE error)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Cannot sign relocated ${binary}: ${error}")
endif()
endif()
endforeach()
endforeach()
endfunction()
|