Skip to content

Commit 382828a

Browse files
committed
tooling: Add option to specify lockfile generation
It works like this: make LOCKFILE_SOURCE=../conanfile.py all when you are in sub-directory and you want to use some other profile for dependency resolution etc. The lockfile source can also be used for the status target: make LOCKFILE_SOURCE=../conanfile.py status This will result in a different answer to the case where no lockfile is specified. This partially resolves issue #100.
1 parent 3068330 commit 382828a

File tree

2 files changed

+97
-62
lines changed

2 files changed

+97
-62
lines changed

Makefile

+18-7
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ define print_header
1919
@printf ":: %s\n" ${1}
2020
endef
2121

22-
CLOE_ROOT := .
22+
CLOE_ROOT := $(shell pwd)
2323
CLOE_LAUNCH := PYTHONPATH="${CLOE_ROOT}/cli" python3 -m cloe_launch
2424

2525
# Build configuration:
26-
BUILD_DIR := build
27-
INSTALL_DIR := /usr/local
28-
CONAN_OPTIONS :=
26+
BUILD_DIR := build
27+
LOCKFILE_SOURCE := conanfile.py
28+
BUILD_LOCKFILE := ${BUILD_DIR}/conan.lock
29+
LOCKFILE_OPTION := --lockfile="${CLOE_ROOT}/${BUILD_LOCKFILE}"
30+
INSTALL_DIR := /usr/local
31+
CONAN_OPTIONS :=
2932

3033
.PHONY: help
3134
.DEFAULT: help
@@ -38,7 +41,7 @@ include Makefile.setup
3841
include Makefile.all
3942

4043
# Workspace targets -----------------------------------------------------------
41-
.PHONY: status deploy sphinx doxygen docker-all docker-test docker-release purge-all smoketest
44+
.PHONY: lockfile status deploy sphinx doxygen docker-all docker-test docker-release purge-all smoketest
4245
help::
4346
echo "Available workspace targets:"
4447
echo " smoketest to run BATS system tests"
@@ -52,8 +55,16 @@ help::
5255
echo " docker-release to upload all Conan packages from Docker images"
5356
echo
5457

55-
status:
56-
@for pkg in ${ALL_PKGS}; do [ -d $${pkg} ] && ${MAKE} -C $${pkg} status || true; done
58+
${BUILD_LOCKFILE}:
59+
${MAKE} -f Makefile.package LOCKFILE_SOURCE=${LOCKFILE_SOURCE} ${BUILD_LOCKFILE}
60+
61+
lockfile: ${BUILD_LOCKFILE}
62+
63+
status: ${BUILD_LOCKFILE}
64+
@for pkg in ${ALL_PKGS}; do \
65+
[ -d $${pkg} ] || continue; \
66+
${MAKE} LOCKFILE_SOURCE="" LOCKFILE_OPTION=${LOCKFILE_OPTION} -C $${pkg} status || true; \
67+
done
5768

5869
deploy:
5970
$(call print_header, "Deploying binaries to ${INSTALL_DIR}...")

Makefile.package

+79-55
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,16 @@ endif
3636
SOURCE_DIR := .
3737
SOURCE_CONANFILE := conanfile.py
3838
SOURCE_CMAKELISTS:= ${SOURCE_DIR}/CMakeLists.txt
39+
LOCKFILE_SOURCE :=
40+
LOCKFILE_OPTION :=
3941
CLEAN_SOURCE_DIR := false
4042
BUILD_DIR := build
4143
BUILD_CONANINFO := ${BUILD_DIR}/conanbuildinfo.cmake
4244
BUILD_CMAKECACHE := ${BUILD_DIR}/CMakeCache.txt
45+
BUILD_LOCKFILE := ${BUILD_DIR}/conan.lock
4346
BUILD_LAYOUT := ${PROJECT_ROOT}/.conan-layout.ini
4447
BUILD_POLICY := missing
4548

