Skip to content

Commit

Permalink
Merge pull request #8 from xandox/release-debug-build
Browse files Browse the repository at this point in the history
support --build-type argument for debug/release build
  • Loading branch information
d-krupke authored Dec 23, 2024
2 parents 84df993 + 3d1d2f9 commit e8c1bcb
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 38 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ of something, as we need to prioritize quite often.

## Changelog

- _1.3.0_ The Debug/Release will propagate to the conan profile. (thanks to @xandox)
- _1.2.0_ Workaround for Windows and MSVC found by Ramin Kosfeld (TU Braunschweig).
- _1.1.1_ Fixing problem if the conan default profile has been renamed via environment variable.
- _1.1.0_ conan is now called directly. This is kind of hacky, but circumvents problems with conan not being in the path if only installed for build.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ where = ["src"]

[project]
name = "skbuild_conan"
version = "v1.2.0"
version = "v1.3.0"
authors = [
{ name = "TU Braunschweig, IBR, Algorithms Group (Dominik Krupke)", email = "[email protected]" },
]
Expand Down
32 changes: 20 additions & 12 deletions src/skbuild_conan/conan_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from conan.cli.cli import Cli as ConanCli
from conan.api.conan_api import ConanAPI
import conan


class EnvContextManager:
"""
Expand All @@ -34,6 +36,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
else:
os.environ[key] = val


class ConanHelper:
"""
The ConanHelper is used for installing conan dependencies automatically
Expand All @@ -50,23 +53,27 @@ def __init__(
settings=None,
profile: str = "default",
env: typing.Optional[typing.Dict] = None,
build_type: str = "Release",
):
self.generator_folder = os.path.abspath(output_folder)
self.local_recipes = local_recipes if local_recipes else []
self.settings = settings if settings else {}
self.profile = profile
self.env = env
self.build_type = build_type
self.generator_folder = os.path.join(
os.path.abspath(output_folder), self.build_type.lower()
)
env = env if env else {}
self._default_profile_name = env.get("CONAN_DEFAULT_PROFILE",
os.environ.get("CONAN_DEFAULT_PROFILE", "default"))
self._default_profile_name = env.get(
"CONAN_DEFAULT_PROFILE", os.environ.get("CONAN_DEFAULT_PROFILE", "default")
)
if env:
self._log(f"Temporarily overriding environment variables: {env}")
self._check_conan_version()


def _log(self, msg: str):
print(f"[skbuild-conan] {msg}")

def _conan_cli(self, cmd: typing.List[str]) -> str:
printable_cmd = " ".join(cmd)
# color the command blue
Expand All @@ -88,9 +95,8 @@ def _conan_cli(self, cmd: typing.List[str]) -> str:
return out

def conan_version(self):
args = ["-v"]
version = self._conan_cli(args).split(" ")[-1]
return version
return conan.__version__


def _check_conan_version(self):
self._log("Checking Conan version...")
Expand Down Expand Up @@ -130,7 +136,7 @@ def install_from_paths(self, paths: typing.List[str]):
"-pr",
self.profile,
"-s",
"build_type=Release",
f"build_type={self.build_type}",
"--build=missing",
]
self._conan_cli(cmd)
Expand All @@ -150,7 +156,7 @@ def create_profile(self):
self._log("Profile already exists.")
return # Profile already exists
cmd = ["profile", "detect", "--name", self.profile]
self._conan_cli( cmd)
self._conan_cli(cmd)

