Skip to content

Commit

Permalink
Merge pull request #624 from scpeters/multiarch
Browse files Browse the repository at this point in the history
Attempt at multiarch support (#545)
  • Loading branch information
dirk-thomas committed May 6, 2014
2 parents 6677020 + 2e83966 commit e1da2a2
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 16 deletions.
26 changes: 26 additions & 0 deletions cmake/catkin_generate_environment.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,32 @@ function(catkin_generate_environment)
file(WRITE "${CMAKE_BINARY_DIR}/CATKIN_IGNORE" "")
endif()

# get multiarch name
set(CATKIN_LIB_ENVIRONMENT_PATHS "'${CATKIN_GLOBAL_LIB_DESTINATION}'")
set(CATKIN_PKGCONFIG_ENVIRONMENT_PATHS "os.path.join('${CATKIN_GLOBAL_LIB_DESTINATION}', 'pkgconfig')")
if (UNIX AND NOT APPLE)
# Two step looking for multiarch support: check for gcc -print-multiarch
# and, if failed, try to run dpkg-architecture
execute_process(COMMAND gcc -print-multiarch
OUTPUT_VARIABLE CATKIN_MULTIARCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if ("${CATKIN_MULTIARCH}" STREQUAL "")
execute_process(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
OUTPUT_VARIABLE CATKIN_MULTIARCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif()
if (NOT "${CATKIN_MULTIARCH}" STREQUAL "")
set(CATKIN_LIB_ENVIRONMENT_PATHS
"[${CATKIN_LIB_ENVIRONMENT_PATHS}, os.path.join('${CATKIN_GLOBAL_LIB_DESTINATION}', '${CATKIN_MULTIARCH}')]")
set(CATKIN_PKGCONFIG_ENVIRONMENT_PATHS
"[${CATKIN_PKGCONFIG_ENVIRONMENT_PATHS}, os.path.join('${CATKIN_GLOBAL_LIB_DESTINATION}', '${CATKIN_MULTIARCH}', 'pkgconfig')]")
endif()
endif()

# generate Python setup util
atomic_configure_file(${catkin_EXTRAS_DIR}/templates/_setup_util.py.in
${CATKIN_DEVEL_PREFIX}/_setup_util.py
Expand Down
33 changes: 20 additions & 13 deletions cmake/templates/_setup_util.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ IS_WINDOWS = (system == 'Windows')
ENV_VAR_SUBFOLDERS = {
'CMAKE_PREFIX_PATH': '',
'CPATH': 'include',
'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': '@CATKIN_GLOBAL_LIB_DESTINATION@',
'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': @CATKIN_LIB_ENVIRONMENT_PATHS@,
'PATH': '@CATKIN_GLOBAL_BIN_DESTINATION@',
'PKG_CONFIG_PATH': 'lib/pkgconfig',
'PKG_CONFIG_PATH': @CATKIN_PKGCONFIG_ENVIRONMENT_PATHS@,
'PYTHONPATH': '@PYTHON_INSTALL_DIR@',
}

Expand All @@ -68,11 +68,14 @@ def rollback_env_variables(environ, env_var_subfolders):
lines = []
unmodified_environ = copy.copy(environ)
for key in sorted(env_var_subfolders.keys()):
subfolder = env_var_subfolders[key]
value = _rollback_env_variable(unmodified_environ, key, subfolder)
if value is not None:
environ[key] = value
lines.append(assignment(key, value))
subfolders = env_var_subfolders[key]
if not isinstance(subfolders, list):
subfolders = [subfolders]
for subfolder in subfolders:
value = _rollback_env_variable(unmodified_environ, key, subfolder)
if value is not None:
environ[key] = value
lines.append(assignment(key, value))
if lines:
lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH'))
return lines
Expand Down Expand Up @@ -143,19 +146,23 @@ def prepend_env_variables(environ, env_var_subfolders, workspaces):
return lines


def _prefix_env_variable(environ, name, paths, subfolder):
def _prefix_env_variable(environ, name, paths, subfolders):
'''
Return the prefix to prepend to the environment variable NAME, adding any path in NEW_PATHS_STR without creating duplicate or empty items.
'''
value = environ[name] if name in environ else ''
environ_paths = [path for path in value.split(os.pathsep) if path]
checked_paths = []
for path in paths:
if subfolder:
path = os.path.join(path, subfolder)
# exclude any path already in env and any path we already added
if path not in environ_paths and path not in checked_paths:
checked_paths.append(path)
if not isinstance(subfolders, list):
subfolders = [subfolders]
for subfolder in subfolders:
path_tmp = path
if subfolder:
path_tmp = os.path.join(path_tmp, subfolder)
# exclude any path already in env and any path we already added
if path_tmp not in environ_paths and path_tmp not in checked_paths:
checked_paths.append(path_tmp)
prefix_str = os.pathsep.join(checked_paths)
if prefix_str != '' and environ_paths:
prefix_str += os.pathsep
Expand Down
26 changes: 24 additions & 2 deletions python/catkin/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,25 @@ def isolation_print_command(cmd, path=None, add_env=None):
)


def get_multiarch():
if not sys.platform.lower().startswith('linux'):
return ''
# this function returns the suffix for lib directories on supported systems or an empty string
# it uses two step approach to look for multiarch: first run gcc -print-multiarch and if
# failed try to run dpkg-architecture
p = subprocess.Popen(
['gcc', '-print-multiarch'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
out, err = subprocess.Popen(
['dpkg-architecture', '-qDEB_HOST_MULTIARCH'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

# be sure of returning empty string or a valid multiarch tuple format
assert(not out.strip() or out.strip().count('-') == 2);
return out.strip()

def get_python_install_dir():
# this function returns the same value as the CMake variable PYTHON_INSTALL_DIR from catkin/cmake/python.cmake
python_install_dir = 'lib'
Expand Down Expand Up @@ -519,9 +538,12 @@ def build_cmake_package(
subs['ld_path'] = os.path.join(install_target, 'lib') + ":"
pythonpath = os.path.join(install_target, get_python_install_dir())
subs['pythonpath'] = pythonpath + ':'
subs['pkgcfg_path'] = os.path.join(install_target, 'lib', 'pkgconfig')
subs['pkgcfg_path'] += ":"
subs['pkgcfg_path'] = os.path.join(install_target, 'lib', 'pkgconfig') + ":"
subs['path'] = os.path.join(install_target, 'bin') + ":"
arch = get_multiarch()
if arch:
subs['ld_path'] += os.path.join(install_target, 'lib', arch) + ":"
subs['pkgcfg_path'] += os.path.join(install_target, 'lib', arch, 'pkgconfig') + ":"
if not os.path.exists(os.path.dirname(new_setup_path)):
os.mkdir(os.path.dirname(new_setup_path))
with open(new_setup_path, 'w') as file_handle:
Expand Down
3 changes: 2 additions & 1 deletion test/unit_tests/test_setup_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

data = configure_file(os.path.join(os.path.dirname(__file__), '..', '..', 'cmake', 'templates', '_setup_util.py.in'),
{
'CATKIN_GLOBAL_LIB_DESTINATION': 'lib',
'CATKIN_LIB_ENVIRONMENT_PATHS': "'lib'",
'CATKIN_PKGCONFIG_ENVIRONMENT_PATHS': "os.path.join('lib', 'pkgconfig')",
'CATKIN_GLOBAL_BIN_DESTINATION': 'bin',
'PYTHON_INSTALL_DIR': 'pythonX.Y/packages',
'CMAKE_PREFIX_PATH_AS_IS': '',
Expand Down

0 comments on commit e1da2a2

Please sign in to comment.