How to use Facebook BUCK with DTrace files? - objective-c

So, if you open https://github.com/airbnb/BuckSample
And will try to install with cocoaPods https://github.com/ReactiveCocoa/ReactiveObjC
and after you'll add a new BUCK build rule like
apple_third_party_lib(
name = "ReactiveObjC",
visibility = ["PUBLIC"],
srcs = glob([
"ReactiveObjC/**/*.m",
]),
exported_headers = glob([
"ReactiveObjC/**/*.h",
]),
frameworks = [
"$PLATFORM_DIR/Developer/Library/Frameworks/Foundation.framework",
],
)
buck build //Pods:ReactiveObjC will fail with error like this
Pods/ReactiveObjC/ReactiveObjC/RACPassthroughSubscriber.m:12:9: fatal error: 'RACSignalProvider.h' file not found
If we go further we'll see that RACSignalProvider.h is not in the Pod sources, but there is RACSignalProvider.d which is DTrace source file.
When we try to compile it with XCode we can see that there is an extra step before compiling actual framwork
CompileDTraceScript /*user folder*/Pods/ReactiveObjC/ReactiveObjC/RACSignalProvider.d (in target 'ReactiveObjC' from project 'Pods')
cd /*user folder*/Pods
/usr/sbin/dtrace -h -s /*user folder*/Pods/ReactiveObjC/ReactiveObjC/RACSignalProvider.d -o /*user folder*/Library/Developer/Xcode/DerivedData/Odnoklassniki-gsukbcogkxolydbhlpglswzdhhpg/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/ReactiveObjC.build/DerivedSources/RACSignalProvider.h
which is not happening when we run buck build
Is there something missing from config? Or this just not supported by BUCK?

So the answer is, you need to use a genrule() to process your DTrace files
It should look like
genrule(
name = "ReactiveObjC_DTrace",
srcs = [
"ReactiveObjC/ReactiveObjC/RACSignalProvider.d",
"ReactiveObjC/ReactiveObjC/RACCompoundDisposableProvider.d",
],
bash =
"""
mkdir -p $OUT
/usr/sbin/dtrace -h -s $SRCDIR/ReactiveObjC/ReactiveObjC/RACSignalProvider.d -o $OUT/RACSignalProvider.h
/usr/sbin/dtrace -h -s $SRCDIR/ReactiveObjC/ReactiveObjC/RACCompoundDisposableProvider.d -o $OUT/RACCompoundDisposableProvider.h
""",
out = "ReactiveObjC_DTrace",
visibility = ["PUBLIC"]
)
And then modify your ReactiveObjC rule to look like
apple_third_party_lib(
name = "ReactiveObjC",
visibility = ["PUBLIC"],
srcs = glob([
"ReactiveObjC/**/*.m",
]),
deps = [
"//Pods:ReactiveObjC_DTrace",
],
exported_headers = glob([
"ReactiveObjC/**/*.h",
"$(location :ReactiveObjC_DTrace)/**/*.h"
]),
frameworks = [
"$PLATFORM_DIR/Developer/Library/Frameworks/Foundation.framework",
],
)

Related

How to call a bash script from cmake and pass a generator dependent string as argument?

