Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reverse build/host activation order, to give build exe's higher priority #2686

Merged
merged 2 commits into from
Feb 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 35 additions & 14 deletions conda_build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,25 @@ def bundle_conda(output, metadata, env, stats, **kw):
else:
if not metadata.always_include_files():
log.warn("No files or script found for output {}".format(output.get('name')))
build_deps = metadata.get_value('requirements/build')
host_deps = metadata.get_value('requirements/host')
build_pkgs = [pkg.split()[0] for pkg in build_deps]
host_pkgs = [pkg.split()[0] for pkg in host_deps]
dangerous_double_deps = {'python': 'PYTHON', 'r-base': 'R'}
for dep, env_var in dangerous_double_deps.items():
if all(dep in pkgs_list for pkgs_list in (build_pkgs, host_pkgs)):
raise CondaBuildException("Empty package; {0} present in build and host deps. "
"You probably picked up the build environment's {0} "
" executable. You need to alter your recipe to "
" use the {1} env var in your recipe to "
"run that executable.".format(dep, env_var))
elif (dep in build_pkgs and metadata.uses_new_style_compiler_activation):
link = ("https://conda.io/docs/user-guide/tasks/build-packages/"
"define-metadata.html#host")
raise CondaBuildException("Empty package; {0} dep present in build but not "
"host requirements. You need to move your {0} dep "
"to the host requirements section. See {1} for more "
"info." .format(dep, link))
initial_files = set(utils.prefix_files(metadata.config.host_prefix))

for pat in metadata.always_include_files():
Expand Down Expand Up @@ -986,18 +1005,6 @@ def _write_sh_activation_text(file_handle, m):
activate_path = ''.join((cygpath_prefix,
os.path.join(utils.root_script_dir, 'activate').replace('\\', '\\\\'),
cygpath_suffix))
build_prefix_path = ''.join((cygpath_prefix,
m.config.build_prefix.replace('\\', '\\\\'),
cygpath_suffix))

file_handle.write('source "{0}" "{1}"\n'.format(activate_path, build_prefix_path))

# conda 4.4 requires a conda-meta/history file for a valid conda prefix
history_file = join(m.config.build_prefix, 'conda-meta', 'history')
if not isfile(history_file):
if not isdir(dirname(history_file)):
os.makedirs(dirname(history_file))
open(history_file, 'a').close()

if m.is_cross:
# HACK: we need both build and host envs "active" - i.e. on PATH,
Expand All @@ -1019,12 +1026,26 @@ def _write_sh_activation_text(file_handle, m):
if not isdir(dirname(history_file)):
os.makedirs(dirname(history_file))
open(history_file, 'a').close()
file_handle.write('unset CONDA_PATH_BACKUP\n')
file_handle.write('export CONDA_MAX_SHLVL=2\n')
host_prefix_path = ''.join((cygpath_prefix,
m.config.host_prefix.replace('\\', '\\\\'),
cygpath_suffix))
file_handle.write('source "{0}" "{1}"\n' .format(activate_path, host_prefix_path))
file_handle.write('unset CONDA_PATH_BACKUP\n')
file_handle.write('export CONDA_MAX_SHLVL=2\n')

# Write build prefix activation AFTER host prefix, so that its executables come first
build_prefix_path = ''.join((cygpath_prefix,
m.config.build_prefix.replace('\\', '\\\\'),
cygpath_suffix))

file_handle.write('source "{0}" "{1}"\n'.format(activate_path, build_prefix_path))

# conda 4.4 requires a conda-meta/history file for a valid conda prefix
history_file = join(m.config.build_prefix, 'conda-meta', 'history')
if not isfile(history_file):
if not isdir(dirname(history_file)):
os.makedirs(dirname(history_file))
open(history_file, 'a').close()


def _write_activation_text(script_path, m):
Expand Down
13 changes: 7 additions & 6 deletions conda_build/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,6 @@ def build_vcvarsall_cmd(cmd, arch=arch_selector):


def _write_bat_activation_text(file_handle, m):
file_handle.write('call "{conda_root}\\activate.bat" "{prefix}"\n'.format(
conda_root=root_script_dir,
prefix=m.config.build_prefix))
if m.is_cross:
# HACK: we need both build and host envs "active" - i.e. on PATH,
# and with their activate.d scripts sourced. Conda only
Expand All @@ -225,12 +222,16 @@ def _write_bat_activation_text(file_handle, m):
if not isdir(dirname(history_file)):
os.makedirs(dirname(history_file))
open(history_file, 'a').close()
# removing this placeholder should make conda double-activate with conda 4.3
file_handle.write('set "PATH=%PATH:CONDA_PATH_PLACEHOLDER;=%"\n')
file_handle.write('set CONDA_MAX_SHLVL=2\n')
file_handle.write('call "{conda_root}\\activate.bat" "{prefix}"\n'.format(
conda_root=root_script_dir,
prefix=m.config.host_prefix))
# removing this placeholder should make conda double-activate with conda 4.3
file_handle.write('set "PATH=%PATH:CONDA_PATH_PLACEHOLDER;=%"\n')
file_handle.write('set CONDA_MAX_SHLVL=2\n')
# Write build prefix activation AFTER host prefix, so that its executables come first
file_handle.write('call "{conda_root}\\activate.bat" "{prefix}"\n'.format(
conda_root=root_script_dir,
prefix=m.config.build_prefix))


def build(m, bld_bat):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# common point of confusion around the split between build and host

package:
name: empty_pkg_with_python_build_host
version: 1.0

build:
script: echo weeee

requirements:
build:
- {{ compiler('c') }}
- python
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package:
name: empty_pkg_with_python_build_host
version: 1.0

build:
script: echo weeee

requirements:
build:
- python
host:
- python
14 changes: 13 additions & 1 deletion tests/test_api_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from conda_build.utils import (copy_into, on_win, check_call_env, convert_path_for_cygwin_or_msys2,
package_has_file, check_output_env, get_conda_operation_locks, rm_rf)
from conda_build.os_utils.external import find_executable
from conda_build.exceptions import DependencyNeedsBuildingError
from conda_build.exceptions import DependencyNeedsBuildingError, CondaBuildException

from .utils import is_valid_dir, metadata_dir, fail_dir, add_mangling, FileNotFoundError

Expand Down Expand Up @@ -1224,3 +1224,15 @@ def test_overlinking_detection(testing_config):
with pytest.raises(SystemExit):
api.build(recipe, config=testing_config)
rm_rf(dest_file)


def test_empty_package_with_python_in_build_and_host_barfs(testing_config):
recipe = os.path.join(metadata_dir, '_empty_pkg_with_python_build_host')
with pytest.raises(CondaBuildException):
api.build(recipe, config=testing_config)


def test_empty_package_with_python_and_compiler_in_build_barfs(testing_config):
recipe = os.path.join(metadata_dir, '_compiler_python_build_section')
with pytest.raises(CondaBuildException):
api.build(recipe, config=testing_config)