When you build a Bazel project, your WORKSPACE project root directory is populated by a bunch of convenience symlinks:
<workspace-name>/ <== The workspace directory
bazel-my-project => <...my-project> <== Symlink to execRoot
bazel-out => <...bin> <== Convenience symlink to outputPath
bazel-bin => <...bin> <== Convenience symlink to ...
bazel-genfiles => <...genfiles> <== Convenience symlink to ...
See the official doc, Bazel internals: Directory layout, for details.
My question: is there a Bazel option to avoid all these links to be generated or at least an option to tell Bazel to put all these links in another place (in /tmp/my-project for instance)?
(My motivation is that I also use other tools that scan *.hpp and *.cpp files in my project directory, unfortunatly all the symlinks generated by Bazel are messing up the result...).
Quoting the documentation of --symlink_prefix:
Warning: the special functionality for / will be deprecated soon;
use --experimental_convenience_symlinks=ignore instead.
--symlink_prefix=/ will stop these symlinks from being created.
https://docs.bazel.build/versions/master/command-line-reference.html
Related
I cannot make local include paths work in the Meson build system.
This C++ inclusion works correctly:
#include </cygdrive/c/Users/user/project/Third-Party/eigen/Eigen/Dense>
This one does not:
#include "Third-Party/eigen/Eigen/Dense"
fatal error: Eigen/Dense: No such file or directory
In the Meson build file, I tried to add Eigen's path, without success:
# '.' will refer to current build directory
include_dirs = include_directories('include', '.', '../project/Third-Party/eigen')
This is the project tree structure:
project
meson.build
src
meson.build
example.h
example.cpp
Third-Party
eigen (headers only lib)
Eigen
Note: with CMake I do not have this issue.
For dependency management, meson allows you to manually declare include_directories() in your build files. However, there is another way do handle dependencies: using dependency() command.
dependency() is a much better way to handle dependencies, because meson will build it if necessary (if dependency is a shared or a static library) and safely allows you to use includes. That means that you don't have to know where includes for dependency are located physically or care about their paths ever after. The only downside is that this kind of dependency needs it's own meson.build file.
Using dependency() command:
To actually use it, you have to write a wrap file for dependency. Or, if you are lucky enough, there is already a wrap file for you in the Wrap DB -- a community-driven database for meson wrap files. Wrap file is a config of some kind that declare where you can get a dependency and in what form. Wrap file can wrap around zip archives and git repositories.
For your given dependency, there is wrap file in Wrap DB: eigen. All you have to do is download it and place it in the subprojects directory near your meson.build. For example:
$ cd project
$ mkdir subprojects
$ wget "https://wrapdb.mesonbuild.com/v1/projects/eigen/3.3.4/1/get_wrap" \
-O subprojects/eigen.wrap
Now, not every project builds with meson. For the ones that don't, wrap file also specify a patch. Patch is used to just copy appropriate meson.build file into dependency directory (as well as any other files that would be needed for building that particular dependency with meson). Eigen wrap file contains a patch.
To find out how any particular dependency declare itself as a dependency (using declare_dependency() command), you need to investigate meson.build file in dependency source directory (although it's often just name of the dependency plus _dep, e.g. "eigen_dep"). For me, eigen directory was subprojects/eigen-eigen-5a0156e40feb. So, you search for the declare_dependency() command:
$ grep declare_dependency subprojects/eigen-eigen-5a0156e40feb/meson.build
eigen_dep = declare_dependency(
As you can see, eigen declare dependency as eigen_dep. If you want to know what exactly is declared, just scroll down the dependency meson.build file.
Now, to use that eigen_dep in your project, create a dependency object with a dependency() command. Here is a sample project that I used to compile "A simple first program" from Eigen: Getting Started:
project('example', 'cpp')
eigen_dependency = dependency('eigen', fallback: ['eigen', 'eigen_dep'])
executable('example', 'example.cpp', dependencies: eigen_dependency)
Notice arguments for the dependency() command. The first one is system-wide dependency that meson is searching for. If there is no eigen for development installed in your system, then meson uses fallback: first item in fallback is basename of the wrap file, second item is a name of declared dependency.
Then use eigen_dependency variable in whatever you build, passing it to the dependencies argument.
Using include_directories() command:
If you want to just include some files from external directory (such as your "Third-Party" directory) using include_directories() command, that directory has to be relative to the meson.build file where you use it.
To use manually declared includes, you need to call include_directories() command to get the include_directories object. Pass that object to include_directories argument in whatever you build.
Given your example, I assume that root meson.build file is a project build file. Then in that root meson.build, for example, you can write:
# File: project/meson.build
project('example', 'cpp')
eigen_includes = include_directories('Third-Parties/eigen')
executable('example', 'example.cpp', include_directories: eigen_includes)
But if you want to get eigen includes from src/meson.build, then you need to change include_directories to:
# File: project/src/meson.build
eigen_includes = include_directories('../Third-Parties/eigen')
...
How do I specify a custom directory layout for an sbt-based project? I've been looking at the online sbt material, but I'm struggling to find this information...
What I did find in the documentation were the default locations:
Sources in the base directory
Sources in src/main/scala and src/main/java
Tests in src/test/scala and src/test/java
Data files in src/main/resources and src/test/resources
Unmanaged jar-files in lib/
How do I override these in the build.sbt file?
My project structure is currently as follows:
Source in: [workspace]/sandbox-scala/src/sbt/myFirst/
Libraries in: [workspace]/java-lib/common/lib/
Any help appreciated.
One can override a number of sbt's default directory locations. Here's an example that overrides the directory where sbt expects to find "unmanaged" dependencies/jar files:
unmanagedBase := baseDirectory.value / "custom-jars-directory"
(More examples related to depndencies in the sbt documentation.)
You can also configure the directories as specific to a particular "task"... E.g., to set the directory where test-case source code is, try:
scalaSource in Test := { (baseDirectory in Test)(_ / "test") }.value
And then your core application source code could be somewhere else, say under src/:
scalaSource in Compile := { (baseDirectory in Compile)(_ / "src") }.value
NOTE: For older versions of sbt you may need the following (now-deprecated) syntax:
unmanagedBase <<= baseDirectory { base => base / "custom-jars-directory" }
scalaSource in Compile <<= (baseDirectory in Compile)(_ / "src")
This syntax will not work in newer versions of sbt (since 0.13.13, I believe).
I'm currently working to upgrade a set of c++ binaries that each use their own set of Makefiles to something more modern based off of Autotools. However I can't figure out how to include a third party library (eg. the Oracle Instant Client) into the build/packaging process.
Is this something really simple that I've missed?
Edit to add more detail
My current build environment looks like the following:
/src
/lib
/libfoo
... source and header files
Makefile
/oci #Oracle Instant Client
... header and shared libraries
Makefile
/bin
/bar
... source and header files
Makefile
Makefile
/build
/bin
/lib
build.sh
Today the top level build.sh does the following steps:
Runs each lib's Makefile and copies the output to /build/lib
Runs each binary's Makefile and copied the output to /build/bin
Each Makefile has a set of hardcoded paths to the various sibling directories. Needless to say this has become a nightmare to maintain. I have started testing out autotools but where I am stuck is figuring out the equivalent to copying /src/lib/oci/*.so to /build/lib for compile time linking and bundling into a distribution.
I figured out how to make this happen.
First I switched to a non recursive make.
Next I made the following changes to configure.am as per this page http://www.openismus.com/documents/linux/using_libraries/using_libraries
AC_ARG_WITH([oci-include-path],
[AS_HELP_STRING([--with-oci-include-path],
[location of the oci headers, defaults to lib/oci])],
[OCI_CFLAGS="-$withval"],
[OCI_CFLAGS="-Ilib/oci"])
AC_SUBST([OCI_CFLAGS])
AC_ARG_WITH([oci-lib-path],
[AS_HELP_STRING([--with-oci-lib-path],
[location of the oci libraries, defaults to lib/oci])],
[OCI_LIBS="-L$withval -lclntsh -lnnz11"],
[OCI_LIBS='-L./lib/oci -lclntsh -lnnz11'])
AC_SUBST([OCI_LIBS])
In the Makefile.am you then use the following lines (assuming a binary named foo)
foo_CPPFLAGS = $(OCI_CFLAGS)
foo_LDADD = libnavycommon.la $(OCI_LIBS)
ocidir = $(libdir)
oci_DATA = lib/oci/libclntsh.so.11.1 \
lib/oci/libnnz11.so \
lib/oci/libocci.so.11.1 \
lib/oci/libociicus.so \
lib/oci/libocijdbc11.so
The autotools are not a package management system, and attempting to put that type of functionality in is a bad idea. Rather than incorporating the third party library into your distribution, you should simply have the configure script check for its existence and abort if the required library is not available. The onus is on the user to satisfy the dependency. You can then release a binary package that will allow the user to use the package management system to simplify dependency resolution.
As a follow up to another question I recently asked, I realize my issue is that I don't know how to include Apple 'frameworks' in the Eclipse CDT project properties so that they're picked up and linked at compile time.
This results in includes in this form not to be resolved:
#include <OpenCL/cl.h>
Where the actual path would be something like:
/System/Library/Frameworks/OpenCL.framework/Versions/A/Headers
And the cmd line option would be (if I was manually compiling):
-framework OpenCL
In summary: How can I get Eclipse to see the framework(s) I want fromt he project properties?
Any help highly appreciated!
An alternative answer to JohnIdol's answer. In particular, an approach that can work in the case that you don't want to change the <OpenCL/cl.h> reference to <cl.h>
First, I came to the site with exactly this question in mind (how to include Apple 'frameworks' in Eclipse CDT (C/C++) projects) and I really appreciate the discussion - it gave me a starting point.
John's answer is cool but it does involve changing how the include file is called (e.g., <OpenCL/cl.h> becomes <cl.h> in the code). Then he does a direct include-path reference in the eclipse properties for each Header directory he needs.
In my case, I had checked-out GNU Backgammon to play around with the source code. This code compiles (with some mods to LDFLAGS and CPPFLAGS before doing the autogen.sh) on the OS X CLI environment using the I-guess-standard apple approach of the -framework option and with include files references like
#include <CoreAudio/CoreAudioTypes.h>
I may never actually commit anything but I didn't want to start hacking the #includes in code that is already compiling just fine using the standard approach. So I did the following:
Made a new directory in my workspace gnubg called "Frameworks".
Inside that directory, make soft-links to the header directories.
ln -s /System/Library/Frameworks/CoreAudio.framework/Headers CoreAudio
In the gnubg project properties > C/C++ General> Paths and Symbols, added /gnubg/Frameworks to the Include directories (as a workspace path). I only had to do this once, regardless of the number of soft links I made.
This way I did not have to change the code at all, Eclipse was happy, CLI compilation was happy as well.
I note that there is a slight wrinkle if using some directories in Frameworks such as the CoreServices.framework. In those cases there is a Frameworks subdirectory and relative path references in some of the include files (e.g., ..) to other include files. So in this case I had to modify the procedure a bit. Basically, I had to add an additional sub-directory in Frameworks for CoreServices.framework and then in that directory I had to add two soft links. One for the CoreServices (for the Headers) and one for Framework subdirectory.
lrwxr-xr-x 1 dhansen staff 57B Jul 27 02:06 CoreServices -> /System/Library/Frameworks/CoreServices.framework/Headers
lrwxr-xr-x 1 dhansen staff 60B Jul 27 02:05 Frameworks -> /System/Library/Frameworks/CoreServices.framework/Frameworks
Then I had to add /gnubg/Frameworks/CoreServices.framework to the include path (step 3 above).
And that's it. No more include file problems.
Since current Eclipse CDT releases don't perform sub-framework header inclusion correctly, you can avoid sub-framework problems (like those generated by the CoreServices header files) by creating symbolic links to the include directories of each sub-framework. I elaborated on this subject, which stems from danhan answer, in the following post:
http://thegreyblog.blogspot.com/2014/02/how-to-include-apple-frameworks-headers.html
In order to automate this process, I've created a Z shell script which automates this process and creates the symlink to the specified frameworks' header directory, together with the links to the include directory of each one of their sub-frameworks. The script can be found here: https://github.com/emcrisostomo/link-osx-framework-headers
Hope this helps.
OK so I had to include like this:
#include <cl.h>
Then add an include to the folder with the header file in Properties > C/C++ General > Paths and Symbols resulting in the following option for the compiler:
-I/System/Library/Frameworks/OpenCL.framework/Versions/A/Headers
And, most notably, had to add the following options for libraries path and framework inclusion under Properties > C/C++ Build > Settings:
-L/System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries -framework OpenCL
The above did the trick.
goto Your Project>Properties>MacOS X C++ Linker>Command
Where "g++" add " -framework OpenCL"
I want to integrate a header-only C++ library in my Autotools project. Since the library uses Autoconf and Automake, I use AC_CONFIG_SUBDIRS in configure.ac and added the library dir to the SUBDIRS = line in Makefile.am.
My question is: how do I prevent the header library from being installed by make install? I'm building a single binary, so my users don't need these headers.
I'd prefer not to tamper with the library, so I can fetch upgrade by just untarring the new version.
Here is an idea.
Move all the third-party libraries you do not want to see installed into a subdirectory called noinst/. So for instance if you want to ship your project with something like Boost, unpack it into the directory noinst/boost/. Use AC_CONFIG_SUBDIRS([noinst/boost]). Inside noinst/Makefile.am, do something like this:
SUBDIRS = boost
# Override Automake's installation targets with the command ":" that does nothing.
install:; #:
install-exec:; #:
install-data:; #:
uninstall:; #:
The effect is that whenever some of the recursive "make install*" or "make uninstall" commands are run from the top-level directory, the recursion will stop in noinst/ and not visit its subdirectories. Other recursive commands (like "make", "make clean" or "make dist") will still recurse into the subdirectories.
You could of course override install: and friends directly into the third-party package, and avoid the extra noinst/ directory. But if you are like me, you don't want to tamper with third-party packages to ease their update.
Also a nice property of the above setup is that if someone goes into noinst/boost/ and decide to run make install, it will work. It just does not occur by default when they install your package.
just came across a similar problem and found the solution in the automake manual:
noinst_HEADERS would be the right variable to use in a directory containing only headers and no associated library or program
Andreas
Don't use SUBDIRS then. The following hack may work:
all-local:
${MAKE} -C thatlib all
Of course it would be best if the library remained in its own directory outside of your project, and you just point to it via CFLAGS/LIBS flags.