While using the Unix Makefiles generator I have added the following to a CMakeLists.txt file:
add_custom_target(maintainer-clean
# The current directory is CMAKE_CURRENT_BINARY_DIR.
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cwm4/scripts/cmake_maintainer_clean.sh $(MAKE) \"${GITACHE_PACKAGES}\"
)
This cmake_maintainer_clean.sh script is make specific, and it needs to use $(MAKE) in the generated Makefile when calling the script.
However, when switching to the generator Ninja this custom command is put as-is in the build.ninja file, causing the $ of the $(MAKE) to cause problems (ninja refuses to run any target, failing to parse build.ninja).
Therefore, I wish to make this generator-specific. How can I use $(MAKE) as first argument to the script when the generator is Unix Makefiles and something else, without a $ - e.g. "ninja" - when the generator is Ninja?
Can I do something like:
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cwm4/scripts/cmake_maintainer_clean.sh $<UNIX:$(MAKE),ninja> \"${GITACHE_PACKAGES}\"
?
I would make separate presets for each generator, so you can associate a particular environment variable with it. Here is how the CMakePresets.json file may look like:
{
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "base",
"binaryDir": "${sourceDir}/build",
"hidden": true
},
{
"name": "Ninja",
"inherits": "base",
"displayName": "Ninja Config",
"generator": "Ninja",
"environment": {
"SCRIPT_ARG": "Ninja"
}
},
{
"name": "Make",
"inherits": "base",
"displayName": "Make Config",
"generator": "Unix Makefiles",
"environment": {
"SCRIPT_ARG": "Make"
}
}
]
}
Where the SCRIPT_ARG can be read later inside of the CMakeLists.txt configuration:
cmake_minimum_required(VERSION 3.20)
project(Hello)
add_executable(Hello main.cpp)
add_custom_target(my-script
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/script.sh $ENV{SCRIPT_ARG}
)
add_dependencies(Hello my-script)
Providing script.sh is as simple as this:
#!/bin/sh
echo "Hello from script, $1!"
You will end up with the following output during build phase:
% cmake --preset Make
...
% cmake --build build
Hello from script, Make!
[ 0%] Built target my-script
...
Corresponding output for Ninja generator would be:
% cmake --preset Ninja
...
% cmake --build build
Hello from script, Ninja!
[ 0%] Built target my-script
...
If you need something more complex than an environment variable, you can introduce condition statement based on value of CMAKE_GENERATOR:
cmake_minimum_required(VERSION 3.20)
project(Hello)
add_executable(Hello main.cpp)
if(CMAKE_GENERATOR STREQUAL Ninja)
add_custom_target(my-script COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/script.sh $ENV{SCRIPT_ARG})
elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
add_custom_target(my-script COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/another_script.sh)
endif()
add_dependencies(Hello my-script)
The provided solutions work at build step, and for the part whether it's possible to distinguish between generators during build system generation phase (e.g. with use of generator expressions) i don't think it's possible, because the configuration is generator-agnostic at this point.

Can I use the environment to add/replace to the CMAKE_MODULE_PATH?

Within a CMakeLists.txt file, you can write something like:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
but what if I want to "prime" that variable before the invocation of CMake? Using the environment, perhaps? Is this possible?
The documentation says it is empty by default, but I was hoping to diverge from this default.
CMAKE_MODULE_PATH is not an "cmake-env-variable". It won't read same name environment variable to initialize it automatically. As an example, CMAKE_EXPORT_COMPILE_COMMANDS can be initialized from env var (ref).
An alternative for your situation:
if(DEFINED ENV{CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH "$ENV{CMAKE_MODULE_PATH}")
else()
message(WARNING "CMAKE_MODULE_PATH env var not defined, using the default empty one")
endif()
My preferred option would be to pass this to cmake at the time of configuration.
Using command line options
cmake -D "CMAKE_MODULE_PATH:STRING=${CMAKE_MODULE_PATH}" -S ...
or
Using a cache configuration script
# initialCache.cmake
set(CMAKE_MODULE_PATH $ENV{CMAKE_MODULE_PATH} CACHE STRING "path to look for cmake modules")
cmake -C initialCache.cmake -S ...
or
Using a preset
CMakePresets.json
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0
},
"configurePresets": [
{
"name": "mypreset",
"displayName": "My preset",
"description": "Preset using the environment variable to set CMAKE_MODULE_PATH",
"cacheVariables": {
"CMAKE_MODULE_PATH": {
"type": "STRING",
"value": "$env{CMAKE_MODULE_PATH}"
}
}
}
]
}
cmake --preset mypreset -S ...

dependency and option in meson project

