Bazel asks me to change
#import <mylibrary/myheader.h>
to
#import "mylibrary/myheader.h"
XCode is fine with < >
though, so I'm bound to keep coding and later have bazel build
fail again.
Is the library a local library? Why are you using system include syntax to
include it?
Cheers,
Dave
On Tue, Jul 14, 2015 at 2:07 PM, Jorge Canizales [email protected]
wrote:
Bazel asks me to change
import
to
import "mylibrary/myheader.h"
XCode is fine with < > though, so I'm bound to keep coding and later have bazel
build fail again.—
Reply to this email directly or view it on GitHub
https://github.com/google/bazel/issues/306.
It is a local library. The reason I was using angle brackets is I developed that code using Cocoapods to manage dependencies. Because the location on the file system of the library headers is an implementation detail of Cocoapods (which passes the appropriate flags to the compiler to find them), it serves no purpose to search them starting in the current directory. So it was < >
between libraries and " "
within libraries.
I see the style guide calls for " "
for non-system libraries. Although I think that's counterproductive when the libraries use includes = ["."]
generously, I'm happy either way :) Still, Bazel shouldn't reject what XCode accepts.
I'm running into the same issue as @jcanizales. Because we're moving from cocoapods, my coworkers and I are happy with the convention: system include ( < >
) between libraries and " "
within.
It is an aesthetic thing, and it won't stop us from adopting Bazel (it's been great so far!), but I just wanted to say that this would definitely be nice for us! Since this is an older issue, is there any update on priority?
Thanks!
+1 - It'd be awesome if this worked out of the box, because a large subset of objc code uses angle bracket includes ( see www.cocoapods.com ) None the less, I think there are a few ways to overcome this issue:
1) Replicate the directory structure made in pod install
:
In short, move the source code into directory structure the same way that cocoapods did: copy and paste them into genfiles. i.e. genfiles/SomeProject/SomeHeader.h
. Then, you can simply -isystem $(GENDIR)
and the angle brackets will resolve to the correct path. This may not work for all cases and have other complexities.
2) Use clang's built in virtual file system, VFS.
VFS can alias the <>
includes to their real location. Here is the RFC http://clang-developers.42468.n3.nabble.com/RFC-A-virtual-file-system-for-clang-td4037693.html .
The drawback here, in my testing of this, the VFS needs an absolute path to the build directory: the per compilation bazel sandbox. I'm already compiling .o files with a shell script and passing them to objc_library
, so it would be easy to generate a VFS overlay containing the absolute path of the sandbox.
2a) Use VFS and disable the sandbox. This way, you wouldn't need to have custom compiler invocations, and can generate a VFS overlay where the absolute path is the source directory.
Any update on this? It seems there are a large number of cocoapods which do this type of style. I am in the process of importing these cocoapods and rewriting their BUILD files for our purposes.
@lswith we are also doing this at Pinterest literally right now (porting our 40ish cocopods over). We ended up making a workspace rule called new_pod_repository
( https://bazel.build/versions/master/docs/be/workspace.html ). Example:
new_pod_repository(
name = "PINOperation",
url = "https://github.com/pinterest/PINOperation/archive/1.0.3.zip",
owner = "@ios-cx",
strip_prefix = "PINOperation-1.0.3",
)
During workspace loading we pull down the repo and then automatically convert the Podspec into a BUILD file using a Swift program. Then we can just refer to these as a dep like @PINOperation//:PINOperation
By making each cocoapod a separate workspace rule you get <>
imports that work in the same way (assuming you move the headers around in the same way that cocoapods does) + it also semantically to be a workspace makes sense as a workspace rule since we're getting something from a third-party.
The goal is to push as much as we can to our automated Podspec -> BUILD tool so it's easy to add/upgrade/remove pods
This is exactly what I need!!!! I would love if you open source this! It
would be a lot of help. I'm happy to help contribute as well
On Fri, 5 May 2017 at 6:58 am, Brandon Kase notifications@github.com
wrote:
@lswith https://github.com/lswith we are also doing this at Pinterest
literally right now (porting our 40ish cocopods over). We ended up making a
workspace rule called new_pod_repository (
https://bazel.build/versions/master/docs/be/workspace.html ). Example:new_pod_repository(
name = "PINOperation",
url = "https://github.com/pinterest/PINOperation/archive/1.0.3.zip",
owner = "@ios-cx",
strip_prefix = "PINOperation-1.0.3",
)During workspace loading we pull down the repo and then automatically
convert the Podspec into a BUILD file using a Swift program. Then we can
just refer to these as a dep like @PINOperation//:PINOperationBy making each cocoapod a separate workspace rule you get <> imports that
work in the same way (assuming you move the headers around in the same way
that cocoapods does) + it also semantically to be a workspace makes sense
as a workspace rule since we're getting something from a third-party.The goal is to push as much as we can to our automated Podspec -> BUILD
tool so it's easy to add/upgrade/remove pods—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/bazelbuild/bazel/issues/306#issuecomment-299306945,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA-K-yf_8naMmz4Wit1hEhkTMWKXx_Cpks5r2ju8gaJpZM4FYlDO
.
@lswith We have plans to open-source in the near future but would like to finish our migration to stress test out the integration against the complexity of podspecs (subspecs, multiplatform attributes, external pod dependencies, etc) so we're confident it'll work well for others and have comprehensive documentation.
We can also keep you in the loop before the OSS announcement if you'd like to beta test the integration (which would be great!).
perfect. Please do!
@bkase do you think you could give an example BUILD file for the FBSDKCoreKit cocoapod? I don't quite understand how the header files should be placed to allow for correct compilation by Bazel.
@lswith this is what our script generates for FBSDKCoreKit (I'm working on this one now, currently working on Bolt -- a dep of this) so I'm not sure if this will exactly work yet.
load('//:build_extensions.bzl', 'pch_with_name_hint')
FBSDKCoreKit_source_headers = [
] + glob(
[
"FBSDKCoreKit/FBSDKCoreKit/**/*.h"
],
exclude_directories = 1
)
FBSDKCoreKit_extra_headers = [
] + glob(
[
"bazel_support/Headers/Public/**/*.h"
],
exclude_directories = 1
)
FBSDKCoreKit_headers = FBSDKCoreKit_source_headers + FBSDKCoreKit_extra_headers
objc_library(
name = "FBSDKCoreKit",
srcs = [
] + glob(
[
"FBSDKCoreKit/FBSDKCoreKit/**/*.m"
],
exclude_directories = 1
) + select(
{
"//conditions:default": glob(
[
],
exclude = [
"FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/Device/**/*"
],
exclude_directories = 1
),
":tvosCase": glob(
[
],
exclude = [
"FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkResolver.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkUtility.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKMutableCopying.h",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/AppLink/**/*",
"FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/**/*",
"FBSDKCoreKit/FBSDKCoreKit/Internal/Cryptography/**/*",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSystemAccountStoreAdapter.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.{h,m}",
"FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/**/*"
],
exclude_directories = 1
)
}
),
hdrs = FBSDKCoreKit_headers,
pch = pch_with_name_hint(
"FBSDKCoreKit"
),
includes = [
"bazel_support/Headers/Public/",
"bazel_support/Headers/Public/FBSDKCoreKit/"
],
weak_sdk_frameworks = select(
{
"//conditions:default": [
"Accounts",
"CoreLocation",
"Social",
"Security",
"QuartzCore",
"CoreGraphics",
"UIKit",
"Foundation",
"AudioToolbox"
],
":tvosCase": [
"CoreLocation",
"Security",
"QuartzCore",
"CoreGraphics",
"UIKit",
"Foundation",
"AudioToolbox"
]
}
),
deps = select(
{
"//conditions:default": [
"@Bolts//:Bolts"
]
}
),
visibility = [
"//visibility:public"
]
)
]
You can see that it references bazel_support/Headers/Public/**/*.h
-- this is that header flattening. This flattening we actually do in the workspace rule, not in the BUILD file (and specifically we do this in our swift binary) -- Here is the logic for that if it helps:
// make recursive directories
shell.dir("bazel_support/Headers/Public")
shell.dir("bazel_support/Headers/Private/")
let publicHeaderdir = "bazel_support/Headers/Public/\(podspecName)"
shell.dir(publicHeaderdir)
// Create a directory structure condusive to <> imports
// - Get all of the paths matching wild card imports
// - Put them into the public header directory
let buildFile = PodBuildFile.with(podSpec: podSpec, buildOptions: buildOptions)
buildFile.skylarkConvertibles.flatMap { $0 as? RepoTools.ObjcLibrary }
.flatMap { $0.headers }
.flatMap { podGlob(pattern: $0) }
.forEach { shell.symLink(from: "\(pwd)/\($0)", to: publicHeaderdir) }
I like what you've done here! I was wondering how you handled the conditions for different OS' and how you put the files in the Public folder. I was wondering about the pch_with_name_hint
? Is that to simply generate the cocoapods pch attribute?
@lswith - pch_with_name_hint
is a way in our macro to suggest the prefix of the PCH file. It's far from perfect but it's worked for us so far.
We leverage select
statements to differentiate between OS types (tvos, osx, ios, watchos). Macros where you would normally insert a glob()
now will pass a select
with glob
values.
I was wondering what configuration option you would use to differentiate between OS types? The main reason I ask this is because it looks like bazel is moving towards doing complete cross compilation and specifying which type of OS is done with the rule itself not with bazel flags. Take a look at the new apple rules to see what I mean: https://github.com/bazelbuild/rules_apple
@lswith - We aren't on Bazel 0.5 yet so we haven't been able to adopt the new rules. We will likely have to tackle this soon though.
Sorry I was wrong anyways. It appears they will be using platforms based on this thread: https://github.com/bazelbuild/bazel/issues/350
Ping 🚀! Does anyone from the bazel team have a any suggestions on the original issue?
I'm not sure if this issue has been resolved, but given the age and lack of activity, I'm going to assume it's no longer relevant. Please let me know otherwise and I'll reopen and retriage.
Most helpful comment
@lswith we are also doing this at Pinterest literally right now (porting our 40ish cocopods over). We ended up making a workspace rule called
new_pod_repository
( https://bazel.build/versions/master/docs/be/workspace.html ). Example:During workspace loading we pull down the repo and then automatically convert the Podspec into a BUILD file using a Swift program. Then we can just refer to these as a dep like
@PINOperation//:PINOperation
By making each cocoapod a separate workspace rule you get
<>
imports that work in the same way (assuming you move the headers around in the same way that cocoapods does) + it also semantically to be a workspace makes sense as a workspace rule since we're getting something from a third-party.The goal is to push as much as we can to our automated Podspec -> BUILD tool so it's easy to add/upgrade/remove pods