use tools paths and flags from the toolchain (#7)
* take tools paths and flags from the toolchain * correct toolchain data extraction, correct cmake flags and environment * framework script: export variables intended to be used in config script config script can create child processes which could use this variables * cmake: prepend relative [to the execroot] paths with "$EXT_BUILD_ROOT/" unfortunately, CMake does not understand relative paths (sometimes it runs tests for the passed compiler and for that concatenates the passed relative path to some tmp directory created for test) we replace only paths starting with external/ and <top-package-name>/, so we are quite fine to not make a mistake with replacing some not related to paths text; the targets for replacement take very different form (judging by examining toolchain definitions), for instance "-Lexternal/something" * test data for cross compilation for android and with --crosstool_top data files taken from bazel examples and bazel test data; NB one of the interesting things is that we need to specify tools dependency on android sdk and ndk, so that cmake_external shell script have access to these tools * remove cross compilation example with CROSSTOOL for now * add very simple CMake library (test data) * rename target to indicate it is not a test, but example * adjust android example: rename the target to indicate it is not a test but example, add android ndk sources as additional tool for cmake target, (otherwise it is not available in sandbox) use more simple cmake-built library * corrections to the framework & cmake: - correct search for the root directory of the filegroup (when it is not under external) - it was a mistake to specify shared library linker, specify CMAKE_AR instead - unfortunately, I have not discovered how to modify CMake behaviour to pass the custom static flags (rcsD) before "-qc <target>" to the ar linker; option from documentation does not work. To be investigated. For now, do not pass the static cxx linker options, taken from Bazel toolchain.
88
WORKSPACE
|
@ -3,15 +3,15 @@ workspace(name = "rules_foreign_cc")
|
|||
all_content = """filegroup(name = "all", srcs = glob(["**"]), visibility = ["//visibility:public"])"""
|
||||
|
||||
new_http_archive(
|
||||
name = "bazel_skylib",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
],
|
||||
strip_prefix= "bazel-skylib-0.5.0",
|
||||
sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
|
||||
type = "tar.gz",
|
||||
build_file_content = all_content,
|
||||
)
|
||||
name = "bazel_skylib",
|
||||
build_file_content = all_content,
|
||||
sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
|
||||
strip_prefix = "bazel-skylib-0.5.0",
|
||||
type = "tar.gz",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
new_http_archive(
|
||||
name = "libevent",
|
||||
|
@ -21,21 +21,59 @@ new_http_archive(
|
|||
)
|
||||
|
||||
new_http_archive(
|
||||
name = "zlib",
|
||||
urls = [
|
||||
"https://zlib.net/zlib-1.2.11.tar.xz",
|
||||
],
|
||||
strip_prefix= "zlib-1.2.11",
|
||||
sha256 = "4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066",
|
||||
build_file_content = all_content,
|
||||
)
|
||||
name = "zlib",
|
||||
build_file_content = all_content,
|
||||
sha256 = "4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066",
|
||||
strip_prefix = "zlib-1.2.11",
|
||||
urls = [
|
||||
"https://zlib.net/zlib-1.2.11.tar.xz",
|
||||
],
|
||||
)
|
||||
|
||||
new_http_archive(
|
||||
name = "libpng",
|
||||
urls = [
|
||||
"http://ftp-osl.osuosl.org/pub/libpng/src/libpng16/libpng-1.6.34.tar.xz",
|
||||
],
|
||||
strip_prefix= "libpng-1.6.34",
|
||||
sha256 = "2f1e960d92ce3b3abd03d06dfec9637dfbd22febf107a536b44f7a47c60659f6",
|
||||
build_file_content = all_content,
|
||||
)
|
||||
name = "libpng",
|
||||
build_file_content = all_content,
|
||||
sha256 = "2f1e960d92ce3b3abd03d06dfec9637dfbd22febf107a536b44f7a47c60659f6",
|
||||
strip_prefix = "libpng-1.6.34",
|
||||
urls = [
|
||||
"http://ftp-osl.osuosl.org/pub/libpng/src/libpng16/libpng-1.6.34.tar.xz",
|
||||
],
|
||||
)
|
||||
|
||||
new_http_archive(
|
||||
name = "org_linaro_components_toolchain_gcc_5_3_1",
|
||||
build_file = "framework_example/cmake_cross/compilers/linaro_linux_gcc_5.3.1.BUILD",
|
||||
strip_prefix = "gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf",
|
||||
url = "https://bazel-mirror.storage.googleapis.com/releases.linaro.org/components/toolchain/binaries/latest-5/arm-linux-gnueabihf/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf.tar.xz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_toolchains",
|
||||
sha256 = "259ec05a457bc93aec2aee7e4e67fb4bc1724a183b67baaf5dd6a08be6d6a84a",
|
||||
strip_prefix = "bazel-toolchains-e76b1031eba14c16d72f5837ae7cb7630a2322e2",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/e76b1031eba14c16d72f5837ae7cb7630a2322e2.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-toolchains/archive/e76b1031eba14c16d72f5837ae7cb7630a2322e2.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
android_sdk_repository(
|
||||
name = "androidsdk",
|
||||
)
|
||||
|
||||
android_ndk_repository(
|
||||
name = "androidndk",
|
||||
)
|
||||
|
||||
# Google Maven Repository
|
||||
GMAVEN_TAG = "20180625-1"
|
||||
|
||||
http_archive(
|
||||
name = "gmaven_rules",
|
||||
strip_prefix = "gmaven_rules-%s" % GMAVEN_TAG,
|
||||
url = "https://github.com/bazelbuild/gmaven_rules/archive/%s.tar.gz" % GMAVEN_TAG,
|
||||
)
|
||||
|
||||
load("@gmaven_rules//:gmaven.bzl", "gmaven_rules")
|
||||
|
||||
gmaven_rules()
|
||||
|
|
|
@ -25,7 +25,7 @@ cc_binary(
|
|||
)
|
||||
|
||||
cc_binary(
|
||||
name = "test_zlib",
|
||||
name = "zlib_usage_example",
|
||||
srcs = ["zlib-example.cpp"],
|
||||
deps = ["libz"],
|
||||
deps = [":libz"],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.bazel">
|
||||
|
||||
<uses-sdk android:minSdkVersion="14" />
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,38 @@
|
|||
load("//tools/build_defs:cmake.bzl", "cmake_external")
|
||||
load("@gmaven_rules//:defs.bzl", "gmaven_artifact")
|
||||
|
||||
cmake_external(
|
||||
name = "libhello",
|
||||
additional_tools = [
|
||||
"@androidndk//:files",
|
||||
],
|
||||
lib_source = "//framework_example/cmake_hello_world_lib:srcs",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "hello_lib_usage_example",
|
||||
srcs = ["hello_lib-example.cpp"],
|
||||
linkstatic = True,
|
||||
deps = [":libhello"],
|
||||
alwayslink = True,
|
||||
)
|
||||
|
||||
android_library(
|
||||
name = "lib",
|
||||
srcs = ["java/com/example/android/bazel/MainActivity.java"],
|
||||
custom_package = "com.example.android.bazel",
|
||||
manifest = "LibraryManifest.xml",
|
||||
resource_files = glob(["res/**/*"]),
|
||||
deps = [
|
||||
":hello_lib_usage_example",
|
||||
gmaven_artifact("com.android.support:appcompat-v7:aar:26.1.0"),
|
||||
gmaven_artifact("com.android.support.constraint:constraint-layout:aar:1.1.2"),
|
||||
],
|
||||
)
|
||||
|
||||
android_binary(
|
||||
name = "app",
|
||||
custom_package = "com.example.android.bazel",
|
||||
manifest = "AndroidManifest.xml",
|
||||
deps = [":lib"],
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.bazel">
|
||||
|
||||
<uses-sdk android:minSdkVersion="14" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,13 @@
|
|||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jstring
|
||||
|
||||
JNICALL
|
||||
Java_com_example_android_bazel_MainActivity_stringFromJNI(
|
||||
JNIEnv *env,
|
||||
jobject /* this */) {
|
||||
std::string hello = "Hello from C++";
|
||||
return env->NewStringUTF(hello.c_str());
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
#include "hello.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
hello_func();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package framework_example.cmake_android.java.com.example.android.bazel;
|
||||
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
static {
|
||||
System.loadLibrary("app");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// setContentView(R.layout.activity_main);
|
||||
//
|
||||
// // Example of a call to a native method
|
||||
// TextView tv = (TextView) findViewById(R.id.sample_text);
|
||||
// tv.setText(stringFromJNI());
|
||||
}
|
||||
|
||||
/**
|
||||
* A native method that is implemented by the 'native-lib' native library,
|
||||
* which is packaged with this application.
|
||||
*/
|
||||
public native String stringFromJNI();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.example.android.bazel.MainActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sample_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">Built By Bazel</string>
|
||||
</resources>
|
|
@ -0,0 +1,11 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,80 @@
|
|||
// Copied from https://gist.github.com/arq5x/5315739 for test purposes
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // for strlen
|
||||
#include <assert.h>
|
||||
#include "zlib.h"
|
||||
|
||||
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// original string len = 36
|
||||
char a[50] = "Hello Hello Hello Hello Hello Hello!";
|
||||
|
||||
// placeholder for the compressed (deflated) version of "a"
|
||||
char b[50];
|
||||
|
||||
// placeholder for the UNcompressed (inflated) version of "b"
|
||||
char c[50];
|
||||
|
||||
|
||||
printf("Uncompressed size is: %lu\n", strlen(a));
|
||||
printf("Uncompressed string is: %s\n", a);
|
||||
|
||||
|
||||
printf("\n----------\n\n");
|
||||
|
||||
// STEP 1.
|
||||
// deflate a into b. (that is, compress a into b)
|
||||
|
||||
// zlib struct
|
||||
z_stream defstream;
|
||||
defstream.zalloc = Z_NULL;
|
||||
defstream.zfree = Z_NULL;
|
||||
defstream.opaque = Z_NULL;
|
||||
// setup "a" as the input and "b" as the compressed output
|
||||
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
|
||||
defstream.next_in = (Bytef *)a; // input char array
|
||||
defstream.avail_out = (uInt)sizeof(b); // size of output
|
||||
defstream.next_out = (Bytef *)b; // output char array
|
||||
|
||||
// the actual compression work.
|
||||
deflateInit(&defstream, Z_BEST_COMPRESSION);
|
||||
deflate(&defstream, Z_FINISH);
|
||||
deflateEnd(&defstream);
|
||||
|
||||
// This is one way of getting the size of the output
|
||||
printf("Compressed size is: %lu\n", strlen(b));
|
||||
printf("Compressed string is: %s\n", b);
|
||||
|
||||
|
||||
printf("\n----------\n\n");
|
||||
|
||||
|
||||
// STEP 2.
|
||||
// inflate b into c
|
||||
// zlib struct
|
||||
z_stream infstream;
|
||||
infstream.zalloc = Z_NULL;
|
||||
infstream.zfree = Z_NULL;
|
||||
infstream.opaque = Z_NULL;
|
||||
// setup "b" as the input and "c" as the compressed output
|
||||
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
|
||||
infstream.next_in = (Bytef *)b; // input char array
|
||||
infstream.avail_out = (uInt)sizeof(c); // size of output
|
||||
infstream.next_out = (Bytef *)c; // output char array
|
||||
|
||||
// the actual DE-compression work.
|
||||
inflateInit(&infstream);
|
||||
inflate(&infstream, Z_NO_FLUSH);
|
||||
inflateEnd(&infstream);
|
||||
|
||||
printf("Uncompressed size is: %lu\n", strlen(c));
|
||||
printf("Uncompressed string is: %s\n", c);
|
||||
|
||||
|
||||
// make sure uncompressed is exactly equal to original.
|
||||
assert(strcmp(a,c)==0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# example code is taken from https://github.com/Akagi201/learning-cmake/tree/master/hello-world-lib
|
||||
# for test only
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = glob(["**"]),
|
||||
visibility = ["//visibility:public"]
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
# taken from https://github.com/Akagi201/learning-cmake/tree/master/hello-world-lib
|
||||
# for test only
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
project(hellolib)
|
||||
|
||||
add_subdirectory(src)
|
|
@ -0,0 +1,24 @@
|
|||
# taken from https://github.com/Akagi201/learning-cmake/tree/master/hello-world-lib
|
||||
# for test only
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
message("CMAKE_CXX_CREATE_STATIC_LIBRARY: " CMAKE_CXX_CREATE_STATIC_LIBRARY)
|
||||
|
||||
set(LIBHELLO_SRC hello.c)
|
||||
|
||||
add_library(hello_dynamic SHARED ${LIBHELLO_SRC})
|
||||
add_library(hello_static STATIC ${LIBHELLO_SRC})
|
||||
|
||||
set_target_properties(hello_dynamic PROPERTIES OUTPUT_NAME "hello")
|
||||
set_target_properties(hello_dynamic PROPERTIES VERSION 1.2 SOVERSION 1)
|
||||
|
||||
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
install(TARGETS hello_dynamic hello_static
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
|
||||
install(FILES hello.h DESTINATION include)
|
|
@ -0,0 +1,7 @@
|
|||
#include "hello.h"
|
||||
|
||||
void hello_func(void) {
|
||||
printf("Hello World!\n");
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef HELLO_H_
|
||||
#define HELLO_H_ (1)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void hello_func(void);
|
||||
|
||||
#endif
|
|
@ -1,227 +0,0 @@
|
|||
""" Defines create_linking_info, which wraps passed libraries into CcLinkingInfo
|
||||
"""
|
||||
|
||||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
|
||||
LibrariesToLinkInfo = provider(
|
||||
doc = "Libraries to be wrapped into CcLinkingInfo",
|
||||
fields = dict(
|
||||
static_libraries = "Static library files, optional",
|
||||
shared_libraries = "Dynamic library files, optional",
|
||||
interface_libraries = "Interface library files, optional",
|
||||
))
|
||||
|
||||
def _to_list(element):
|
||||
if element == None:
|
||||
return []
|
||||
else:
|
||||
return [element]
|
||||
|
||||
def _to_depset(element):
|
||||
if element == None:
|
||||
return depset()
|
||||
return depset(element)
|
||||
|
||||
def _perform_error_checks(
|
||||
system_provided,
|
||||
shared_library_artifacts,
|
||||
interface_library_artifacts,
|
||||
targets_windows):
|
||||
# If the shared library will be provided by system during runtime, users are not supposed to
|
||||
# specify shared_library.
|
||||
if system_provided and shared_library_artifacts != None:
|
||||
fail("'shared_library' shouldn't be specified when 'system_provided' is true")
|
||||
|
||||
# If a shared library won't be provided by system during runtime and we are linking the shared
|
||||
# library through interface library, the shared library must be specified.
|
||||
if (not system_provided and shared_library_artifacts == None and
|
||||
interface_library_artifacts != None):
|
||||
fail("'shared_library' should be specified when 'system_provided' is false")
|
||||
|
||||
if targets_windows and shared_library_artifacts != None:
|
||||
fail("'interface library' must be specified when using cc_import for " +
|
||||
"shared library on Windows")
|
||||
|
||||
def _build_static_library_to_link(ctx, library):
|
||||
if library == None:
|
||||
fail("Parameter 'static_library_artifact' cannot be None")
|
||||
|
||||
static_library_category = None
|
||||
if ctx.attr.alwayslink:
|
||||
static_library_category = "alwayslink_static_library"
|
||||
else:
|
||||
static_library_category = "static_library"
|
||||
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = static_library_category,
|
||||
)
|
||||
|
||||
def _build_shared_library_to_link(ctx, library, cc_toolchain, targets_windows):
|
||||
if library == None:
|
||||
fail("Parameter 'shared_library_artifact' cannot be None")
|
||||
|
||||
if targets_windows:
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = "dynamic_library",
|
||||
)
|
||||
else:
|
||||
return cc_common.create_symlink_library_to_link(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
library = library,
|
||||
)
|
||||
|
||||
def _build_interface_library_to_link(ctx, library, cc_toolchain, targets_windows):
|
||||
if library == None:
|
||||
fail("Parameter 'interface_library_artifact' cannot be None")
|
||||
|
||||
if targets_windows:
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = "interface_library",
|
||||
)
|
||||
else:
|
||||
return cc_common.create_symlink_library_to_link(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
library = library,
|
||||
)
|
||||
|
||||
# we could possibly take a decision about linking interface/shared library beased on each library name
|
||||
# (usefull for the case when multiple output targets are provided)
|
||||
def _build_libraries_to_link_and_runtime_artifact(ctx, files, cc_toolchain, targets_windows):
|
||||
static_libraries = [_build_static_library_to_link(ctx, lib) for lib in (files.static_libraries or [])]
|
||||
|
||||
shared_libraries = []
|
||||
runtime_artifacts = []
|
||||
if files.shared_libraries != None:
|
||||
for lib in files.shared_libraries:
|
||||
shared_library += _build_shared_library_to_link(ctx, lib, cc_toolchain, targets_windows)
|
||||
runtime_artifact += shared_library.artifact()
|
||||
|
||||
interface_libraries = []
|
||||
if files.interface_libraries != None:
|
||||
for lib in files.interface_libraries:
|
||||
interface_libraries += _build_interface_library_to_link(ctx, lib, cc_toolchain, targets_windows)
|
||||
|
||||
dynamic_libraries_for_linking = None
|
||||
if len(interface_libraries) > 0:
|
||||
dynamic_libraries_for_linking = interface_libraries
|
||||
else:
|
||||
dynamic_libraries_for_linking = shared_libraries
|
||||
|
||||
return {"static_libraries": static_libraries,
|
||||
"dynamic_libraries": dynamic_libraries_for_linking,
|
||||
"runtime_artifacts": runtime_artifacts}
|
||||
|
||||
def _build_cc_link_params(
|
||||
ctx,
|
||||
user_link_flags,
|
||||
static_libraries,
|
||||
dynamic_libraries,
|
||||
runtime_artifacts):
|
||||
static_shared = None
|
||||
static_no_shared = None
|
||||
if static_libraries != None and len(static_libraries) > 0:
|
||||
static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
else:
|
||||
static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
|
||||
no_static_shared = None
|
||||
no_static_no_shared = None
|
||||
if dynamic_libraries != None and len(dynamic_libraries) > 0:
|
||||
no_static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
no_static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
else:
|
||||
no_static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
no_static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
|
||||
return {"static_mode_params_for_dynamic_library": static_shared,
|
||||
"static_mode_params_for_executable": static_no_shared,
|
||||
"dynamic_mode_params_for_dynamic_library": no_static_shared,
|
||||
"dynamic_mode_params_for_executable": no_static_no_shared}
|
||||
|
||||
def targets_windows(ctx, cc_toolchain):
|
||||
""" Returns true if build is targeting Windows
|
||||
Args:
|
||||
ctx - rule context
|
||||
cc_toolchain - optional - Cc toolchain
|
||||
"""
|
||||
toolchain = cc_toolchain if cc_toolchain else find_cpp_toolchain(ctx)
|
||||
feature_configuration = cc_common.configure_features(
|
||||
cc_toolchain = toolchain,
|
||||
requested_features = ctx.features,
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
|
||||
return cc_common.is_enabled(
|
||||
feature_configuration = feature_configuration,
|
||||
feature_name = "targets_windows",
|
||||
)
|
||||
|
||||
def create_linking_info(ctx, user_link_flags, files):
|
||||
""" Creates CcLinkingInfo for the passed user link options and libraries.
|
||||
Args:
|
||||
ctx - rule context
|
||||
user_link_flags - (list of strings) link optins, provided by user
|
||||
files - (LibrariesToLink) provider with the library files
|
||||
"""
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
for_windows = targets_windows(ctx, cc_toolchain)
|
||||
|
||||
_perform_error_checks(
|
||||
False,
|
||||
files.shared_libraries,
|
||||
files.interface_libraries,
|
||||
for_windows,
|
||||
)
|
||||
|
||||
artifacts = _build_libraries_to_link_and_runtime_artifact(
|
||||
ctx,
|
||||
files,
|
||||
cc_toolchain,
|
||||
for_windows,
|
||||
)
|
||||
|
||||
link_params = _build_cc_link_params(ctx, user_link_flags, **artifacts)
|
||||
|
||||
return CcLinkingInfo(**link_params)
|
|
@ -0,0 +1,397 @@
|
|||
""" Defines create_linking_info, which wraps passed libraries into CcLinkingInfo
|
||||
"""
|
||||
|
||||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
load(
|
||||
"@bazel_tools//tools/build_defs/cc:action_names.bzl",
|
||||
"ASSEMBLE_ACTION_NAME",
|
||||
"CPP_COMPILE_ACTION_NAME",
|
||||
"CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME",
|
||||
"CPP_LINK_EXECUTABLE_ACTION_NAME",
|
||||
"CPP_LINK_STATIC_LIBRARY_ACTION_NAME",
|
||||
"C_COMPILE_ACTION_NAME",
|
||||
)
|
||||
|
||||
LibrariesToLinkInfo = provider(
|
||||
doc = "Libraries to be wrapped into CcLinkingInfo",
|
||||
fields = dict(
|
||||
static_libraries = "Static library files, optional",
|
||||
shared_libraries = "Shared library files, optional",
|
||||
interface_libraries = "Interface library files, optional",
|
||||
),
|
||||
)
|
||||
|
||||
CxxToolsInfo = provider(
|
||||
doc = "Paths to the C/C++ tools, taken from the toolchain",
|
||||
fields = dict(
|
||||
cc = "C compiler",
|
||||
cxx = "C++ compiler",
|
||||
cxx_linker_static = "C++ linker to link static library",
|
||||
cxx_linker_executable = "C++ linker to link executable",
|
||||
),
|
||||
)
|
||||
|
||||
CxxFlagsInfo = provider(
|
||||
doc = "Flags for the C/C++ tools, taken from the toolchain",
|
||||
fields = dict(
|
||||
cc = "C compiler flags",
|
||||
cxx = "C++ compiler flags",
|
||||
cxx_linker_shared = "C++ linker flags when linking shared library",
|
||||
cxx_linker_static = "C++ linker flags when linking static library",
|
||||
cxx_linker_executable = "C++ linker flags when linking executable",
|
||||
assemble = "Assemble flags",
|
||||
),
|
||||
)
|
||||
|
||||
def _to_list(element):
|
||||
if element == None:
|
||||
return []
|
||||
else:
|
||||
return [element]
|
||||
|
||||
def _to_depset(element):
|
||||
if element == None:
|
||||
return depset()
|
||||
return depset(element)
|
||||
|
||||
def _perform_error_checks(
|
||||
system_provided,
|
||||
shared_library_artifacts,
|
||||
interface_library_artifacts,
|
||||
targets_windows):
|
||||
# If the shared library will be provided by system during runtime, users are not supposed to
|
||||
# specify shared_library.
|
||||
if system_provided and shared_library_artifacts != None:
|
||||
fail("'shared_library' shouldn't be specified when 'system_provided' is true")
|
||||
|
||||
# If a shared library won't be provided by system during runtime and we are linking the shared
|
||||
# library through interface library, the shared library must be specified.
|
||||
if (not system_provided and shared_library_artifacts == None and
|
||||
interface_library_artifacts != None):
|
||||
fail("'shared_library' should be specified when 'system_provided' is false")
|
||||
|
||||
if targets_windows and shared_library_artifacts != None:
|
||||
fail("'interface library' must be specified when using cc_import for " +
|
||||
"shared library on Windows")
|
||||
|
||||
def _build_static_library_to_link(ctx, library):
|
||||
if library == None:
|
||||
fail("Parameter 'static_library_artifact' cannot be None")
|
||||
|
||||
static_library_category = None
|
||||
if ctx.attr.alwayslink:
|
||||
static_library_category = "alwayslink_static_library"
|
||||
else:
|
||||
static_library_category = "static_library"
|
||||
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = static_library_category,
|
||||
)
|
||||
|
||||
def _build_shared_library_to_link(ctx, library, cc_toolchain, targets_windows):
|
||||
if library == None:
|
||||
fail("Parameter 'shared_library_artifact' cannot be None")
|
||||
|
||||
if targets_windows:
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = "dynamic_library",
|
||||
)
|
||||
else:
|
||||
return cc_common.create_symlink_library_to_link(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
library = library,
|
||||
)
|
||||
|
||||
def _build_interface_library_to_link(ctx, library, cc_toolchain, targets_windows):
|
||||
if library == None:
|
||||
fail("Parameter 'interface_library_artifact' cannot be None")
|
||||
|
||||
if targets_windows:
|
||||
return cc_common.create_library_to_link(
|
||||
ctx = ctx,
|
||||
library = library,
|
||||
artifact_category = "interface_library",
|
||||
)
|
||||
else:
|
||||
return cc_common.create_symlink_library_to_link(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
library = library,
|
||||
)
|
||||
|
||||
# we could possibly take a decision about linking interface/shared library beased on each library name
|
||||
# (usefull for the case when multiple output targets are provided)
|
||||
def _build_libraries_to_link_and_runtime_artifact(ctx, files, cc_toolchain, targets_windows):
|
||||
static_libraries = [_build_static_library_to_link(ctx, lib) for lib in (files.static_libraries or [])]
|
||||
|
||||
shared_libraries = []
|
||||
runtime_artifacts = []
|
||||
if files.shared_libraries != None:
|
||||
for lib in files.shared_libraries:
|
||||
shared_library += _build_shared_library_to_link(ctx, lib, cc_toolchain, targets_windows)
|
||||
runtime_artifact += shared_library.artifact()
|
||||
|
||||
interface_libraries = []
|
||||
if files.interface_libraries != None:
|
||||
for lib in files.interface_libraries:
|
||||
interface_libraries += _build_interface_library_to_link(ctx, lib, cc_toolchain, targets_windows)
|
||||
|
||||
dynamic_libraries_for_linking = None
|
||||
if len(interface_libraries) > 0:
|
||||
dynamic_libraries_for_linking = interface_libraries
|
||||
else:
|
||||
dynamic_libraries_for_linking = shared_libraries
|
||||
|
||||
return {
|
||||
"static_libraries": static_libraries,
|
||||
"dynamic_libraries": dynamic_libraries_for_linking,
|
||||
"runtime_artifacts": runtime_artifacts,
|
||||
}
|
||||
|
||||
def _build_cc_link_params(
|
||||
ctx,
|
||||
user_link_flags,
|
||||
static_libraries,
|
||||
dynamic_libraries,
|
||||
runtime_artifacts):
|
||||
static_shared = None
|
||||
static_no_shared = None
|
||||
if static_libraries != None and len(static_libraries) > 0:
|
||||
static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
else:
|
||||
static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
|
||||
no_static_shared = None
|
||||
no_static_no_shared = None
|
||||
if dynamic_libraries != None and len(dynamic_libraries) > 0:
|
||||
no_static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
no_static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(dynamic_libraries),
|
||||
dynamic_libraries_for_runtime = _to_depset(runtime_artifacts),
|
||||
)
|
||||
else:
|
||||
no_static_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
user_link_flags = user_link_flags,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
no_static_no_shared = cc_common.create_cc_link_params(
|
||||
ctx = ctx,
|
||||
libraries_to_link = _to_depset(static_libraries),
|
||||
)
|
||||
|
||||
return {
|
||||
"static_mode_params_for_dynamic_library": static_shared,
|
||||
"static_mode_params_for_executable": static_no_shared,
|
||||
"dynamic_mode_params_for_dynamic_library": no_static_shared,
|
||||
"dynamic_mode_params_for_executable": no_static_no_shared,
|
||||
}
|
||||
|
||||
def targets_windows(ctx, cc_toolchain):
|
||||
""" Returns true if build is targeting Windows
|
||||
Args:
|
||||
ctx - rule context
|
||||
cc_toolchain - optional - Cc toolchain
|
||||
"""
|
||||
toolchain = cc_toolchain if cc_toolchain else find_cpp_toolchain(ctx)
|
||||
feature_configuration = cc_common.configure_features(
|
||||
cc_toolchain = toolchain,
|
||||
requested_features = ctx.features,
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
|
||||
return cc_common.is_enabled(
|
||||
feature_configuration = feature_configuration,
|
||||
feature_name = "targets_windows",
|
||||
)
|
||||
|
||||
def create_linking_info(ctx, user_link_flags, files):
|
||||
""" Creates CcLinkingInfo for the passed user link options and libraries.
|
||||
Args:
|
||||
ctx - rule context
|
||||
user_link_flags - (list of strings) link optins, provided by user
|
||||
files - (LibrariesToLink) provider with the library files
|
||||
"""
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
for_windows = targets_windows(ctx, cc_toolchain)
|
||||
|
||||
_perform_error_checks(
|
||||
False,
|
||||
files.shared_libraries,
|
||||
files.interface_libraries,
|
||||
for_windows,
|
||||
)
|
||||
|
||||
artifacts = _build_libraries_to_link_and_runtime_artifact(
|
||||
ctx,
|
||||
files,
|
||||
cc_toolchain,
|
||||
for_windows,
|
||||
)
|
||||
|
||||
link_params = _build_cc_link_params(ctx, user_link_flags, **artifacts)
|
||||
|
||||
return CcLinkingInfo(**link_params)
|
||||
|
||||
def getToolsInfo(ctx):
|
||||
""" Takes information about tools paths from cc_toolchain, returns CxxToolsInfo
|
||||
Args:
|
||||
ctx - rule context
|
||||
"""
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
feature_configuration = cc_common.configure_features(
|
||||
cc_toolchain = cc_toolchain,
|
||||
requested_features = ctx.features,
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
|
||||
return CxxToolsInfo(
|
||||
cc = cc_common.get_tool_for_action(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = C_COMPILE_ACTION_NAME,
|
||||
),
|
||||
cxx = cc_common.get_tool_for_action(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_COMPILE_ACTION_NAME,
|
||||
),
|
||||
cxx_linker_static = cc_common.get_tool_for_action(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
|
||||
),
|
||||
cxx_linker_executable = cc_common.get_tool_for_action(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
|
||||
),
|
||||
)
|
||||
|
||||
def getFlagsInfo(ctx):
|
||||
""" Takes information about flags from cc_toolchain, returns CxxFlagsInfo
|
||||
Args:
|
||||
ctx - rule context
|
||||
"""
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
feature_configuration = cc_common.configure_features(
|
||||
cc_toolchain = cc_toolchain,
|
||||
requested_features = ctx.features,
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
copts = ctx.attr.copts if hasattr(ctx.attr, "copts") else depset()
|
||||
|
||||
return CxxFlagsInfo(
|
||||
cc = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = C_COMPILE_ACTION_NAME,
|
||||
variables = cc_common.create_compile_variables(
|
||||
feature_configuration = feature_configuration,
|
||||
cc_toolchain = cc_toolchain,
|
||||
user_compile_flags = copts,
|
||||
),
|
||||
),
|
||||
cxx = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_COMPILE_ACTION_NAME,
|
||||
variables = cc_common.create_compile_variables(
|
||||
feature_configuration = feature_configuration,
|
||||
cc_toolchain = cc_toolchain,
|
||||
user_compile_flags = copts,
|
||||
add_legacy_cxx_options = True,
|
||||
),
|
||||
),
|
||||
cxx_linker_shared = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME,
|
||||
variables = cc_common.create_link_variables(
|
||||
cc_toolchain = cc_toolchain,
|
||||
feature_configuration = feature_configuration,
|
||||
is_using_linker = True,
|
||||
is_linking_dynamic_library = True,
|
||||
),
|
||||
),
|
||||
cxx_linker_static = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
|
||||
variables = cc_common.create_link_variables(
|
||||
cc_toolchain = cc_toolchain,
|
||||
feature_configuration = feature_configuration,
|
||||
is_using_linker = False,
|
||||
is_linking_dynamic_library = False,
|
||||
),
|
||||
),
|
||||
cxx_linker_executable = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
|
||||
variables = cc_common.create_link_variables(
|
||||
cc_toolchain = cc_toolchain,
|
||||
feature_configuration = feature_configuration,
|
||||
is_using_linker = True,
|
||||
is_linking_dynamic_library = False,
|
||||
),
|
||||
),
|
||||
assemble = cc_common.get_memory_inefficient_command_line(
|
||||
feature_configuration = feature_configuration,
|
||||
action_name = ASSEMBLE_ACTION_NAME,
|
||||
variables = cc_common.create_compile_variables(
|
||||
feature_configuration = feature_configuration,
|
||||
cc_toolchain = cc_toolchain,
|
||||
user_compile_flags = copts,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
def absolutize_path_in_str(ctx, text, root_str):
|
||||
""" Replaces relative paths in [the middle of] 'text', prepending them with 'root_str'.
|
||||
If there is nothing to replace, returns the 'text'.
|
||||
|
||||
We only will replace relative paths starting with either 'external/' or '<top-package-name>/',
|
||||
because we only want to point with absolute paths to external repositories or inside our
|
||||
current workspace. (And also to limit the possibility of error with such not exact replacing.)
|
||||
|
||||
Args:
|
||||
ctx - rule context (to determine the top package name)
|
||||
text - the text to do replacement in
|
||||
root_str - the text to prepend to the found relative path
|
||||
"""
|
||||
package = ctx.label.package
|
||||
if package.find("/") > 0:
|
||||
(package, separator, tail) = package.partition("/")
|
||||
|
||||
new_text = _prefix(text, "external/", root_str)
|
||||
if new_text == text:
|
||||
new_text = _prefix(text, package + "/", root_str)
|
||||
|
||||
return new_text
|
||||
|
||||
def _prefix(text, from_str, prefix):
|
||||
(before, middle, after) = text.partition(from_str)
|
||||
if not middle or before.endswith("/"):
|
||||
return text
|
||||
return before + prefix + middle + after
|
|
@ -1,24 +1,102 @@
|
|||
""" Defines the rule for building external library with CMake
|
||||
"""
|
||||
|
||||
load("//tools/build_defs:framework.bzl", "cc_external_rule_impl", "detect_root",
|
||||
"CC_EXTERNAL_RULE_ATTRIBUTES", "create_attrs")
|
||||
load(
|
||||
"//tools/build_defs:framework.bzl",
|
||||
"CC_EXTERNAL_RULE_ATTRIBUTES",
|
||||
"cc_external_rule_impl",
|
||||
"create_attrs",
|
||||
"detect_root",
|
||||
)
|
||||
load("//tools/build_defs:cc_toolchain_util.bzl", "absolutize_path_in_str", "getFlagsInfo", "getToolsInfo")
|
||||
|
||||
def _cmake_external(ctx):
|
||||
options = " ".join(ctx.attr.cmake_options)
|
||||
root = detect_root(ctx.attr.lib_source)
|
||||
cmake_string = "cmake -DCMAKE_PREFIX_PATH=\"$EXT_BUILD_ROOT\" -DCMAKE_INSTALL_PREFIX=$INSTALLDIR {} $EXT_BUILD_ROOT/{}".format(options, root)
|
||||
options = " ".join(ctx.attr.cmake_options)
|
||||
root = detect_root(ctx.attr.lib_source)
|
||||
|
||||
attrs = create_attrs(ctx.attr,
|
||||
configure_name = 'CMake',
|
||||
configure_script = cmake_string)
|
||||
tools = getToolsInfo(ctx)
|
||||
flags = getFlagsInfo(ctx)
|
||||
|
||||
return cc_external_rule_impl(ctx, attrs)
|
||||
cmake_string = " ".join([
|
||||
" ".join(_get_toolchain_variables(ctx, tools, flags)),
|
||||
" cmake",
|
||||
" ".join(_get_toolchain_options(ctx, tools, flags)),
|
||||
"-DCMAKE_PREFIX_PATH=\"$EXT_BUILD_ROOT\"",
|
||||
"-DCMAKE_INSTALL_PREFIX=$INSTALLDIR",
|
||||
options,
|
||||
"$EXT_BUILD_ROOT/" + root,
|
||||
])
|
||||
|
||||
attrs = create_attrs(
|
||||
ctx.attr,
|
||||
configure_name = "CMake",
|
||||
configure_script = cmake_string,
|
||||
)
|
||||
|
||||
return cc_external_rule_impl(ctx, attrs)
|
||||
|
||||
def _get_toolchain_variables(ctx, tools, flags):
|
||||
vars = []
|
||||
|
||||
if tools.cc:
|
||||
vars += _env_var(ctx, "CC", [tools.cc])
|
||||
if tools.cxx:
|
||||
vars += _env_var(ctx, "CXX", [tools.cxx])
|
||||
if flags.cc:
|
||||
vars += _env_var(ctx, "CFLAGS", flags.cc)
|
||||
if flags.cc:
|
||||
vars += _env_var(ctx, "CXXFLAGS", flags.cxx)
|
||||
if flags.assemble:
|
||||
vars += _env_var(ctx, "ASMFLAGS", flags.assemble)
|
||||
return vars
|
||||
|
||||
def _get_toolchain_options(ctx, tools, flags):
|
||||
options = []
|
||||
if tools.cxx_linker_static:
|
||||
options += _option(ctx, "CMAKE_AR", [tools.cxx_linker_static])
|
||||
|
||||
# this does not work by some reason
|
||||
# options += _option(ctx, "CMAKE_CXX_CREATE_STATIC_LIBRARY", ["<CMAKE_AR> <LINK_FLAGS> qc <TARGET> <OBJECTS>"])
|
||||
# options += _option(ctx, "CMAKE_CXX_ARCHIVE_CREATE", ["<CMAKE_AR> <LINK_FLAGS> qc <TARGET> <OBJECTS>"])
|
||||
# options += _option(ctx, "CMAKE_CXX_ARCHIVE_APPEND", ["<CMAKE_AR> <LINK_FLAGS> qc <TARGET> <OBJECTS>"])
|
||||
# options += _option(ctx, "CMAKE_CXX_ARCHIVE_FINISH", ["<CMAKE_RANLIB> <TARGET>"])
|
||||
|
||||
if tools.cxx_linker_executable:
|
||||
# https://github.com/Kitware/CMake/blob/master/Modules/CMakeCXXInformation.cmake
|
||||
rule_string = " ".join([
|
||||
"{}",
|
||||
"<FLAGS>",
|
||||
"<CMAKE_CXX_LINK_FLAGS>",
|
||||
"<LINK_FLAGS>",
|
||||
"<OBJECTS>",
|
||||
"-o <TARGET>",
|
||||
"<LINK_LIBRARIES>",
|
||||
]).format(absolutize_path_in_str(ctx, tools.cxx_linker_executable, "$EXT_BUILD_ROOT/"))
|
||||
options += _option(ctx, "CMAKE_CXX_LINK_EXECUTABLE", [rule_string])
|
||||
|
||||
# commented out for now, because http://cmake.3232098.n2.nabble.com/CMake-incorrectly-passes-linker-flags-to-ar-td7592436.html
|
||||
# if flags.cxx_linker_static:
|
||||
# options += _option(ctx, "CMAKE_STATIC_LINKER_FLAGS", flags.cxx_linker_static)
|
||||
if flags.cxx_linker_shared:
|
||||
options += _option(ctx, "CMAKE_SHARED_LINKER_FLAGS", flags.cxx_linker_shared)
|
||||
if flags.cxx_linker_executable:
|
||||
options += _option(ctx, "CMAKE_EXE_LINKER_FLAGS", flags.cxx_linker_executable)
|
||||
|
||||
return options
|
||||
|
||||
def _env_var(ctx, cmake_option, flags):
|
||||
return ["{}=\"{}\"".format(cmake_option, _join_flags_list(ctx, flags))]
|
||||
|
||||
def _option(ctx, cmake_option, flags):
|
||||
return ["-D{}=\"{}\"".format(cmake_option, _join_flags_list(ctx, flags))]
|
||||
|
||||
def _join_flags_list(ctx, flags):
|
||||
return " ".join([absolutize_path_in_str(ctx, flag, "$EXT_BUILD_ROOT/") for flag in flags])
|
||||
|
||||
def _attrs():
|
||||
attrs = dict(CC_EXTERNAL_RULE_ATTRIBUTES)
|
||||
attrs.update({"cmake_options": attr.string_list(mandatory = False, default = [])})
|
||||
return attrs
|
||||
attrs = dict(CC_EXTERNAL_RULE_ATTRIBUTES)
|
||||
attrs.update({"cmake_options": attr.string_list(mandatory = False, default = [])})
|
||||
return attrs
|
||||
|
||||
""" Rule for building external library with CMake
|
||||
Attributes:
|
||||
|
@ -29,5 +107,5 @@ cmake_external = rule(
|
|||
attrs = _attrs(),
|
||||
fragments = ["cpp"],
|
||||
output_to_genfiles = True,
|
||||
implementation = _cmake_external
|
||||
implementation = _cmake_external,
|
||||
)
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
"""
|
||||
|
||||
load("@bazel_skylib//lib:collections.bzl", "collections")
|
||||
load("//tools/build_defs:cc_linking_util.bzl", "create_linking_info", "LibrariesToLinkInfo",
|
||||
"targets_windows")
|
||||
load(
|
||||
"//tools/build_defs:cc_toolchain_util.bzl",
|
||||
"LibrariesToLinkInfo",
|
||||
"create_linking_info",
|
||||
"targets_windows",
|
||||
)
|
||||
|
||||
""" Dict with definitions of the context attributes, that customize cc_external_rule_impl function.
|
||||
Many of the attributes have default values.
|
||||
|
@ -13,242 +17,245 @@ load("//tools/build_defs:cc_linking_util.bzl", "create_linking_info", "Libraries
|
|||
description dict. See cmake.bzl as an example.
|
||||
"""
|
||||
CC_EXTERNAL_RULE_ATTRIBUTES = {
|
||||
# Library name. Defines the name of the install directory and the name of the static library,
|
||||
# if no output files parameters are defined (any of static_libraries, shared_libraries,
|
||||
# interface_libraries, binaries_names)
|
||||
# Optional. If not defined, defaults to the target's name.
|
||||
"lib_name": attr.string(mandatory = False),
|
||||
# Label with source code to build. Typically a filegroup for the source of remote repository.
|
||||
# Mandatory.
|
||||
"lib_source": attr.label(mandatory = True, allow_files = True),
|
||||
# Optional compilation definitions to be passed to the dependencies of this library.
|
||||
# They are NOT passed to the compiler, you should duplicate them in the configuration options.
|
||||
"defines": attr.string_list(mandatory = False, default = []),
|
||||
#
|
||||
# Optional additional inputs to be declared as needed for the shell script action.
|
||||
# Not used by the shell script part in cc_external_rule_impl.
|
||||
"additional_inputs": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
# Optional additional tools needed for the building.
|
||||
# Not used by the shell script part in cc_external_rule_impl.
|
||||
"additional_tools": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
#
|
||||
# Optional part of the shell script to be added after the make commands
|
||||
"postfix_script": attr.string(mandatory = False),
|
||||
# Optinal make commands, defaults to ["make", "make install"]
|
||||
"make_commands": attr.string_list(mandatory = False, default = ["make", "make install"]),
|
||||
#
|
||||
# Optional dependencies to be copied into the directory structure.
|
||||
# Typically those directly required for the external building of the library/binaries.
|
||||
# (i.e. those that the external buidl system will be looking for and paths to which are
|
||||
# provided by the calling rule)
|
||||
"deps": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
# Optional tools to be copied into the directory structure.
|
||||
# Similar to deps, those directly required for the external building of the library/binaries.
|
||||
"tools_deps": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
#
|
||||
# Optional name of the output subdirectory with the header files, defaults to 'include'.
|
||||
"out_include_dir": attr.string(mandatory = False, default = "include"),
|
||||
# Optional name of the output subdirectory with the library files, defaults to 'lib'.
|
||||
"out_lib_dir": attr.string(mandatory = False, default = "lib"),
|
||||
# Optional name of the output subdirectory with the binary files, defaults to 'bin'.
|
||||
"out_bin_dir": attr.string(mandatory = False, default = "bin"),
|
||||
#
|
||||
# Optional. if true, link all the object files from the static library,
|
||||
# even if they are not used.
|
||||
"alwayslink": attr.bool(mandatory = False, default = False),
|
||||
# Optional link options to be passed up to the dependencies of this library
|
||||
"linkopts": attr.string_list(mandatory = False, default = []),
|
||||
#
|
||||
# Output files names parameters. If any of them is defined, only these files are passed to
|
||||
# Bazel providers.
|
||||
# if no of them is defined, default lib_name.a/lib_name.lib static library is assumed.
|
||||
#
|
||||
# Optional names of the resulting static libraries.
|
||||
"static_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting shared libraries.
|
||||
"shared_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting interface libraries.
|
||||
"interface_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting binaries.
|
||||
"binaries": attr.string_list(mandatory = False),
|
||||
#
|
||||
# Optional name of the output subdirectory with pkgconfig files.
|
||||
"out_pkg_config_dir": attr.string(mandatory = False),
|
||||
# link to the shell utilities used by the shell script in cc_external_rule_impl.
|
||||
"_utils": attr.label(
|
||||
default = Label("//tools/build_defs:utils.sh"),
|
||||
allow_single_file = True,
|
||||
executable = True,
|
||||
cfg = "target"
|
||||
),
|
||||
# we need to declare this attribute to access cc_toolchain
|
||||
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
|
||||
# Library name. Defines the name of the install directory and the name of the static library,
|
||||
# if no output files parameters are defined (any of static_libraries, shared_libraries,
|
||||
# interface_libraries, binaries_names)
|
||||
# Optional. If not defined, defaults to the target's name.
|
||||
"lib_name": attr.string(mandatory = False),
|
||||
# Label with source code to build. Typically a filegroup for the source of remote repository.
|
||||
# Mandatory.
|
||||
"lib_source": attr.label(mandatory = True, allow_files = True),
|
||||
# Optional compilation definitions to be passed to the dependencies of this library.
|
||||
# They are NOT passed to the compiler, you should duplicate them in the configuration options.
|
||||
"defines": attr.string_list(mandatory = False, default = []),
|
||||
#
|
||||
# Optional additional inputs to be declared as needed for the shell script action.
|
||||
# Not used by the shell script part in cc_external_rule_impl.
|
||||
"additional_inputs": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
# Optional additional tools needed for the building.
|
||||
# Not used by the shell script part in cc_external_rule_impl.
|
||||
"additional_tools": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
#
|
||||
# Optional part of the shell script to be added after the make commands
|
||||
"postfix_script": attr.string(mandatory = False),
|
||||
# Optinal make commands, defaults to ["make", "make install"]
|
||||
"make_commands": attr.string_list(mandatory = False, default = ["make", "make install"]),
|
||||
#
|
||||
# Optional dependencies to be copied into the directory structure.
|
||||
# Typically those directly required for the external building of the library/binaries.
|
||||
# (i.e. those that the external buidl system will be looking for and paths to which are
|
||||
# provided by the calling rule)
|
||||
"deps": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
# Optional tools to be copied into the directory structure.
|
||||
# Similar to deps, those directly required for the external building of the library/binaries.
|
||||
"tools_deps": attr.label_list(mandatory = False, allow_files = True, default = []),
|
||||
#
|
||||
# Optional name of the output subdirectory with the header files, defaults to 'include'.
|
||||
"out_include_dir": attr.string(mandatory = False, default = "include"),
|
||||
# Optional name of the output subdirectory with the library files, defaults to 'lib'.
|
||||
"out_lib_dir": attr.string(mandatory = False, default = "lib"),
|
||||
# Optional name of the output subdirectory with the binary files, defaults to 'bin'.
|
||||
"out_bin_dir": attr.string(mandatory = False, default = "bin"),
|
||||
#
|
||||
# Optional. if true, link all the object files from the static library,
|
||||
# even if they are not used.
|
||||
"alwayslink": attr.bool(mandatory = False, default = False),
|
||||
# Optional link options to be passed up to the dependencies of this library
|
||||
"linkopts": attr.string_list(mandatory = False, default = []),
|
||||
#
|
||||
# Output files names parameters. If any of them is defined, only these files are passed to
|
||||
# Bazel providers.
|
||||
# if no of them is defined, default lib_name.a/lib_name.lib static library is assumed.
|
||||
#
|
||||
# Optional names of the resulting static libraries.
|
||||
"static_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting shared libraries.
|
||||
"shared_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting interface libraries.
|
||||
"interface_libraries": attr.string_list(mandatory = False),
|
||||
# Optional names of the resulting binaries.
|
||||
"binaries": attr.string_list(mandatory = False),
|
||||
#
|
||||
# Optional name of the output subdirectory with pkgconfig files.
|
||||
"out_pkg_config_dir": attr.string(mandatory = False),
|
||||
# link to the shell utilities used by the shell script in cc_external_rule_impl.
|
||||
"_utils": attr.label(
|
||||
default = Label("//tools/build_defs:utils.sh"),
|
||||
allow_single_file = True,
|
||||
executable = True,
|
||||
cfg = "target",
|
||||
),
|
||||
# we need to declare this attribute to access cc_toolchain
|
||||
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
|
||||
}
|
||||
|
||||
def create_attrs(attr_struct, configure_name, configure_script, **kwargs):
|
||||
""" Function for adding/modifying context attributes struct (originally from ctx.attr),
|
||||
provided by user, to be passed to the cc_external_rule_impl function as a struct.
|
||||
""" Function for adding/modifying context attributes struct (originally from ctx.attr),
|
||||
provided by user, to be passed to the cc_external_rule_impl function as a struct.
|
||||
|
||||
Copies a struct 'attr_struct' values (with attributes from CC_EXTERNAL_RULE_ATTRIBUTES)
|
||||
to the resulting struct, adding or replacing attributes passed in 'configure_name',
|
||||
'configure_script', and '**kwargs' parameters.
|
||||
"""
|
||||
dict = {}
|
||||
for key in CC_EXTERNAL_RULE_ATTRIBUTES:
|
||||
if not key.startswith("_") and hasattr(attr_struct, key):
|
||||
dict[key] = getattr(attr_struct, key)
|
||||
Copies a struct 'attr_struct' values (with attributes from CC_EXTERNAL_RULE_ATTRIBUTES)
|
||||
to the resulting struct, adding or replacing attributes passed in 'configure_name',
|
||||
'configure_script', and '**kwargs' parameters.
|
||||
"""
|
||||
dict = {}
|
||||
for key in CC_EXTERNAL_RULE_ATTRIBUTES:
|
||||
if not key.startswith("_") and hasattr(attr_struct, key):
|
||||
dict[key] = getattr(attr_struct, key)
|
||||
|
||||
dict["configure_name"] = configure_name
|
||||
dict["configure_script"] = configure_script
|
||||
dict["configure_name"] = configure_name
|
||||
dict["configure_script"] = configure_script
|
||||
|
||||
for arg in kwargs:
|
||||
dict[arg] = kwargs[arg]
|
||||
return struct(**dict)
|
||||
for arg in kwargs:
|
||||
dict[arg] = kwargs[arg]
|
||||
return struct(**dict)
|
||||
|
||||
def cc_external_rule_impl(ctx, attrs):
|
||||
""" Framework function for performing external C/C++ building.
|
||||
""" Framework function for performing external C/C++ building.
|
||||
|
||||
To be used to build external libraries or/and binaries with CMake, configure/make, autotools etc.,
|
||||
and use results in Bazel.
|
||||
It is possible to use it to build a group of external libraries, that depend on each other or on
|
||||
Bazel library, and pass nessesary tools.
|
||||
To be used to build external libraries or/and binaries with CMake, configure/make, autotools etc.,
|
||||
and use results in Bazel.
|
||||
It is possible to use it to build a group of external libraries, that depend on each other or on
|
||||
Bazel library, and pass nessesary tools.
|
||||
|
||||
Accepts the actual commands for build configuration/execution in attrs.
|
||||
Accepts the actual commands for build configuration/execution in attrs.
|
||||
|
||||
Creates and runs a shell script, which:
|
||||
Creates and runs a shell script, which:
|
||||
|
||||
1) prepares directory structure with sources, dependencies, and tools symlinked into subdirectories
|
||||
of the execroot directory. Adds tools into PATH.
|
||||
2) defines the correct absolute paths in tools with the script paths, see 7
|
||||
3) defines the following environment variables:
|
||||
EXT_BUILD_ROOT: execroot directory
|
||||
EXT_BUILD_DEPS: subdirectory of execroot, which contains the following subdirectories:
|
||||
include - here the include directories are symlinked
|
||||
lib - here the library files are symlinked
|
||||
lib/pkgconfig - here the pkgconfig files are symlinked
|
||||
bin - here the tools are copied
|
||||
INSTALLDIR: subdirectory of the execroot (named by the lib_name), where the library/binary
|
||||
will be installed
|
||||
1) prepares directory structure with sources, dependencies, and tools symlinked into subdirectories
|
||||
of the execroot directory. Adds tools into PATH.
|
||||
2) defines the correct absolute paths in tools with the script paths, see 7
|
||||
3) defines the following environment variables:
|
||||
EXT_BUILD_ROOT: execroot directory
|
||||
EXT_BUILD_DEPS: subdirectory of execroot, which contains the following subdirectories:
|
||||
include - here the include directories are symlinked
|
||||
lib - here the library files are symlinked
|
||||
lib/pkgconfig - here the pkgconfig files are symlinked
|
||||
bin - here the tools are copied
|
||||
INSTALLDIR: subdirectory of the execroot (named by the lib_name), where the library/binary
|
||||
will be installed
|
||||
|
||||
These variables should be used by the calling rule to refer to the created directory structure.
|
||||
4) calls 'attrs.configure_script'
|
||||
5) calls 'attrs.make_commands'
|
||||
6) calls 'attrs.postfix_script'
|
||||
7) replaces absolute paths in possibly created scripts with a placeholder value
|
||||
These variables should be used by the calling rule to refer to the created directory structure.
|
||||
4) calls 'attrs.configure_script'
|
||||
5) calls 'attrs.make_commands'
|
||||
6) calls 'attrs.postfix_script'
|
||||
7) replaces absolute paths in possibly created scripts with a placeholder value
|
||||
|
||||
Please see cmake.bzl for example usage.
|
||||
Please see cmake.bzl for example usage.
|
||||
|
||||
Args:
|
||||
ctx: calling rule context
|
||||
attrs: struct with fields from CC_EXTERNAL_RULE_ATTRIBUTES (see descriptions there), and
|
||||
two mandatory fields:
|
||||
configure_name: name of the configuration tool, to be used in action mnemonic
|
||||
configure_script: actual configuration script
|
||||
All other fields are ignored.
|
||||
"""
|
||||
lib_name = _value(attrs.lib_name, ctx.attr.name)
|
||||
Args:
|
||||
ctx: calling rule context
|
||||
attrs: struct with fields from CC_EXTERNAL_RULE_ATTRIBUTES (see descriptions there), and
|
||||
two mandatory fields:
|
||||
configure_name: name of the configuration tool, to be used in action mnemonic
|
||||
configure_script: actual configuration script
|
||||
All other fields are ignored.
|
||||
"""
|
||||
lib_name = _value(attrs.lib_name, ctx.attr.name)
|
||||
|
||||
inputs = _define_inputs(attrs)
|
||||
outputs = _define_outputs(ctx, attrs, lib_name)
|
||||
out_cc_info = _define_out_cc_info(ctx, attrs, inputs, outputs)
|
||||
inputs = _define_inputs(attrs)
|
||||
outputs = _define_outputs(ctx, attrs, lib_name)
|
||||
out_cc_info = _define_out_cc_info(ctx, attrs, inputs, outputs)
|
||||
|
||||
shell_utils = ctx.attr._utils.files.to_list()[0].path
|
||||
shell_utils = ctx.attr._utils.files.to_list()[0].path
|
||||
|
||||
script_lines = [
|
||||
"set -e",
|
||||
"EXT_BUILD_ROOT=$(pwd)",
|
||||
"source " + shell_utils,
|
||||
"echo \"Building external library '{}'\"".format(lib_name),
|
||||
"TMPDIR=$(mktemp -d)",
|
||||
"trap \"{ rm -rf $TMPDIR; }\" EXIT",
|
||||
"EXT_BUILD_DEPS=$(mktemp -d --tmpdir=$EXT_BUILD_ROOT)",
|
||||
"\n".join(_copy_deps_and_tools(inputs)),
|
||||
"define_absolute_paths $EXT_BUILD_ROOT/bin $EXT_BUILD_ROOT/bin",
|
||||
"INSTALLDIR=$EXT_BUILD_ROOT/" + outputs.installdir.path,
|
||||
"mkdir -p $INSTALLDIR",
|
||||
"echo_vars INSTALLDIR EXT_BUILD_DEPS EXT_BUILD_ROOT PATH",
|
||||
"pushd $TMPDIR",
|
||||
attrs.configure_script,
|
||||
"\n".join(attrs.make_commands),
|
||||
_value(attrs.postfix_script, ""),
|
||||
"replace_absolute_paths $INSTALLDIR $INSTALLDIR",
|
||||
"popd",
|
||||
]
|
||||
script_lines = [
|
||||
"set -e",
|
||||
"export EXT_BUILD_ROOT=$(pwd)",
|
||||
"source " + shell_utils,
|
||||
"echo \"Building external library '{}'\"".format(lib_name),
|
||||
"TMPDIR=$(mktemp -d)",
|
||||
"trap \"{ rm -rf $TMPDIR; }\" EXIT",
|
||||
"export EXT_BUILD_DEPS=$(mktemp -d --tmpdir=$EXT_BUILD_ROOT)",
|
||||
"\n".join(_copy_deps_and_tools(inputs)),
|
||||
"define_absolute_paths $EXT_BUILD_ROOT/bin $EXT_BUILD_ROOT/bin",
|
||||
"export INSTALLDIR=$EXT_BUILD_ROOT/" + outputs.installdir.path,
|
||||
"mkdir -p $INSTALLDIR",
|
||||
"echo_vars INSTALLDIR EXT_BUILD_DEPS EXT_BUILD_ROOT PATH",
|
||||
"pushd $TMPDIR",
|
||||
attrs.configure_script,
|
||||
"\n".join(attrs.make_commands),
|
||||
_value(attrs.postfix_script, ""),
|
||||
"replace_absolute_paths $INSTALLDIR $INSTALLDIR",
|
||||
"popd",
|
||||
]
|
||||
|
||||
script_text = '\n'.join(script_lines)
|
||||
script_text = "\n".join(script_lines)
|
||||
|
||||
ctx.actions.run_shell(
|
||||
mnemonic="Cc" + attrs.configure_name.capitalize() + "MakeRule",
|
||||
inputs = inputs.declared_inputs,
|
||||
outputs = outputs.declared_outputs,
|
||||
tools = ctx.attr._utils.files,
|
||||
use_default_shell_env=True,
|
||||
command = script_text,
|
||||
execution_requirements = {"block-network": ""}
|
||||
)
|
||||
ctx.actions.run_shell(
|
||||
mnemonic = "Cc" + attrs.configure_name.capitalize() + "MakeRule",
|
||||
inputs = inputs.declared_inputs,
|
||||
outputs = outputs.declared_outputs,
|
||||
tools = ctx.attr._utils.files,
|
||||
use_default_shell_env = True,
|
||||
command = script_text,
|
||||
execution_requirements = {"block-network": ""},
|
||||
)
|
||||
|
||||
return [DefaultInfo(files = depset(direct = outputs.declared_outputs)),
|
||||
OutputGroupInfo(gen_dir = depset([outputs.installdir]),
|
||||
bin_dir = depset([outputs.out_bin_dir]),
|
||||
out_binary_files = depset(outputs.out_binary_files),
|
||||
pkg_config_dir = outputs.out_pkg_dir or []),
|
||||
cc_common.create_cc_skylark_info(ctx=ctx),
|
||||
out_cc_info.compilation_info,
|
||||
out_cc_info.linking_info,
|
||||
]
|
||||
return [
|
||||
DefaultInfo(files = depset(direct = outputs.declared_outputs)),
|
||||
OutputGroupInfo(
|
||||
gen_dir = depset([outputs.installdir]),
|
||||
bin_dir = depset([outputs.out_bin_dir]),
|
||||
out_binary_files = depset(outputs.out_binary_files),
|
||||
pkg_config_dir = outputs.out_pkg_dir or [],
|
||||
),
|
||||
cc_common.create_cc_skylark_info(ctx = ctx),
|
||||
out_cc_info.compilation_info,
|
||||
out_cc_info.linking_info,
|
||||
]
|
||||
|
||||
def _value(value, default_value):
|
||||
if (value):
|
||||
return value
|
||||
return default_value
|
||||
if (value):
|
||||
return value
|
||||
return default_value
|
||||
|
||||
def _depset(item):
|
||||
if item == None:
|
||||
return depset()
|
||||
return depset([item])
|
||||
if item == None:
|
||||
return depset()
|
||||
return depset([item])
|
||||
|
||||
def _list(item):
|
||||
if item:
|
||||
return [item]
|
||||
return []
|
||||
if item:
|
||||
return [item]
|
||||
return []
|
||||
|
||||
def _copy_deps_and_tools(files):
|
||||
list = []
|
||||
list += _symlink_to_dir("lib", files.libs, False)
|
||||
list += _symlink_to_dir("include", files.headers, True)
|
||||
list += _symlink_to_dir("lib/pkgconfig", files.pkg_configs, False)
|
||||
list += _symlink_to_dir("bin", files.tools_files, False)
|
||||
list = []
|
||||
list += _symlink_to_dir("lib", files.libs, False)
|
||||
list += _symlink_to_dir("include", files.headers, True)
|
||||
list += _symlink_to_dir("lib/pkgconfig", files.pkg_configs, False)
|
||||
list += _symlink_to_dir("bin", files.tools_files, False)
|
||||
|
||||
list += ["if [ -d $EXT_BUILD_DEPS/bin ]; then"]
|
||||
list += [" tools=$(find $EXT_BUILD_DEPS/bin -type d,l -maxdepth 1)"]
|
||||
list += [" for tool in $tools; do export PATH=$PATH:$tool; done"]
|
||||
list += ["fi"]
|
||||
list += ["path $EXT_BUILD_DEPS/bin"]
|
||||
list += ["export PKG_CONFIG_PATH=$EXT_BUILD_ROOT/lib/pkgconfig"]
|
||||
list += ["if [ -d $EXT_BUILD_DEPS/bin ]; then"]
|
||||
list += [" tools=$(find $EXT_BUILD_DEPS/bin -type d,l -maxdepth 1)"]
|
||||
list += [" for tool in $tools; do export PATH=$PATH:$tool; done"]
|
||||
list += ["fi"]
|
||||
list += ["path $EXT_BUILD_DEPS/bin"]
|
||||
list += ["export PKG_CONFIG_PATH=$EXT_BUILD_ROOT/lib/pkgconfig"]
|
||||
|
||||
return list
|
||||
return list
|
||||
|
||||
def _symlink_to_dir(dir_name, files_list, link_children):
|
||||
if len(files_list) == 0:
|
||||
return []
|
||||
list = ["mkdir -p $EXT_BUILD_DEPS/" + dir_name]
|
||||
if len(files_list) == 0:
|
||||
return []
|
||||
list = ["mkdir -p $EXT_BUILD_DEPS/" + dir_name]
|
||||
|
||||
paths_list = []
|
||||
for file in files_list:
|
||||
paths_list += [file if type(file) == "string" else file.path]
|
||||
paths_list = []
|
||||
for file in files_list:
|
||||
paths_list += [file if type(file) == "string" else file.path]
|
||||
|
||||
link_function = "symlink_dir_contents_to_dir" if link_children else "symlink_to_dir"
|
||||
for path in paths_list:
|
||||
list += ["{} $EXT_BUILD_ROOT/{} $EXT_BUILD_DEPS/{}".format(link_function, path, dir_name)]
|
||||
link_function = "symlink_dir_contents_to_dir" if link_children else "symlink_to_dir"
|
||||
for path in paths_list:
|
||||
list += ["{} $EXT_BUILD_ROOT/{} $EXT_BUILD_DEPS/{}".format(link_function, path, dir_name)]
|
||||
|
||||
return list
|
||||
return list
|
||||
|
||||
def _check_file_name(var, name):
|
||||
if (len(var) == 0):
|
||||
fail("{} can not be empty string.".format(name.capitalize()))
|
||||
if (len(var) == 0):
|
||||
fail("{} can not be empty string.".format(name.capitalize()))
|
||||
|
||||
if (not var[0:1].isalpha()):
|
||||
fail("{} should start with a letter.".format(name.capitalize()))
|
||||
if (not var[0:1].isalpha()):
|
||||
fail("{} should start with a letter.".format(name.capitalize()))
|
||||
for index in range(1, len(var) - 1):
|
||||
letter = var[index]
|
||||
if not letter.isalnum() and letter != '_':
|
||||
|
@ -265,58 +272,58 @@ _Outputs = provider(
|
|||
out_binary_files = "Binary files, which will be created by the action",
|
||||
libraries = "Library files, which will be created by the action",
|
||||
declared_outputs = "All output files and directories of the action",
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
def _define_outputs(ctx, attrs, lib_name):
|
||||
static_libraries = []
|
||||
if (not (hasattr(attrs, "static_libraries") and len(attrs.static_libraries) > 0) and
|
||||
static_libraries = []
|
||||
if (not (hasattr(attrs, "static_libraries") and len(attrs.static_libraries) > 0) and
|
||||
not (hasattr(attrs, "shared_libraries") and len(attrs.shared_libraries) > 0) and
|
||||
not (hasattr(attrs, "interface_libraries") and len(attrs.interface_libraries) > 0) and
|
||||
not (hasattr(attrs, "binaries") and len(attrs.binaries) > 0)):
|
||||
static_libraries = [lib_name + (".lib" if targets_windows(ctx, None) else ".a")]
|
||||
else:
|
||||
static_libraries = attrs.static_libraries
|
||||
static_libraries = [lib_name + (".lib" if targets_windows(ctx, None) else ".a")]
|
||||
else:
|
||||
static_libraries = attrs.static_libraries
|
||||
|
||||
_check_file_name(lib_name, "Library name")
|
||||
_check_file_name(lib_name, "Library name")
|
||||
|
||||
out_binary_files = []
|
||||
for file in attrs.binaries:
|
||||
out_binary_files += [_declare_out(ctx, lib_name, attrs.out_bin_dir, file)]
|
||||
out_binary_files = []
|
||||
for file in attrs.binaries:
|
||||
out_binary_files += [_declare_out(ctx, lib_name, attrs.out_bin_dir, file)]
|
||||
|
||||
out_pkg_dir = None
|
||||
if attrs.out_pkg_config_dir:
|
||||
out_pkg_dir = ctx.actions.declare_file("/".join([lib_name, attrs.out_pkg_config_dir]))
|
||||
out_pkg_dir = None
|
||||
if attrs.out_pkg_config_dir:
|
||||
out_pkg_dir = ctx.actions.declare_file("/".join([lib_name, attrs.out_pkg_config_dir]))
|
||||
|
||||
installdir = ctx.actions.declare_directory(lib_name)
|
||||
out_include_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_include_dir)
|
||||
out_bin_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_bin_dir)
|
||||
out_lib_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_lib_dir)
|
||||
installdir = ctx.actions.declare_directory(lib_name)
|
||||
out_include_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_include_dir)
|
||||
out_bin_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_bin_dir)
|
||||
out_lib_dir = ctx.actions.declare_directory(lib_name + "/" + attrs.out_lib_dir)
|
||||
|
||||
libraries = LibrariesToLinkInfo(
|
||||
static_libraries = _declare_out(ctx, lib_name, out_lib_dir, static_libraries),
|
||||
shared_libraries = _declare_out(ctx, lib_name, out_lib_dir, attrs.shared_libraries),
|
||||
interface_libraries = _declare_out(ctx, lib_name, out_lib_dir, attrs.interface_libraries),
|
||||
)
|
||||
declared_outputs = [installdir, out_include_dir, out_bin_dir, out_lib_dir] + out_binary_files
|
||||
declared_outputs += _list(out_pkg_dir) + libraries.static_libraries
|
||||
declared_outputs += libraries.shared_libraries + libraries.interface_libraries
|
||||
libraries = LibrariesToLinkInfo(
|
||||
static_libraries = _declare_out(ctx, lib_name, out_lib_dir, static_libraries),
|
||||
shared_libraries = _declare_out(ctx, lib_name, out_lib_dir, attrs.shared_libraries),
|
||||
interface_libraries = _declare_out(ctx, lib_name, out_lib_dir, attrs.interface_libraries),
|
||||
)
|
||||
declared_outputs = [installdir, out_include_dir, out_bin_dir, out_lib_dir] + out_binary_files
|
||||
declared_outputs += _list(out_pkg_dir) + libraries.static_libraries
|
||||
declared_outputs += libraries.shared_libraries + libraries.interface_libraries
|
||||
|
||||
return _Outputs(
|
||||
installdir = installdir,
|
||||
out_include_dir = out_include_dir,
|
||||
out_bin_dir = out_bin_dir,
|
||||
out_lib_dir = out_lib_dir,
|
||||
out_pkg_dir = out_pkg_dir,
|
||||
out_binary_files = out_binary_files,
|
||||
libraries = libraries,
|
||||
declared_outputs = declared_outputs,
|
||||
)
|
||||
return _Outputs(
|
||||
installdir = installdir,
|
||||
out_include_dir = out_include_dir,
|
||||
out_bin_dir = out_bin_dir,
|
||||
out_lib_dir = out_lib_dir,
|
||||
out_pkg_dir = out_pkg_dir,
|
||||
out_binary_files = out_binary_files,
|
||||
libraries = libraries,
|
||||
declared_outputs = declared_outputs,
|
||||
)
|
||||
|
||||
def _declare_out(ctx, lib_name, dir, files):
|
||||
if files and len(files) > 0:
|
||||
return [ctx.actions.declare_file("/".join([lib_name, dir.basename, file])) for file in files]
|
||||
return []
|
||||
if files and len(files) > 0:
|
||||
return [ctx.actions.declare_file("/".join([lib_name, dir.basename, file])) for file in files]
|
||||
return []
|
||||
|
||||
_InputFiles = provider(
|
||||
doc = """Provider to keep different kinds of input files, directories,
|
||||
|
@ -331,45 +338,45 @@ to be copied into the bin folder, which is added to the PATH""",
|
|||
PKG_CONFIG_PATH is assigned to that folder""",
|
||||
deps_compilation_info = "Merged CcCompilationInfo from deps attribute",
|
||||
deps_linking_info = "Merged CcLinkingInfo from deps attribute",
|
||||
declared_inputs = "All files and directories that must be declared as action inputs"
|
||||
)
|
||||
declared_inputs = "All files and directories that must be declared as action inputs",
|
||||
),
|
||||
)
|
||||
|
||||
def _define_inputs(attrs):
|
||||
pkg_configs = []
|
||||
compilation_infos = []
|
||||
linking_infos = []
|
||||
pkg_configs = []
|
||||
compilation_infos = []
|
||||
linking_infos = []
|
||||
|
||||
for dep in attrs.deps:
|
||||
compilation_infos += [dep[CcCompilationInfo]]
|
||||
linking_infos += [dep[CcLinkingInfo]]
|
||||
for dep in attrs.deps:
|
||||
compilation_infos += [dep[CcCompilationInfo]]
|
||||
linking_infos += [dep[CcLinkingInfo]]
|
||||
|
||||
provider = dep[OutputGroupInfo]
|
||||
if provider and hasattr(provider, "pkg_config_dir"):
|
||||
# or do we want to be able to produce several files?
|
||||
pkg_configs += provider.pkg_config_dir.to_list()
|
||||
provider = dep[OutputGroupInfo]
|
||||
if provider and hasattr(provider, "pkg_config_dir"):
|
||||
# or do we want to be able to produce several files?
|
||||
pkg_configs += provider.pkg_config_dir.to_list()
|
||||
|
||||
tools_roots = []
|
||||
tools_files = []
|
||||
for tool in attrs.tools_deps:
|
||||
tool_root = detect_root(tool)
|
||||
tools_roots += [tool_root]
|
||||
for file_list in tool.files.to_list():
|
||||
tools_files += _list(file_list)
|
||||
tools_roots = []
|
||||
tools_files = []
|
||||
for tool in attrs.tools_deps:
|
||||
tool_root = detect_root(tool)
|
||||
tools_roots += [tool_root]
|
||||
for file_list in tool.files.to_list():
|
||||
tools_files += _list(file_list)
|
||||
|
||||
for tool in attrs.additional_tools:
|
||||
for file_list in tool.files.to_list():
|
||||
tools_files += _list(file_list)
|
||||
for tool in attrs.additional_tools:
|
||||
for file_list in tool.files.to_list():
|
||||
tools_files += _list(file_list)
|
||||
|
||||
deps_compilation = cc_common.merge_cc_compilation_infos(cc_compilation_infos = compilation_infos)
|
||||
deps_linking = cc_common.merge_cc_linking_infos(cc_linking_infos = linking_infos)
|
||||
deps_compilation = cc_common.merge_cc_compilation_infos(cc_compilation_infos = compilation_infos)
|
||||
deps_linking = cc_common.merge_cc_linking_infos(cc_linking_infos = linking_infos)
|
||||
|
||||
(libs, linkopts) = _collect_libs_and_flags(deps_linking)
|
||||
headers = []
|
||||
for cc_info in compilation_infos:
|
||||
headers += _get_headers(cc_info)
|
||||
(libs, linkopts) = _collect_libs_and_flags(deps_linking)
|
||||
headers = []
|
||||
for cc_info in compilation_infos:
|
||||
headers += _get_headers(cc_info)
|
||||
|
||||
return _InputFiles(
|
||||
return _InputFiles(
|
||||
headers = headers,
|
||||
libs = libs,
|
||||
deps_linkopts = linkopts,
|
||||
|
@ -378,70 +385,83 @@ def _define_inputs(attrs):
|
|||
deps_compilation_info = deps_compilation,
|
||||
deps_linking_info = deps_linking,
|
||||
declared_inputs = depset(attrs.lib_source.files) + libs + tools_files + pkg_configs +
|
||||
attrs.additional_inputs + deps_compilation.headers
|
||||
)
|
||||
attrs.additional_inputs + deps_compilation.headers,
|
||||
)
|
||||
|
||||
def _get_headers(compilation_info):
|
||||
include_dirs = collections.uniq(compilation_info.system_includes.to_list())
|
||||
headers = []
|
||||
for header in compilation_info.headers:
|
||||
path = header.path
|
||||
included = False
|
||||
for dir in include_dirs:
|
||||
if path.startswith(dir):
|
||||
included = True
|
||||
break
|
||||
if not included:
|
||||
headers += [header]
|
||||
return headers + include_dirs
|
||||
include_dirs = collections.uniq(compilation_info.system_includes.to_list())
|
||||
headers = []
|
||||
for header in compilation_info.headers:
|
||||
path = header.path
|
||||
included = False
|
||||
for dir in include_dirs:
|
||||
if path.startswith(dir):
|
||||
included = True
|
||||
break
|
||||
if not included:
|
||||
headers += [header]
|
||||
return headers + include_dirs
|
||||
|
||||
def _define_out_cc_info(ctx, attrs, inputs, outputs):
|
||||
compilation_info = CcCompilationInfo(headers = depset([outputs.out_include_dir]),
|
||||
system_includes = depset([outputs.out_include_dir.path]),
|
||||
defines = depset(attrs.defines))
|
||||
out_compilation_info = cc_common.merge_cc_compilation_infos(
|
||||
cc_compilation_infos = [inputs.deps_compilation_info, compilation_info])
|
||||
compilation_info = CcCompilationInfo(
|
||||
headers = depset([outputs.out_include_dir]),
|
||||
system_includes = depset([outputs.out_include_dir.path]),
|
||||
defines = depset(attrs.defines),
|
||||
)
|
||||
out_compilation_info = cc_common.merge_cc_compilation_infos(
|
||||
cc_compilation_infos = [inputs.deps_compilation_info, compilation_info],
|
||||
)
|
||||
|
||||
linkopts = depset(direct = attrs.linkopts, transitive = [depset(inputs.deps_linkopts)])
|
||||
linking_info = create_linking_info(ctx, linkopts, outputs.libraries)
|
||||
out_linking_info = cc_common.merge_cc_linking_infos(
|
||||
cc_linking_infos = [inputs.deps_linking_info, linking_info])
|
||||
linkopts = depset(direct = attrs.linkopts, transitive = [depset(inputs.deps_linkopts)])
|
||||
linking_info = create_linking_info(ctx, linkopts, outputs.libraries)
|
||||
out_linking_info = cc_common.merge_cc_linking_infos(
|
||||
cc_linking_infos = [inputs.deps_linking_info, linking_info],
|
||||
)
|
||||
|
||||
return struct(
|
||||
compilation_info = out_compilation_info,
|
||||
linking_info = out_linking_info
|
||||
)
|
||||
return struct(
|
||||
compilation_info = out_compilation_info,
|
||||
linking_info = out_linking_info,
|
||||
)
|
||||
|
||||
def _collect_libs_and_flags(cc_linking):
|
||||
libs = []
|
||||
linkopts = []
|
||||
libs = []
|
||||
linkopts = []
|
||||
|
||||
for params in [cc_linking.static_mode_params_for_dynamic_library,
|
||||
cc_linking.static_mode_params_for_executable,
|
||||
cc_linking.dynamic_mode_params_for_dynamic_library,
|
||||
cc_linking.dynamic_mode_params_for_executable]:
|
||||
libs += [lib.artifact() for lib in params.libraries_to_link.to_list()]
|
||||
libs += params.dynamic_libraries_for_runtime.to_list()
|
||||
linkopts = params.linkopts.to_list()
|
||||
for params in [
|
||||
cc_linking.static_mode_params_for_dynamic_library,
|
||||
cc_linking.static_mode_params_for_executable,
|
||||
cc_linking.dynamic_mode_params_for_dynamic_library,
|
||||
cc_linking.dynamic_mode_params_for_executable,
|
||||
]:
|
||||
libs += [lib.artifact() for lib in params.libraries_to_link.to_list()]
|
||||
libs += params.dynamic_libraries_for_runtime.to_list()
|
||||
linkopts = params.linkopts.to_list()
|
||||
|
||||
return (collections.uniq(libs), collections.uniq(linkopts))
|
||||
return (collections.uniq(libs), collections.uniq(linkopts))
|
||||
|
||||
def detect_root(source):
|
||||
"""Detects the path to the topmost directory of the 'source' outputs.
|
||||
To be used with external build systems to point to the source code/tools directories.
|
||||
"""Detects the path to the topmost directory of the 'source' outputs.
|
||||
To be used with external build systems to point to the source code/tools directories.
|
||||
|
||||
If the target groups the sources of the external dependency, the workspace root is used,
|
||||
and no other checks are performed (i.e. it is assumed that the whole contents of the external
|
||||
dependency is used).
|
||||
Otherwise, for the "usual" targets, target's files are iterated and the path with the least length
|
||||
is selected.
|
||||
"""
|
||||
root = source.label.workspace_root
|
||||
sources = source.files
|
||||
if (not root or len(root) == 0) and len(sources) > 0:
|
||||
root = ""
|
||||
# find topmost directory
|
||||
for file in sources:
|
||||
if len(root) == 0 or len(root) > len(file.path):
|
||||
root = file.path
|
||||
return root
|
||||
If the target groups the sources of the external dependency, the workspace root is used,
|
||||
and no other checks are performed (i.e. it is assumed that the whole contents of the external
|
||||
dependency is used).
|
||||
Otherwise, for the "usual" targets, target's files are iterated and the path with the least length
|
||||
is selected.
|
||||
"""
|
||||
root = source.label.workspace_root
|
||||
sources = source.files
|
||||
if (not root or len(root) == 0) and len(sources) > 0:
|
||||
root = ""
|
||||
|
||||
# find topmost directory
|
||||
for file in sources:
|
||||
if len(root) == 0 or len(root) > len(file.path):
|
||||
root = file.path
|
||||
else:
|
||||
return root
|
||||
|
||||
(before, sep, after) = root.rpartition("/")
|
||||
if before and sep and after:
|
||||
return before
|
||||
return root
|
||||
|
|