Skip to content

Commit

Permalink
Improve the conan to build flow.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmarrec committed Apr 16, 2024
1 parent c6dd282 commit 5fe2f54
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 14 deletions.
116 changes: 107 additions & 9 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,101 @@
# Building with conan v2

Check you have conan v2, and add the nrel-v2 remote to grab ruby and swig/4.1.1
Check you have `conan >= 2`, and add the `nrel-v2` remote to grab `ruby` and `swig/4.1.1`.

```shell
conan --version
conan remote add -f nrel-v2 http://conan.openstudio.net/artifactory/api/conan/conan-v2
```

## Install the conan dependencies into a build folder

```shell
conan install . --output-folder=../OS-build-release-v2 --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Release
cd ../OS-build-release-v2
conan install . --output-folder=../OS-build-release --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Release
```

You can also do another configuration, such as `Debug`, `RelWithDeb`, etc

```shell
conan install . --output-folder=../OS-build --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Debug
```

You'll have the `conan-release` and `conan-debug` CMake Presets in the root folder. Do `cmake --list-presets` to list the available presets (which are in `CMakeUserPresets.json`)

*Side note:* If you want a specific configure option (such as a build folder in Release mode where you build with `-DBUILD_CSHARP_BINDINGS:BOOL=ON`) in a different build dir for the same source dir, you probably will need to go and edit the `<build_dir>/CMakePresets.json` to rename it to another configuration name so it does not clash with the preset `conan-release`

## CMake Configure and build

### With presets

#### Why are Presets recommended

The recommend flow is to use [CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html).

If you notice the messages printed to the console when you run the `conan install` command from above,
you'll see that the `conanfile` actually defines common build variables for you already,
such as defining which `CPack` Generators to use depending on your target platform, trying to infer the `Python_ROOT_DIR` etc

<pre><font color="#75507B"><b>conanfile.py:</b></font> <font color="#75507B"><b>Calling generate()</b></font>
conanfile.py: Generators folder: /path/to/OS-build-release
conanfile.py: Setting PYTHON_VERSION and Python_ROOT_DIR from your current python: 3.8.13, &apos;/home/julien/.pyenv/versions/3.8.13&apos;
conanfile.py: CMakeToolchain generated: conan_toolchain.cmake
conanfile.py: Preset &apos;conan-release&apos; added to CMakePresets.json. Invoke it manually using &apos;cmake --preset conan-release&apos; if using CMake&gt;=3.23
conanfile.py: If your CMake version is not compatible with CMakePresets (&lt;3.23) call cmake like:
cmake &lt;path&gt; -G Ninja -DCMAKE_TOOLCHAIN_FILE=/path/to/OS-build-release/conan_toolchain.cmake \
-DBUILD_CLI=ON -DBUILD_RUBY_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=ON \
-DBUILD_PYTHON_PIP_PACKAGE=OFF -DBUILD_TESTING=ON -DBUILD_BENCHMARK=ON \
-DCPACK_BINARY_TGZ=ON -DCPACK_BINARY_IFW=OFF -DCPACK_BINARY_DEB=ON -DCPACK_BINARY_NSIS=OFF \
-DCPACK_BINARY_RPM=OFF -DCPACK_BINARY_STGZ=OFF -DCPACK_BINARY_TBZ2=OFF \
-DCPACK_BINARY_TXZ=OFF -DCPACK_BINARY_TZ=OFF \
-DPYTHON_VERSION=3.8.13 -DPython_ROOT_DIR=/home/julien/.pyenv/versions/3.8.13 \
-DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release
conanfile.py: CMakeToolchain generated: CMakePresets.json
conanfile.py: CMakeToolchain generated: ../OpenStudio/CMakeUserPresets.json
<font color="#75507B"><b>conanfile.py:</b></font> <font color="#75507B"><b>Generating aggregated env files</b></font>
conanfile.py: Generated aggregated env files: [&apos;conanbuild.sh&apos;, &apos;conanrun.sh&apos;]
<font color="#4E9A06"><b>Install finished successfully</b></font>
</pre>

**Note that this is also supported by Visual Studio (MSVC)**.

#### Configure and build with Presets

Run these commands from the **source** directory (`OpenStudio/`).

```shell
cmake --preset conan-release [any_futher_configuration_options]
```

Example:

```
cmake --preset conan-release \
-DBUILD_PYTHON_BINDINGS:BOOL=ON -DBUILD_PYTHON_PIP_PACKAGE:BOOL=ON \
-DPYTHON_VERSION=3.8.13 -DPython_ROOT_DIR:PATH=$HOME/.pyenv/versions/3.8.13/ \
-DBUILD_CSHARP_BINDINGS:BOOL=ON
```

Building

```
cmake --build --preset conan-release
```

### Atlernatively: manual CMake

First, go to the **build** directory, and **activate the conan build environment**.

```shell
cd ../OS-build-release
# Unix
. ./conanbuild.sh
# Windows
call conanbuild.bat
```

Still in the build directory, run cmake, but do pass the `CMAKE_TOOLCHAIN_FILE`

