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

Add a function to call conan lock create #319

Merged
merged 9 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,31 @@ It will also accept `OUTPUT_QUIET` and `ERROR_QUIET` arguments so that when it r
command the output is quiet or the error is bypassed (or both).

```cmake
conan_cmake_run(REQUIRES fmt/1.9.4
conan_cmake_install(REQUIRES fmt/1.9.4
cgal/5.0.2
OPTIONS Pkg:shared=True
OtherPkg:option=value
SETTINGS build_type=Debug)
```

## conan_cmake_lock_create()

This function is an additional wrapper for the [conan lock
create](https://docs.conan.io/en/latest/reference/commands/misc/lock.html#conan-lock-create)
sub-command of conan lock command to enable lockfile based workflows. You can pass all the arguments
that the command supports. Also, you can pass the auto-detected settings from
`conan_cmake_autodetect` in the `SETTINGS` argument.

It can receive as arguments: `PATH`, `REFERENCE`, `UPDATE`, `BASE`, `REMOTE`, `LOCKFILE`,
`LOCKFILE_OUT`, `LOCKFILE_NODE_ID`, `INSTALL_FOLDER`, `GENERATOR`, `BUILD`, `ENV`, `ENV_HOST`,
`ENV_BUILD`, `OPTIONS`, `OPTIONS_HOST`, `OPTIONS_BUILD`, `PROFILE`, `PROFILE_HOST`, `PROFILE_BUILD`,
`SETTINGS`, `SETTINGS_HOST`, `SETTINGS_BUILD`. For more information, check [conan lock
create](https://docs.conan.io/en/latest/reference/commands/misc/lock.html#conan-lock-create)
documentation.

It will also accept `OUTPUT_QUIET` and `ERROR_QUIET` arguments so that when it runs the `conan
install` command the output is quiet or the error is bypassed (or both).

## Using conan_cmake_autodetect() and conan_cmake_install() with Multi Configuration generators

The recommended approach when using Multi Configuration generators like Visual Studio or Xcode is
Expand Down
103 changes: 103 additions & 0 deletions conan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,109 @@ function(conan_cmake_install)

endfunction()

function(conan_cmake_lock_create)
if(DEFINED CONAN_COMMAND)
set(CONAN_CMD ${CONAN_COMMAND})
else()
conan_check(REQUIRED)
endif()

set(lockCreateOptions UPDATE BASE OUTPUT_QUIET ERROR_QUIET)
set(lockCreateOneValueArgs PATH REFERENCE REMOTE LOCKFILE LOCKFILE_OUT)
set(lockCreateMultiValueArgs BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE
PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD)
cmake_parse_arguments(ARGS "${lockCreateOptions}" "${lockCreateOneValueArgs}" "${lockCreateMultiValueArgs}" ${ARGN})
foreach(arg ${lockCreateOptions})
if(ARGS_${arg})
set(${arg} ${${arg}} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${lockCreateOneValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "REMOTE")
set(flag "--remote")
elseif("${arg}" STREQUAL "LOCKFILE")
set(flag "--lockfile")
elseif("${arg}" STREQUAL "LOCKFILE_OUT")
set(flag "--lockfile-out")
endif()
set(${arg} ${${arg}} ${flag} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${lockCreateMultiValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "BUILD")
set(flag "--build")
elseif("${arg}" STREQUAL "ENV")
set(flag "--env")
elseif("${arg}" STREQUAL "ENV_HOST")
set(flag "--env:host")
elseif("${arg}" STREQUAL "ENV_BUILD")
set(flag "--env:build")
elseif("${arg}" STREQUAL "OPTIONS")
set(flag "--options")
elseif("${arg}" STREQUAL "OPTIONS_HOST")
set(flag "--options:host")
elseif("${arg}" STREQUAL "OPTIONS_BUILD")
set(flag "--options:build")
elseif("${arg}" STREQUAL "PROFILE")
set(flag "--profile")
elseif("${arg}" STREQUAL "PROFILE_HOST")
set(flag "--profile:host")
elseif("${arg}" STREQUAL "PROFILE_BUILD")
set(flag "--profile:build")
elseif("${arg}" STREQUAL "SETTINGS")
set(flag "--settings")
elseif("${arg}" STREQUAL "SETTINGS_HOST")
set(flag "--settings:host")
elseif("${arg}" STREQUAL "SETTINGS_BUILD")
set(flag "--settings:build")
endif()
list(LENGTH ARGS_${arg} numargs)
foreach(item ${ARGS_${arg}})
if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD")
set(${arg} "--build")
break()
endif()
set(${arg} ${${arg}} ${flag} ${item})
endforeach()
endif()
endforeach()
if(DEFINED UPDATE)
set(UPDATE --update)
endif()
if(DEFINED BASE)
set(BASE --base)
endif()
set(lock_create_Args lock create ${PATH} ${REFERENCE} ${UPDATE} ${BASE} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER}
${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD}
${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD})

string(REPLACE ";" " " _lock_create_Args "${lock_create_Args}")
message(STATUS "Conan executing: ${CONAN_CMD} ${_lock_create_Args}")

if(ARGS_OUTPUT_QUIET)
set(OUTPUT_OPT OUTPUT_QUIET)
endif()
if(ARGS_ERROR_QUIET)
set(ERROR_OPT ERROR_QUIET)
endif()

execute_process(COMMAND ${CONAN_CMD} ${lock_create_Args}
RESULT_VARIABLE return_code
${OUTPUT_OPT}
${ERROR_OPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

if(NOT "${return_code}" STREQUAL "0")
if (ARGS_ERROR_QUIET)
message(WARNING "Conan lock create failed='${return_code}'")
else()
message(FATAL_ERROR "Conan lock create failed='${return_code}'")
endif()
endif()
endfunction()

function(conan_cmake_setup_conanfile)
conan_parse_arguments(${ARGV})
if(ARGUMENTS_CONANFILE)
Expand Down
26 changes: 26 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,32 @@ def test_conan_cmake_install_find_package(self):
run("cmake .. {} -DCMAKE_BUILD_TYPE=Release".format(generator))
run("cmake --build . --config Release")

def test_conan_lock_create(self):
content = textwrap.dedent("""
cmake_minimum_required(VERSION 3.5)
project(FormatOutput CXX)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
add_definitions("-std=c++11")
include(conan.cmake)
conan_cmake_configure(REQUIRES fmt/6.1.2 GENERATORS cmake_find_package)
conan_cmake_autodetect(settings)
conan_cmake_lock_create(PATH conanfile.txt LOCKFILE_OUT mylockfile.lock SETTINGS ${settings})
conan_cmake_install(PATH_OR_REFERENCE .
REMOTE conan-center
LOCKFILE mylockfile.lock
BUILD missing)
find_package(fmt)
add_executable(main main.cpp)
target_link_libraries(main fmt::fmt)
""")
save("CMakeLists.txt", content)
os.makedirs("build")
os.chdir("build")
run("cmake .. {} -DCMAKE_BUILD_TYPE=Release".format(generator))
assert os.path.exists("mylockfile.lock")
run("cmake --build . --config Release")

# https://github.com/conan-io/cmake-conan/issues/315
def test_issue_315(self):
content = textwrap.dedent("""
Expand Down