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

Qt toolchain #29

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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: 20 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#############################
## Terminal output options ##
#############################

# Print debug information while finding toolchains for a rule
build --toolchain_resolution_debug

# If a command fails, print out the full command line
build --verbose_failures

# Display the subcommands used to generate each target
# Uncomment to see the effect, if you have it allways enabled it will increase quite a log the logs
# build --subcommands=pretty_print

#####################
## Caching options ##
#####################

# Enable disk cache
build --disk_cache=~/.bazel/disk_cache/
77 changes: 55 additions & 22 deletions qt_configure.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,70 @@ def qt_autoconf_impl(repository_ctx):
repository_ctx: repository context
"""
os_name = repository_ctx.os.name.lower()
is_linux_machine = False
if os_name.find("windows") != -1:
if os_name.find("windows") == -1 and os_name.find("linux") == -1:
fail("Unsupported OS: %s" % os_name)
is_linux_machine = os_name.find("windows") == -1

# Location of the different Qt artifacts on Linux system installed standalone as well as Windows
# Qt includes
# <location>/include
#
# Qt libraries
# <location>/lib
#
# uic, rcc, moc
# <location>/bin

# Location of the different Qt artifacts on Linux system installed with apt
# Qt includes
# /usr/include/x86_64-linux-gnu/qt5
#
# Qt libraries
# /lib/x86_64-linux-gnu/
# /usr/lib/x86_64-linux-gnu/
#
# uic, rcc, moc
# /usr/bin/

# If QT_DIR is defined and it exists, we consider that it is a standalone installation
# Only in the case that is linux and QT_DIR is not defined it is considerd a none standalone
# installation
qt_dir_path = _get_env_var(repository_ctx, "QT_DIR", None)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to not use https://docs.bazel.build/versions/main/skylark/lib/dict.html#get ? It is available at least from 1.0 onward.

Because this uses QT_DIR, I think repository_rule() down below should set environ = ["QT_DIR"] https://docs.bazel.build/versions/main/skylark/lib/globals.html#repository_rule

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it is right now you are right that get could be used. What happened is that the code evolved. Initially getting the variable was done in a case insensitive way this is why get could have not been used. This should be redone and make clear what behavior is wanted, here the full discussion: #17 (comment)

is_standalone = qt_dir_path != None and repository_ctx.path(qt_dir_path).exists
if not is_linux_machine:
# Inside this folder, in Windows you can find include, lib and bin folder
default_qt_path = "C:\\\\Qt\\\\5.9.9\\\\msvc2017_64\\\\"
elif os_name.find("linux") != -1:
is_linux_machine = True
# In Linux, this is the equivalent to the include folder, the binaries are located in
# /usr/bin/
# This would be the path if it has been installed using a package manager
default_qt_path = "/usr/include/x86_64-linux-gnu/qt5"
if not repository_ctx.path(default_qt_path).exists:
default_qt_path = "/usr/include/qt"
qt_prefix = default_qt_path
if is_standalone:
qt_prefix = qt_dir_path
qt_includes = qt_prefix + "\\\\include"
qt_libs = qt_prefix + "\\\\lib"
qt_bins = qt_prefix + "\\\\bin"
else:
fail("Unsupported OS: %s" % os_name)

if repository_ctx.path(default_qt_path).exists:
print("Installation available on the default path: ", default_qt_path)
if is_standalone:
qt_prefix = qt_dir_path
qt_includes = qt_prefix + "/include"
qt_libs = qt_prefix + "/lib"
qt_bins = qt_prefix + "/bin"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello, curious about this part, how can we pass bin path to qt_toolchain rule to get moc, rcc and uic path?

else:
default_qt_include_path = "/usr/include/x86_64-linux-gnu/qt5"
if repository_ctx.path(default_qt_include_path).exists:
qt_includes = default_qt_include_path
else:
qt_includes = "/usr/include/qt"
qt_libs = "/lib/x86_64-linux-gnu/"
qt_bins = "/usr/bin/"

qt_path = _get_env_var(repository_ctx, "QT_DIR", default_qt_path)
if qt_path != default_qt_path:
print("However QT_DIR is defined and will be used: ", qt_path)
# In Linux in case that we have a standalone installation, we need to provide the path inside the include folder
qt_path_with_include = qt_path + "/include"
if is_linux_machine and repository_ctx.path(qt_path_with_include).exists:
qt_path = qt_path_with_include
print("Qt installation found in:")
print("Qt includes: ", qt_includes)
print("Qt libs: ", qt_libs)
print("Qt bins: ", qt_bins)

repository_ctx.file("BUILD", "# empty BUILD file so that bazel sees this as a valid package directory")
repository_ctx.template(
"local_qt.bzl",
repository_ctx.path(Label("//:BUILD.local_qt.tpl")),
{"%{path}": qt_path},
{"%{path}": qt_includes},
)

qt_autoconf = repository_rule(
Expand Down
77 changes: 77 additions & 0 deletions qt_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
QtSDK = provider(
doc = "Contains information about the Qt SDK used in the toolchain",
fields = {
"qt_include_path": "Path where the Qt include files are located",
"qt_lib_path": "Path where the Qt libraries are located",
"rcc_path": "Path where the rcc binary is located",
"moc_path": "Path where the moc binary is located",
"uic_path": "Path where the uic binary is located",
},
)

def _qt_toolchain_impl(ctx):
toolchain_info = platform_common.ToolchainInfo(
qt_sdk = QtSDK(
qt_include_path = ctx.attr.qt_include_path,
qt_lib_path = ctx.attr.qt_lib_path,
rcc_path = ctx.attr.rcc_path,
moc_path = ctx.attr.moc_path,
uic_path = ctx.attr.uic_path,
),
)
return [toolchain_info]

qt_toolchain = repository_rule(
implementation = _qt_toolchain_impl,
attrs = {
"qt_include_path": attr.string(),
"qt_lib_path": attr.string(),
"rcc_path": attr.string(),
"moc_path": attr.string(),
"uic_path": attr.string(),
},
)

def declare_windows_toolchain():
toolchain_name = "qt_windows_amd64"
toolchain_impl_name = toolchain_name + "_impl"
qt_toolchain(
name = toolchain_impl_name,
tags = ["manual"],
)
native.toolchain(
name = toolchain_name,
exec_compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
target_compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
toolchain = ":" + toolchain_impl_name,
)

def declare_linux_toolchain():
toolchain_name = "qt_linux_amd64"
toolchain_impl_name = toolchain_name + "_impl"
qt_toolchain(
name = toolchain_impl_name,
)
native.toolchain(
name = toolchain_name,
exec_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
target_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
toolchain = ":" + toolchain_impl_name,
)

def declare_toolchains():
declare_linux_toolchain()
declare_windows_toolchain()
native.register_toolchains(":qt_linux_amd64", ":qt_windows_amd64")