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

Inject in the PATH the folder from the CMake exe that invoked the provider if cmake is not found in the PATH #593

Merged
merged 15 commits into from
Jan 22, 2024
21 changes: 21 additions & 0 deletions conan_provider.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,26 @@ function(conan_install)
# Invoke "conan install" with the provided arguments
set(CONAN_ARGS ${CONAN_ARGS} -of=${CONAN_OUTPUT_FOLDER})
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN}")


# In case there was not a valid cmake executable in the PATH, we inject the
# same we used to invoke the provider to the PATH
if(DEFINED PATH_TO_CMAKE_BIN)
set(_OLD_PATH $ENV{PATH})
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
endif()

execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN} --format=json
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

if(DEFINED PATH_TO_CMAKE_BIN)
set(ENV{PATH} "${_OLD_PATH}")
endif()

if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan install failed='${return_code}'")
else()
Expand Down Expand Up @@ -579,3 +593,10 @@ cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependen
# Configurable variables for Conan profiles
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")

find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)

if(NOT _cmake_program)
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
endif()
26 changes: 26 additions & 0 deletions tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,3 +669,29 @@ def test_no_generator_py(self, capfd, basic_cmake_project, resource_path):
run(f'cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release', check=False)
_, err = capfd.readouterr()
assert 'Cmake-conan: CMakeDeps generator was not defined in the conanfile' in err


class TestInjectCMakeFolderToPath:
def test_inject_invoked_path(self, capfd, basic_cmake_project):
"""
Test that we inject the CMake we used to invoke the provider for the Conan builds
"""
source_dir, binary_dir = basic_cmake_project

# remove hello binaries to make sure we invoke to cmake via Conan
run("conan remove hello:*")

cmake_dir = os.path.dirname(subprocess.check_output(["which", "cmake"]).decode().strip())

# remove the cmake folder from the path, invoke cmake with the full path and make sure that nothing fails
original_path = os.environ["PATH"]
modified_path = ":".join([p for p in original_path.split(":") if p != cmake_dir])
os.environ["PATH"] = modified_path

run(f"{cmake_dir}/cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release")

os.environ["PATH"] = original_path

_, err = capfd.readouterr()

assert "Built target hello" in err
Loading