I have a project with a similar folder trees:
├── meson.build (1)
├── meson_options.txt
├── README.md
└── src
└── mysub
├── meson.build (2)
└── mesonTest.c
the meson.options.txt contains
option('avx_opt', type : 'combo', choices : ['avx2', 'avx512'], value : 'avx512')
the mysub project is a dependency of the main proj
so the meson.build (1) :
project(
'my_proj',
'c',
version : '1.1.0',
default_options : ['buildtype=plain','warning_level=3'],
subproject_dir : 'src'
)
project_source_files = [
''
]
message('## source root : ' + meson.project_source_root() + ' ##')
project_dependencies = [
dependency('mysub', fallback : ['mysub', 'mysub_dep']),
]
build_args = [
]
# ===================================================================
# ======
# Target
# ======
build_args += [
'-DPROJECT_NAME=' + meson.project_name(),
'-DPROJECT_VERSION=' + meson.project_version(),
]
the meson.build (2) of the mysub proj is:
project(
'mysub',
'c',
version : '1.1.0',
default_options : ['warning_level=3']
)
project_description = 'mysub binary'
project_source_files = [
'mesonTest.c'
]
project_headers = [
]
avx_type = get_option('avx_opt')
if (avx_type == 'avx512')
build_args_avx512 = [
'-mavx512f',
'-mavx512cd',
'-mavx512vl',
'-mavx512bw',
'-mavx512dq',
'-DNEWLDPC=1'
]
else
build_args_avx512 = [
'-DNEWLDPC=0'
]
endif
project_target = executable(
meson.project_name(),
project_source_files,
install : true,
c_args : build_args,
link_args : '-Wl,--allow-shlib-undefined',
)
# =======
# Project
# =======
# Make this library usable as a Meson subproject.
project_dep = declare_dependency(
include_directories: public_headers,
link_with : project_target
)
set_variable(meson.project_name() + '_dep', project_dep)
# Make this library usable from the system's
# package manager.
install_headers(project_headers, subdir : meson.project_name())
pkg_mod = import('pkgconfig')
pkg_mod.generate(
name : meson.project_name(),
filebase : meson.project_name(),
description : project_description,
subdirs : meson.project_name(),
# libraries : project_target,
)
I have tried to configure in the following way:
meson builddir -Davx_opt=avx512
or
meson builddir -Davx_opt:mysub=avx512
but in both case I got:
The Meson build system
Version: 0.59.1
Source dir: /home/roccasal/wsEclipse/Intel/mesonTest/proj
Build dir: /home/roccasal/wsEclipse/Intel/mesonTest/proj/builddir
Build type: native build
Project name: my_proj
Project version: 1.1.0
C compiler for the host machine: cc (gcc 8.5.0 "cc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4)")
C linker for the host machine: cc ld.bfd 2.30-108
Host machine cpu family: x86_64
Host machine cpu: x86_64
Message: ## source root : /home/roccasal/wsEclipse/Intel/mesonTest/proj ##
Found pkg-config: /usr/bin/pkg-config (1.4.2)
Found CMake: /usr/bin/cmake (3.20.2)
Run-time dependency mysub found: NO (tried pkgconfig and cmake)
Looking for a fallback subproject for the dependency mysub
Executing subproject mysub
mysub| Project name: mysub
mysub| Project version: 1.1.0
mysub| C compiler for the host machine: cc (gcc 8.5.0 "cc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4)")
mysub| C linker for the host machine: cc ld.bfd 2.30-108
src/mysub/meson.build:32:0: ERROR: Tried to access unknown option "avx_opt".
what is wrong in the meson build configuration?
the meson ver used is 0.59.1
//thanks
Check Build-options page in reference manual:
To change values in subprojects prepend the name of the subproject and
a colon:
$ meson configure -Dsubproject:option=newvalue
Thus, try create new build dir with:
meson builddir -Dmysub:avx_opt=avx512
or configure existing with:
meson configure builddir -Dmysub:avx_opt=avx512
To make it working you also need this option defined in meson_options.txt in every subproject that uses it, but to simplify configuration you can as #dcbaker suggested use yielding, i.e. update option definition for the main project:
option('avx_opt', ...., yield : true)
This will give you possibility to configure it the same way for main and subprojects with just:
meson configure builddir -Davx_opt=avx512
Also, (I guess it's just typo in question) file with options should have name meson_options.txt (with underscore).

Yocto include cmake project with custom steps

I am trying to include this simple cmake-based project to my image: https://github.com/MatrixOrbital/HTT-Utility
The steps to build in Linux are:
mkdir build
cd build
cmake ..
make
I am trying to reproduce these steps within my Yocto recipe. The generated binary (./build/htt_util) should be installed in /usr/bin.
So far with the help of devtool and some manual tuning I ended up with this recipe:
LICENSE = "MIT & Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=ff75ee274f4c77abeee3db089083fec7 \
file://hidapi/LICENSE.txt;md5=7c3949a631240cb6c31c50f3eb696077"
SRC_URI = "git://github.com/MatrixOrbital/HTT-Utility.git;protocol=https"
SRC_URI += "file://0001-Adding-ctype.patch;"
PATCHTOOL = "git"
# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "2045d5eacc67b89a02dafe41edfd032179333aee"
S = "${WORKDIR}/git"
inherit cmake
# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""
DEPENDS += "udev"
What should I add to my recipe to achieve the goal of generating a binary and installing into /usr/bin?
I have been trying to play with:
do_configure() {
...
}
do_compile() {
...
}
do_install() {
...
}
But so far I did not manage to do anything useful.
Any help would be appreciated.
do_install() {
install -m 0644 mybinary ${D}${bindir}
}
FILES_${PN} = " \
${bindir} \
"

Using translations of Behat predefined steps (Phar install)

I've run some tests with the predefined step definitions of Mink Extension. They work as long as they're in english language.
Now I've tried the following scenario with german steps:
# language: de
Funktionalität: Demo
#javascript
Szenario: Test 1
Angenommen I am on "/"
Angenommen ich bin auf "/"
...
Behat now tells me that the german step definition is undefined, while the english version works.
According to the CLI help, behat --lang de -dl should display the translated definitions, but it only shows me the english ones ...
What am I doing wrong here?
Edit:
Here's a script to rebuild the scenario. It follows the install steps from the docs (http://extensions.behat.org/mink/#through-phar) in a temporary directory and runs the test feature file.
#!/bin/bash
set -e
TEMPDIR=/tmp/behat-$$
mkdir $TEMPDIR
cd $TEMPDIR
curl http://behat.org/downloads/behat.phar >behat.phar
curl http://behat.org/downloads/mink.phar >mink.phar
curl http://behat.org/downloads/mink_extension.phar >mink_extension.phar
cat >behat.yml <<EOF
default:
extensions:
mink_extension.phar:
mink_loader: 'mink.phar'
base_url: 'http://behat.org'
goutte: ~
EOF
mkdir features
cat >features/test.feature <<EOF
# language: de
Funktionalität: Demo
Szenario: Öffne Startseite DE + EN
Angenommen I am on "/"
Angenommen ich bin auf "/"
EOF
php behat.phar
Basically you didn't do anything wrong.
Although the translation of Behat/Gherkin itself is included in the behat.phar file, the translations of the step definitions from MinkExtension are missing in the mink_extension.phar archive.
This seems to be the case because the build script only includes the files in MinkExtension/src/ without MinkExtension/i18n/. You could open an issue for MinkExtension at to get this fixed.
As a workaround I suggest to install Behat/Mink using composer instead of working with phar archives.
Create the following composer.json file:
{
"require": {
"behat/behat": "2.4.*#stable",
"behat/mink": "1.4.*#stable",
"behat/mink-extension": "*",
"behat/mink-goutte-driver": "*",
"behat/mink-selenium2-driver": "*"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
}
and then install it with:
curl http://getcomposer.org/installer | php
php composer.phar install