platform dependent linker flags in bazel (for glut) - cross-platform

I am trying to build the c++ app with glut using bazel. It should work on both macos and linux. Now the problem is that on macos it requires passing "-framework OpenGL", "-framework GLUT" to linker flags, while on linux I should probably do soemthing like
cc_library(
name = "glut",
srcs = glob(["local/lib/libglut*.dylib", "lib/libglut*.so"]),
...
in glut.BUILD.
So the question is
1. How to provide platform-dependent linker options to cc_library rules in general?
2. And in particular how to link to glut in platform-independent way using bazel?

You can do this using the Bazel select() function. Something like this might work:
config_setting(
name = "linux_x86_64",
values = {"cpu": "k8"},
visibility = ["//visibility:public"],
)
config_setting(
name = "darwin_x86_64",
values = {"cpu": "darwin_x86_64"},
visibility = ["//visibility:public"],
)
cc_library(
name = "glut",
srcs = select({
":darwin_x86_64": [],
":linux_x86_64": glob(["local/lib/libglut*.dylib", "lib/libglut*.so"]),
}),
linkopts = select({
":darwin_x86_64": [
"-framework OpenGL",
"-framework GLUT"
],
":linux_x86_64": [],
})
...
)
Dig around in the Bazel github repository, it's got some good real world examples of using select().

I had a similar problem but with picking the right compiler depending on the platform and #zlalanne's solution didn't work for me. After 2 days of frustration, I finally found the following solution:
config_setting (
name = "darwin",
constraint_values = [ "#bazel_tools//platforms:osx" ]
)
config_setting (
name = "windows",
constraint_values = [ "#bazel_tools//platforms:windows" ]
)
I didn't have any need for linux, but adding this to your BUILD file should work:
config_setting (
name = "linux",
constraint_values = [ "#bazel_tools//platforms:linux" ]
)
Use ":darwin", ":windows" and ":linux" in your selects and you should have a solution that works.

Related

Build a CMake project with Nix

I'm trying to make a derivation from fokus (a KDE plasmoid).
I have a default.nix which looks like:
{ mkDerivation, lib, fetchFromGitLab, cmake, extra-cmake-modules
, plasma-framework
, qt5 }:
let
version = "1.5.4";
repo = fetchFromGitLab {
owner = "divinae";
repo = "focus-plasmoid";
rev = "v${version}";
sha256 = "19nndmqfzdcg7lzcifxa17m2mx85dlf4m2wxzr72gf78h4yj0ahv";
};
in
mkDerivation rec {
inherit version;
pname = "fokus";
src = "${repo}/packages";
dontUnpack = true;
buildInputs = [
plasma-framework
qt5.qtbase
];
nativeBuildInputs = [ cmake extra-cmake-modules ];
meta = with lib; {
description = "Simple pomodoro timer plasmoid";
homepage = "https://store.kde.org/p/1308861/";
license = licenses.gpl3Only;
maintainers = with maintainers; [ ];
platforms = platforms.unix;
};
}
I also added to all-packages:
fokus-plasma-applet = libsForQt5.callPackage ../applications/misc/fokus-plasma-applet { };
The thing is, I have only find few examples in nixpkgs, and I do not see what to do with this error (since CMakeLists.txt is effectively in /package):
building '/nix/store/c21h5667abmj4v0ci4n51ckvkxvc23gk-fokus-1.5.4.drv'...
qtPreHook
patching sources
configuring
fixing cmake files...
cmake flags: -DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_BUILD_RPATH=ON -DBUILD_TESTING=OFF -DCMAKE_INSTALL_LOCALEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/locale -DCMAKE_INSTALL_LIBEXECDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/libexec -DCMAKE_INSTALL_LIBDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib -DCMAKE_INSTALL_DOCDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/doc/fokus -DCMAKE_INSTALL_INFODIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/info -DCMAKE_INSTALL_MANDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/man -DCMAKE_INSTALL_OLDINCLUDEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/include -DCMAKE_INSTALL_INCLUDEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/include -DCMAKE_INSTALL_SBINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/sbin -DCMAKE_INSTALL_BINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/bin -DCMAKE_INSTALL_NAME_DIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib -DCMAKE_POLICY_DEFAULT_CMP0025=NEW -DCMAKE_OSX_SYSROOT= -DCMAKE_FIND_FRAMEWORK=LAST -DCMAKE_STRIP=/nix/store/4g5fidyk19akng9n91cql60ylrjq93s6-gcc-wrapper-10.3.0/bin/strip -DCMAKE_RANLIB=/nix/store/ffcrrgb6k5h7crr93dj90bi9fy1jvj16-binutils-2.35.1/bin/ranlib -DCMAKE_AR=/nix/store/ffcrrgb6k5h7crr93dj90bi9fy1jvj16-binutils-2.35.1/bin/ar -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_INSTALL_PREFIX=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4 -DKDE_INSTALL_EXECROOTDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4 -DKDE_INSTALL_BINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/bin -DKDE_INSTALL_SBINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/sbin -DKDE_INSTALL_LIBDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib -DKDE_INSTALL_LIBEXECDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/libexec -DKDE_INSTALL_CMAKEPACKAGEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib/cmake -DKDE_INSTALL_INCLUDEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/include -DKDE_INSTALL_LOCALSTATEDIR=/var -DKDE_INSTALL_DATAROOTDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share -DKDE_INSTALL_DATADIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share -DKDE_INSTALL_DOCBUNDLEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/doc/HTML -DKDE_INSTALL_KCFGDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/config.kcfg -DKDE_INSTALL_KCONFUPDATEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/kconf_update -DKDE_INSTALL_KSERVICES5DIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/kservices5 -DKDE_INSTALL_KSERVICETYPES5DIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/kservicetypes5 -DKDE_INSTALL_KXMLGUI5DIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/kxmlgui5 -DKDE_INSTALL_KNOTIFY5RCDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/knotifications5 -DKDE_INSTALL_ICONDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/icons -DKDE_INSTALL_LOCALEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/locale -DKDE_INSTALL_SOUNDDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/sounds -DKDE_INSTALL_TEMPLATEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/templates -DKDE_INSTALL_WALLPAPERDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/wallpapers -DKDE_INSTALL_APPDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/applications -DKDE_INSTALL_DESKTOPDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/desktop-directories -DKDE_INSTALL_MIMEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/mime/packages -DKDE_INSTALL_METAINFODIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/appdata -DKDE_INSTALL_MANDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/man -DKDE_INSTALL_INFODIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/info -DKDE_INSTALL_DBUSDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/dbus-1 -DKDE_INSTALL_DBUSINTERFACEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/dbus-1/interfaces -DKDE_INSTALL_DBUSSERVICEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/dbus-1/services -DKDE_INSTALL_DBUSSYSTEMSERVICEDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/share/dbus-1/system-services -DKDE_INSTALL_SYSCONFDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/etc -DKDE_INSTALL_CONFDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/etc/xdg -DKDE_INSTALL_AUTOSTARTDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/etc/xdg/autostart -DKDE_INSTALL_QTPLUGINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib/qt-5.15.2/plugins -DKDE_INSTALL_PLUGINDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib/qt-5.15.2/plugins -DKDE_INSTALL_QMLDIR=/nix/store/5rdpaqmcj9hrpwdcnprr0zm51659mp08-fokus-1.5.4/lib/qt-5.15.2/qml
CMake Error: The source directory "/build" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
builder for '/nix/store/c21h5667abmj4v0ci4n51ckvkxvc23gk-fokus-1.5.4.drv' failed with exit code 1
cannot build derivation '/nix/store/b9jhnh8bix892wql3qifvgf742lq41v9-system-path.drv': 1 dependencies couldn't be built
cannot build derivation '/nix/store/3n3mwi7vqmnkng6r8kpa9881xdgcd253-nixos-system-looping-21.11pre328987.c935f5e0add.drv': 1 dependencies couldn't be built
error: build of '/nix/store/3n3mwi7vqmnkng6r8kpa9881xdgcd253-nixos-system-looping-21.11pre328987.c935f5e0add.drv' failed

Import cmocka library in Bazel Build

I'm using cmocka with Bazel and I want to import cmocka library in my test files (for c embedded code) like <cmocka.h> but I'm always getting: cmocka.h: No such file or directory.
my Build is:
cc_library(
name = "mock",
srcs = ["mock_i2c.c"],
deps = [":src"],
visibility = ["//visibility:public"],
linkstatic = True,
copts = ["-I test/cmocka/include"],
)
There is a includes attribute for that case, also you need to add your headers to hdrs attribute:
cc_library(
name = "mock",
srcs = ["mock_i2c.c"],
deps = [":src"],
hdrs = glob(["test/cmocka/include/**/*.h"]),
visibility = ["//visibility:public"],
linkstatic = True,
includes= ["test/cmocka/include"],
)

How can I include kotlin-reflect in the classpath of the Bazel compiler?

I'm trying to get moshi-kotlin-codegen to run on some Kotlin code via Bazel. After a lot of trial and error, I managed to get the plugin to run, but it's failing due to not having kotlin-reflect on the classpath. This is needed by kotlinpoet, which is used by Moshi, so it should be transitively included, AFAICT. However, even explicitly stating the dependency in the BUILD.bazel file for moshi-kotlin-codegen doesn't make it work, so I can only assume it gets filtered out somewhere.
The WORKSPACE file:
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_jvm_external",
sha256 = "62133c125bf4109dfd9d2af64830208356ce4ef8b165a6ef15bbff7460b35c3a",
strip_prefix = "rules_jvm_external-3.0",
url = "https://github.com/bazelbuild/rules_jvm_external/archive/3.0.zip",
)
load("#rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.github.ajalt:clikt:2.6.0",
"org.eclipse.jgit:org.eclipse.jgit:5.7.0.202003090808-r",
"io.github.microutils:kotlin-logging:1.7.8",
"ch.qos.logback:logback-classic:1.2.3",
"com.github.scribejava:scribejava-core:6.9.0",
"com.squareup.moshi:moshi:1.9.2",
"com.squareup.moshi:moshi-kotlin-codegen:1.9.2",
"org.kohsuke:github-api:1.108",
"com.github.ben-manes.caffeine:caffeine:2.8.2",
"javax.xml.bind:jaxb-api:2.3.1",
"org.junit.jupiter:junit-jupiter:5.6.0",
"org.junit.jupiter:junit-jupiter-params:5.6.0",
"com.google.truth:truth:1.0.1",
],
fetch_sources = True,
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
"https://jcenter.bintray.com/",
],
strict_visibility = True,
)
rules_kotlin_version = "legacy-1.4.0-rc3"
rules_kotlin_sha = "da0e6e1543fcc79e93d4d93c3333378f3bd5d29e82c1bc2518de0dbe048e6598"
http_archive(
name = "io_bazel_rules_kotlin",
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/%s/rules_kotlin_release.tgz" % rules_kotlin_version],
sha256 = rules_kotlin_sha,
)
load("#io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
kotlin_repositories()
kt_register_toolchains()
The BUILD.bazel for moshi-kotlin-codegen:
java_plugin(
name = "moshi_kotlin_codegen_plugin",
processor_class = "com.squareup.moshi.kotlin.codegen.JsonClassCodegenProcessor",
deps = [
"#maven//:com_squareup_moshi_moshi_kotlin_codegen",
],
generates_api = True,
visibility = ["//visibility:public"],
)
(I also tried adding a java_library and depending on that, no luck.)
The final BUILD file that tries to include it:
load("#io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_binary")
kt_jvm_binary(
name = "myproject",
srcs = glob([
"**/*.kt",
]),
main_class = "my.project.MainKt",
plugins = [
"//third_party/moshi_kotlin_codegen:moshi_kotlin_codegen_plugin",
],
deps = [
"#maven//:ch_qos_logback_logback_classic",
"#maven//:com_github_ajalt_clikt",
"#maven//:com_github_ben_manes_caffeine_caffeine",
"#maven//:com_github_scribejava_scribejava_core",
"#maven//:com_squareup_moshi_moshi",
"#maven//:io_github_microutils_kotlin_logging",
"#maven//:org_eclipse_jgit_org_eclipse_jgit",
"#maven//:org_kohsuke_github_api",
"#maven//:javax_xml_bind_jaxb_api",
],
)
The exception during the compilation:
Caused by: kotlin.jvm.KotlinReflectionNotSupportedError: Kotlin reflection implementation is not found at runtime. Make sure you have kotlin-reflect.jar in the classpath
at kotlin.jvm.internal.ClassReference.error(ClassReference.kt:79)
at kotlin.jvm.internal.ClassReference.getQualifiedName(ClassReference.kt:15)
at com.squareup.kotlinpoet.ClassNames.get(ClassName.kt:49)
at com.squareup.moshi.kotlinpoet.classinspector.elements.ElementsClassInspector.<clinit>(ElementsClassInspector.kt:493)
at com.squareup.moshi.kotlin.codegen.JsonClassCodegenProcessor.process(JsonClassCodegenProcessor.kt:99)
at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)
at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147)
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:980)
... 48 more
Turns out that this was indeed a bug. A fix is https://github.com/bazelbuild/rules_kotlin/pull/354.