46-
# Normally, you should set this in your profile, but if you just want to build
47-
# the package in debug mode once, you can do it this way, although it will
48-
# only apply to local builds.
49-
#
50-
# This can be one of: None, Debug, Release, RelWithDebInfo, MinSizeRel
51-
BUILD_TYPE := RelWithDebInfo
52-
5349
PACKAGE_NAME := $(shell sed -rn 's/.*name\s*=\s*"([^"]+)"$$/\1/p' ${SOURCE_CONANFILE})
5450
PACKAGE_VERSION := $(or \
5551
$(shell sed -rn 's/\s+version\s*=\s*"([^"]+)"$$/\1/p' ${SOURCE_CONANFILE}), \
@@ -59,22 +55,42 @@ PACKAGE_VERSION := $(or \
5955
PACKAGE_CHANNEL := cloe/develop
6056
PACKAGE_FQN := ${PACKAGE_NAME}/${PACKAGE_VERSION}@${PACKAGE_CHANNEL}
6157

62-
# Determining the PACKAGE_DIR takes a long time because we have to call Conan,
63-
# so only do it for the targets that actually make use of it.
64-
ifneq "$(filter help list status,${MAKECMDGOALS})" ""
65-
PACKAGE_INFO := $(shell conan info ${PACKAGE_FQN} --package-filter ${PACKAGE_FQN} --paths 2>/dev/null | sed -r 's/$$/\\n/')
66-
PACKAGE_ID := $(shell echo "${PACKAGE_INFO}" | sed -rn "s/^ *ID: *(.*)$$/\1/p")
67-
PACKAGE_DIR := $(shell echo "${PACKAGE_INFO}" | sed -rn "s/^ *package_folder: *(.*)$$/\1/p")
68-
PACKAGE_DATE := $(shell echo "${PACKAGE_INFO}" | sed -rn "s/^ *Creation date: *(.*)$$/\1/p")
69-
endif
58+
# Normally, you should set this in your profile, but if you just want to build
59+
# the package in debug mode once, you can do it this way, although it will
60+
# only apply to local builds.
61+
#
62+
# This can be one of: None, Debug, Release, RelWithDebInfo, MinSizeRel
63+
BUILD_TYPE := RelWithDebInfo
64+
BUILD_TYPE_OPTION := -s ${PACKAGE_NAME}:build_type=${BUILD_TYPE}
7065

7166
# These options can be set to influence package and configure.
7267
CONAN_OPTIONS :=
7368

69+
.PHONY: ${BUILD_LOCKFILE}
70+
ifneq "${LOCKFILE_SOURCE}" ""
71+
ifeq "$(realpath ${LOCKFILE_SOURCE})" "$(realpath ${SOURCE_CONANFILE})"
72+
$(error "LOCKFILE_SOURCE must contain superset of SOURCE_CONANFILE package and dependencies")
73+
endif
74+
LOCKFILE_OPTION := --lockfile="${BUILD_LOCKFILE}"
75+
${BUILD_LOCKFILE}: ${LOCKFILE_SOURCE} | ${BUILD_DIR} export
76+
# Create lockfile from LOCKFILE_SOURCE.
77+
#
78+
conan lock create --lockfile-out "${BUILD_LOCKFILE}" ${BUILD_TYPE_OPTION} ${CONAN_OPTIONS} --build -- "${LOCKFILE_SOURCE}" >/dev/null
79+
endif
80+
81+
# When using a --lockfile option, we cannot use profile, settings, options, env
82+
# or conf 'host' Conan options.
83+
ifneq "${LOCKFILE_OPTION}" ""
84+
ALL_OPTIONS := ${LOCKFILE_OPTION} ${CONAN_OPTIONS}
85+
else
86+
ALL_OPTIONS := ${BUILD_TYPE_OPTION} ${CONAN_OPTIONS}
87+
endif
88+
89+
# INFORMATIONAL TARGETS -------------------------------------------------------
7490
.DEFAULT: help
75-
.SILENT: help status info-name info-version info-channel info-fqn
76-
.PHONY: help status info-name info-version info-channel info-fqn
77-
help::
91+
.SILENT: help status parse-info info-name info-version info-channel info-fqn info
92+
.PHONY: help status parse-info info-name info-version info-channel info-fqn info
93+
help:: parse-info
7894
echo "Usage: make <target>"
7995
echo
8096
echo "The following targets define common operations with this package in"
@@ -83,6 +99,7 @@ help::
8399
echo "Available targets:"
84100
echo " help to show this help"
85101
echo " status to show status of package"
102+
echo " info to show detailed package info"
86103
echo
87104
echo " export to export recipe and sources [conan-cache]"
88105
echo " download to download or create package [conan-cache]"
@@ -103,6 +120,7 @@ help::
103120
echo " clean to remove build directory [in-source]"
104121
echo
105122
echo "Configuration:"
123+
echo " LOCKFILE_SOURCE: ${LOCKFILE_SOURCE}"
106124
echo " SOURCE_DIR: ${SOURCE_DIR}"
107125
echo " BUILD_DIR: ${BUILD_DIR}"
108126
echo " BUILD_POLICY: ${BUILD_POLICY}"
@@ -120,7 +138,19 @@ help::
120138
echo " GIT_COMMIT_HASH: ${GIT_COMMIT_HASH}"
121139
echo
122140

123-
status:
141+
parse-info: ${BUILD_LOCKFILE}
142+
# Fetch package information from Conan.
143+
#
144+
# This command takes long, so we won't run it by default. Instead, if any
145+
# target needs one of these variables, they should depend on this target
146+
# to ensure that these variables are set.
147+
#
148+
$(eval PACKAGE_INFO := $(shell conan info ${ALL_OPTIONS} "${PACKAGE_FQN}" --package-filter "${PACKAGE_FQN}" --paths | sed -r 's/$$/\\n/'))
149+
$(eval PACKAGE_ID := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *ID: *(.*)$$/\1/p'))
150+
$(eval PACKAGE_DIR := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *package_folder: *(.*)$$/\1/p'))
151+
$(eval PACKAGE_DATE := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *Creation date: *(.*)$$/\1/p'))
152+
153+
status: parse-info
124154
# Show the *approximate* status of each package in the cloe workspace.
125155
#
126156
# This lets you know whether a package is in editable mode or not,
@@ -151,6 +181,13 @@ info-channel:
151181
info-fqn:
152182
echo ${PACKAGE_FQN}
153183

184+
info: parse-info
185+
if [ -z "${PACKAGE_INFO}" ]; then \
186+
echo "Errors occurred, no output available."; \
187+
else \
188+
echo ${PACKAGE_INFO}; \
189+
fi
190+
154191
# CONFIGURATION TARGETS -------------------------------------------------------
155192
.PHONY: editable uneditable
156193

@@ -196,14 +233,10 @@ download:
196233
#
197234
# See: https://docs.conan.io/en/latest/mastering/policies.html
198235
#
199-
conan create . ${PACKAGE_FQN} \
200-
--build=never \
201-
${CONAN_OPTIONS} || \
202-
conan create . ${PACKAGE_FQN} \
203-
--build=${BUILD_POLICY} --build=${PACKAGE_NAME} \
204-
${CONAN_OPTIONS}
236+
conan create . ${PACKAGE_FQN} --build=never ${ALL_OPTIONS} || \
237+
conan create . ${PACKAGE_FQN} --build=${BUILD_POLICY} --build=${PACKAGE_NAME} ${ALL_OPTIONS}
205238

206-
package:
239+
package: ${BUILD_LOCKFILE}
207240
# Build the package in Conan cache unconditionally.
208241
#
209242
# Conan will retrieve and build all dependencies based on the build policy.
@@ -212,29 +245,24 @@ package:
212245
# See: https://docs.conan.io/en/latest/mastering/policies.html
213246
#
214247
conan create . ${PACKAGE_FQN} \
215-
--build=${BUILD_POLICY} --build=${PACKAGE_NAME} \
216-
${CONAN_OPTIONS}
248+
--build=${BUILD_POLICY} --build=${PACKAGE_NAME} ${ALL_OPTIONS}
217249

218-
package-all:
250+
package-all: ${BUILD_LOCKFILE}
219251
# Build the package in Conan cache unconditionally.
220252
#
221253
# Conan will retrieve and build all dependencies unconditionally.
222254
# Note that this cannot be called if the package is currently in editable mode.
223255
#
224-
conan create . ${PACKAGE_FQN} \
225-
--build \
226-
${CONAN_OPTIONS}
256+
conan create . ${PACKAGE_FQN} --build ${ALL_OPTIONS}
227257

228-
package-outdated:
258+
package-outdated: ${BUILD_LOCKFILE}
229259
# Build the package in Conan cache if it is outdated.
230260
#
231261
# Note that this does not take dependencies of ${PACKAGE_NAME} into account.
232262
# Rebuilds will occur if package info has changed or a hash of the source
233263
# code changes. Timestamps are not taken into account.
234264
#
235-
conan create . ${PACKAGE_FQN} \
236-
--build=outdated \
237-
${CONAN_OPTIONS}
265+
conan create . ${PACKAGE_FQN} --build=outdated ${ALL_OPTIONS}
238266

239267
purge:
240268
# Remove all instances of this package in the Conan cache.
@@ -245,7 +273,7 @@ purge:
245273
#
246274
-conan remove -f ${PACKAGE_FQN}
247275

248-
list:
276+
list: parse-info
249277
# List all files in the Conan cache package directory.
250278
#
251279
@tree ${PACKAGE_DIR}
@@ -255,13 +283,12 @@ list:
255283
all: ${SOURCE_DIR} ${BUILD_CONANINFO}
256284
# Build the package in-source.
257285
#
258-
mkdir -p ${BUILD_DIR}
259-
conan build . --source-folder=${SOURCE_DIR} --build-folder=${BUILD_DIR}
286+
conan build . --source-folder="${SOURCE_DIR}" --build-folder="${BUILD_DIR}"
260287

261288
clean:
262289
# Clean the build directory and Python cache files.
263290
#
264-
rm -rf ${BUILD_DIR}
291+
rm -rf "${BUILD_DIR}"
265292
rm -rf __pycache__
266293
if ${CLEAN_SOURCE_DIR}; then \
267294
rm -rf ${SOURCE_DIR}; \
@@ -276,8 +303,8 @@ test:
276303
#
277304
# If no tests are available, this will simply return true.
278305
#
279-
@if [ -f ${BUILD_DIR}/CTestTestfile.cmake ]; then \
280-
cd ${BUILD_DIR} && ctest; \
306+
@if [ -f "${BUILD_DIR}"/CTestTestfile.cmake ]; then \
307+
cd "${BUILD_DIR}" && ctest; \
281308
else \
282309
true; \
283310
fi
@@ -290,8 +317,8 @@ export-pkg:
290317
# binaries available to Conan but not the source.
291318
#
292319
# Note that this does not require the package to be editable.
293-
conan export-pkg . ${PACKAGE_FQN} \
294-
--build-folder=${BUILD_DIR}
320+
#
321+
conan export-pkg . ${PACKAGE_FQN} --build-folder="${BUILD_DIR}"
295322

296323
${SOURCE_DIR}:
297324
# Copy source to an external source directory.
@@ -300,23 +327,20 @@ ${SOURCE_DIR}:
300327
# SOURCE_DIR is identical to the current directory.
301328
#
302329
[ "$(shell readlink -f "${SOURCE_DIR}")" != "$(shell readlink -f .)" ]
303-
conan source . --source-folder=${SOURCE_DIR}
330+
conan source . --source-folder="${SOURCE_DIR}"
331+
332+
${BUILD_DIR}:
333+
mkdir -p "${BUILD_DIR}"
304334

305335
${SOURCE_CMAKELISTS}: ${SOURCE_DIR}
306336

307-
${BUILD_CONANINFO}: ${SOURCE_CONANFILE}
337+
${BUILD_CONANINFO}: ${SOURCE_CONANFILE} ${BUILD_DIR} ${BUILD_LOCKFILE}
308338
# Install package dependencies and prepare in-source build.
309339
#
310-
mkdir -p ${BUILD_DIR}
311-
conan install . ${PACKAGE_FQN} \
312-
--install-folder=${BUILD_DIR} \
313-
-s ${PACKAGE_NAME}:build_type=${BUILD_TYPE} \
314-
--build=${BUILD_POLICY} \
315-
${CONAN_OPTIONS}
340+
conan install . ${PACKAGE_FQN} --install-folder="${BUILD_DIR}" --build=${BUILD_POLICY} ${ALL_OPTIONS}
316341
touch ${BUILD_CONANINFO}
317342

318-
${BUILD_CMAKECACHE}: ${BUILD_CONANINFO} ${SOURCE_CMAKELISTS}
343+
${BUILD_CMAKECACHE}: ${SOURCE_CMAKELISTS} ${BUILD_CONANINFO}
319344
# Configure in-source build with CMake.
320345
#
321-
mkdir -p ${BUILD_DIR}
322-
conan build --configure . --source-folder=${SOURCE_DIR} --build-folder=${BUILD_DIR}
346+
conan build --configure . --source-folder="${SOURCE_DIR}" --build-folder="${BUILD_DIR}"

0 commit comments

Comments
 (0)