def install(
self, path: str = ".", requirements: typing.Optional[typing.List[str]] = None
Expand All @@ -161,7 +167,7 @@ def install(
self.create_profile()
self.install_from_paths(self.local_recipes)
self._log("Preparing conan dependencies for building package...")
cmd = [ "install"]
cmd = ["install"]
if requirements:
# requirements passed from Python directly
for req in requirements:
Expand All @@ -179,7 +185,9 @@ def install(
cmd += ["-g", "CMakeDeps", "-g", "CMakeToolchain"]
# profile
cmd += ["-pr", self.profile]
self._conan_cli( cmd)
# build type
cmd += ["-s", f"build_type={self.build_type}"]
self._conan_cli(cmd)

def cmake_args(self):
"""
Expand Down
68 changes: 43 additions & 25 deletions src/skbuild_conan/setup_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ def setup(
:return: The returned values of the wrapped setup.
"""

build_type = parse_args()

# Workaround for mismatching ABI with GCC on Linux
conan_profile_settings = conan_profile_settings if conan_profile_settings else {}
cmake_args = cmake_args if cmake_args else []
if platform.system( )== "Linux" and "compiler.libcxx" not in conan_profile_settings:
if platform.system() == "Linux" and "compiler.libcxx" not in conan_profile_settings:
print(
'[skbuild-conan] Using workaround and setting "compiler.libcxx=libstdc++11"'
)
Expand All @@ -70,7 +72,9 @@ def setup(
# Setting the policy to NEW means:
# CMAKE_MSVC_RUNTIME_LIBRARY is used to initialize the MSVC_RUNTIME_LIBRARY property on all targets.
# If CMAKE_MSVC_RUNTIME_LIBRARY is not set, CMake defaults to choosing a runtime library value consistent with the current build type.
print("[skbuild-conan] Using workaround for Windows and MSVC by enforcing policy CMP0091 to NEW")
print(
"[skbuild-conan] Using workaround for Windows and MSVC by enforcing policy CMP0091 to NEW"
)
cmake_args += ["-DCMAKE_POLICY_DEFAULT_CMP0091=NEW"]
try:
conan_helper = ConanHelper(
Expand All @@ -79,34 +83,25 @@ def setup(
settings=conan_profile_settings,
profile=conan_profile,
env=conan_env,
build_type=build_type,
)
conan_helper.install(path=conanfile, requirements=conan_requirements)
cmake_args += conan_helper.cmake_args()

except Exception as e:
# Setup could not be completed. Give debugging information in red and abort.
print(f"\033[91m[skbuild-conan] {e}\033[0m")
print(
"\033[91m[skbuild-conan] skbuild_conan failed to install dependencies.\033[0m"
)
print("There are several reasons why this could happen:")
print(
"1. A mistake by the developer of the package you are trying to install."
+ " Maybe a wrongly defined dependency?"
)
print("2. An unexpected conflict with an already existing conan configuration.")
print("3. A rare downtime of the conan package index.")
print(
"4. A bug in skbuild_conan. Please report it at https://github.com/d-krupke/skbuild-conan/issues"
)
print(
"5. Your system does not have a C++-compiler installed. Please install one."
)
print(
"6. You conan profile is not configured correctly. "
+ f"Please check `~/.conan2/profiles/{conan_profile}`. "
+ "You can also try to just delete `./conan2/` to reset conan completely."
)
error_message = f"""
\033[91m[skbuild-conan] {e}\033[0m
\033[91m[skbuild-conan] skbuild_conan failed to install dependencies.\033[0m
There are several reasons why this could happen:
1. A mistake by the developer of the package you are trying to install. Maybe a wrongly defined dependency?
2. An unexpected conflict with an already existing conan configuration.
3. A rare downtime of the conan package index.
4. A bug in skbuild_conan. Please report it at https://github.com/d-krupke/skbuild-conan/issues
5. Your system does not have a C++-compiler installed. Please install one.
6. Your conan profile is not configured correctly. Please check `~/.conan2/profiles/{conan_profile}`. You can also try to just delete `./conan2/` to reset conan completely.
"""
print(error_message)
raise e
print(
"[skbuild-conan] Setup of conan dependencies finished. cmake args:", cmake_args
Expand All @@ -115,3 +110,26 @@ def setup(
"[skbuild-conan] See https://github.com/d-krupke/skbuild-conan if you encounter problems."
)
return wrapped_setup(cmake_args=cmake_args, **kwargs)


def parse_args() -> str:
"""
This function parses the command-line arguments ``sys.argv`` and returns
build_type as a string. Release or Debug.
This is consistent with the interface of the underlying scikit-build, which
will also read this argument and change its behavior accordingly.
"""

import argparse

parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
"--build-type",
default="Release",
choices=["Release", "Debug"],
help="specify the CMake build type (e.g. Debug or Release)",
)

args, _ = parser.parse_known_args()
return args.build_type

0 comments on commit e8c1bcb

Please sign in to comment.