Easiest way to set msbuild logging verbosity in fake?

I have a target that looks like this:
Target "builddotnetcode" (fun _ ->
!! "../Mercury.sln"
|> MSBuildRelease null "Clean,Build"
|> Log "MercuryBuild - Output: "
)
I want to simply set the verbosity in there somewhere. As far as I can tell from the docs you need to specify the Verbosity member of the MSBuildParams object. But build is the only MSBuildHelper function that provides a way to pass a MSBuildParams. Using build I then need to specify Configuration=Release property, the project list, and remove the pipeline to the Log. It seems like there ought to be a simpler way that does not cause me to redefine the entire task. Am I missing something?
So what i did is the following. The reason i did is it this was as I want to create a log file per solution file that I am building
let loggerConfig : list<MSBuildFileLoggerConfig> = [
{
Number = 1
Filename = Some (baseDir + name + "_build.log")
Verbosity = Some MSBuildVerbosity.Minimal
Parameters = Some [MSBuildLogParameter.Append]
}
]
let setParams defaults =
{ defaults with
Verbosity = Some MSBuildVerbosity.Minimal
Targets = ["Build"]
MaxCpuCount = Some (Some 4)
FileLoggers = Some loggerConfig
ToolsVersion = Some "12.0"
Properties =
[
"Optimize", "True"
"DebugSymbols", "True"
"Configuration", buildMode
]
}
Lastly the only msbuild task that I could see that will let you override the msbuilddefaults was standard build.
build setParams solution
|> DoNothing