# Run cmake, but do pass the CMAKE_TOOLCHAIN_FILE
#/OS-build-release-v2 %
```
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE:STRING=Release \
-DBUILD_TESTING:BOOL=ON -DCPACK_BINARY_TGZ:BOOL=ON -DCPACK_BINARY_DEB:BOOL=ON \
-DCPACK_BINARY_IFW:BOOL=OFF -DCPACK_BINARY_NSIS:BOOL=OFF -DCPACK_BINARY_RPM:BOOL=OFF -DCPACK_BINARY_STGZ:BOOL=OFF \
Expand All @@ -23,17 +104,34 @@ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE:S
-DPYTHON_VERSION=3.8.13 -DPython_ROOT_DIR:PATH=/home/julien/.pyenv/versions/3.8.13/ \
-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON \
../OpenStudio
```

# You can deactivate now if you want
You can deactivate now if you want

```
# Unix
. ./deactivate_conanbuild.sh
# Windows
call deactivate_conanbuild.bat
```

Note that is also makes cmake presets, at root of OpenStudio, you can also try `cmake --list-presets`. To configure `cmake --preset conan-release`; to build `cmake --build --preset conan-release`.
# Full Example

```
git clone [email protected]/NREL/OpenStudio.git
cd OpenStudio
conan install . --output-folder=../OS-build-release --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Release
cmake --preset conan-release
cmake --build --preset conan-release
```

# Updating the Conan Lockfile

If you want to update a dependency in the conan.lock, just delete the line, and use this:
If you want to update a dependency in the `conan.lock`, just delete the line, and use this:


```shell
conan install . --output-folder=../OS-build-release-v2 --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Release --lockfile-partial --lockfile-out=conan.lock
conan install . --output-folder=../OS-build-release --build=missing \
-c tools.cmake.cmaketoolchain:generator=Ninja -s compiler.cppstd=20 -s build_type=Release \
--lockfile-partial --lockfile-out=conan.lock
```
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
message(STATUS "Using CMake ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 3.20.0)
cmake_minimum_required(VERSION 3.23.0)
cmake_policy(SET CMP0048 NEW)

set(CMAKE_CXX_STANDARD 20)
Expand Down
53 changes: 49 additions & 4 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import sys
from pathlib import Path
from conan import ConanFile
from conan.tools.apple import is_apple_os
from conan.tools.cmake import CMakeToolchain

class CompressorRecipe(ConanFile):
required_conan_version = ">=2.0"

class OpenStudioBuildRecipe(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain", "CMakeDeps"
generators = "CMakeDeps" # CMakeToolchain explicitly instantiated

options = {
"with_testing": [True, False],
Expand Down Expand Up @@ -45,5 +50,45 @@ def requirements(self):
self.requires("benchmark/1.8.3")


#def build_requirements(self):
# self.tool_requires("cmake/3.22.6")
# def build_requirements(self):
# self.tool_requires("cmake/3.22.6")

def generate(self):
tc = CMakeToolchain(self)

tc.cache_variables["BUILD_CLI"] = True
tc.cache_variables["BUILD_RUBY_BINDINGS"] = True
tc.cache_variables["BUILD_PYTHON_BINDINGS"] = True
tc.cache_variables["BUILD_PYTHON_PIP_PACKAGE"] = False

tc.cache_variables["BUILD_TESTING"] = bool(self.options.with_testing)
tc.cache_variables["BUILD_BENCHMARK"] = bool(self.options.with_benchmark)

tc.cache_variables["CPACK_BINARY_TGZ"] = True
tc.cache_variables["CPACK_BINARY_IFW"] = False
tc.cache_variables["CPACK_BINARY_DEB"] = False
if self.settings.build_type == "Release":
if is_apple_os(self) or self.settings.os == "Windows":
tc.cache_variables["CPACK_BINARY_IFW"] = True
else:
tc.cache_variables["CPACK_BINARY_DEB"] = True
tc.cache_variables["CPACK_BINARY_NSIS"] = False
tc.cache_variables["CPACK_BINARY_RPM"] = False
tc.cache_variables["CPACK_BINARY_STGZ"] = False
tc.cache_variables["CPACK_BINARY_TBZ2"] = False
tc.cache_variables["CPACK_BINARY_TXZ"] = False
tc.cache_variables["CPACK_BINARY_TZ"] = False

v = sys.version_info
if (v.major, v.minor) == (3, 8):
python_version = f"{v.major}.{v.minor}.{v.micro}"
self.output.info(f"Setting PYTHON_VERSION and Python_ROOT_DIR from your current python: {python_version}, '{sys.base_prefix}'")
tc.cache_variables["PYTHON_VERSION"] = python_version
tc.cache_variables["Python_ROOT_DIR"] = Path(sys.base_prefix)
else:
self.output.warning(
"Your current python is not in the 3.8.x range, which is what we target.\n"
"You'll need to pass it properly when configuring CMake\n"
"via -DPYTHON_VERSION:STRING='3.8.xx' and -DPython_ROOT_DIR:PATH='/path/to/python3.8/'"
)
tc.generate()

0 comments on commit 5fe2f54

Please sign in to comment.