FAKE build a project with unsafe flag

I am trying to build a solution where one of the projects needs to be build with the unsafe flag on, it is set correctly in the project however when building I get the error:
"Unsafe code may only appear if compiling with /unsafe"
This is my target at the moment
Target "CompileApp" (fun _ ->
!! #"**\*.csproj"
|> MSBuildRelease buildDir "Build"
|> Log "AppBuild-Output: "
)
I tried adding MsBuildParams but not sure how to use them yet (ie there doesnt seem to be an option in MsBuildRelease to add something like this
let setParams defaults =
{ defaults with
Verbosity = Some(Quiet)
Targets = ["Build"]
Properties =
[
"AllowUnsafeBlocks", "True"
"Configuration", "Release"
]
}
Also would the best option here be create two different targets for projects with safe and unsafe code, of would there be a better way?
I found that the AllowUnsafeBlocks=true element was only defined under the DEBUG|AnyCPU and Release|AnyCPU PropertyGroups in my project file.
Using this fixed it for me:
Target "BuildApp" (fun _ ->
!! ".\**\MyApp.*.csproj"
|> MSBuild buildDir "Build" ["Configuration", "Release"; "Platform", "AnyCPU"]
|> Log "AppBuild-Output: "
)
Hope this helps.
Ok I think this might be the way:
Target "CompileUnsafe" (fun _ ->
let buildMode = getBuildParamOrDefault "buildMode" "Release"
let setParams defaults =
{ defaults with
Verbosity = Some(Quiet)
Targets = ["Build"]
Properties =
[
"Optimize", "True"
"DebugSymbols", "True"
"Configuration", buildMode
"AllowUnsafeBlocks", "True"
]
}
build setParams "./ProjectPlugins.sln"
)
IF there are better solutions I'm all ears (the solution was there in the docs and I just missed it)