I am trying to compile my application using CMake, and I need to compile Lua with it for various reasons. My current setup is as follows:
project/
CMakeLists.txt
...
libs/
CMakeLists.txt
...
lua/
CMakeLists.txt
...
I am using LuaDist as it already provides a CMake build system for lua. The problem comes when I try to include lua.h from my project, as it requires luaconfig.h which is generated by the Lua subproject and output to its binary directory, not source directory.
In my main project I do something like this:
include_directories(libs/lua/src/ etc...)
How can I also include generated files from subprojects in my main project?
If you're including lua directly via an add_subdirectory call, you can also use include_directories(${lua_BINARY_DIR}) (assuming there's a project(lua) command in lua's CMakeLists.txt file). The name of the variable may be something else if the project command is different, or you may need multiple additional include_directories, depending on where the header files you need are ... but this should get you started.
Related
Here's an easy version of the BUILD file:
cc_library(
name = "ab",
srcs = ['a.c', 'b.c', 'logger.h'],
)
logger.h contains the implementation of a logging function that uses the macro XOC_FILE_ID. XOC_FILE_ID has to contain the name of the source file.
Using __FILE__ instead would not help because __FILE__ expands to the string "logger.h" inside the file logger.h.
That's why I need to compile these files with different defines:
gcc -c [...] -DXOC_FILE_ID="a.c" a.c
gcc -c [...] -DXOC_FILE_ID="b.c" b.c
My failed approaches:
set the attribute local_defines using the value{source_file}: local_defines = ['XOC_FILE_ID="{source_file}"]: does not get replaced
set the attribute local_defines using the make variable $<: local_defines = ['XOC_FILE_ID="$<"]: Bazel aborts telling me that $(<) is not defined
same approach for attribute copts
Of course, I could try to make Bazel call a compiler wrapper script. However, this would mean that I have to explicitly set PATH to my wrapper script(s) before each call to Bazel. Isn't there a better solution?
You have access to {source_file} in a toolchain definition.
This means you have to write your own toolchain definition.
I tried two ways of writing a toolchain:
Use the Bazel tutorial on toolchains. Afterwards my build was broken: The default compile options of Bazel were missing. cc_library did not create shared libraries any more.
Use a hint pointing to a post in bazel-discuss and use the toolchain that Bazel itself creates using your environment. That's what I'm going to describe now (for Bazel 3.5.1)
If you want to use a compiler that is not in $PATH, do bazel clean and update $PATH to make compiler available. Bazel will pick it up.
create a toolchain directory (maybe my-toolchain/) in your workspace
bazel build #bazel_tools//tools/cpp:toolchain
copy BUILD, all *.bzl files, cc_wrapper.sh and builtin_include_directory_paths from $(bazel info output_base)/external/local_config_cc/ to your toolchain directory; copy the files the symbolic links are pointing to instead of copying the symbolic links
Adapt the BUILD file in my-toolchain/ to your needs—like adding '-DXOC_FILE_ID=\\"%{source_file}\\"' to compile_flags of cc_toolchain_config.
add these lines to your .bazelrc to make Bazel use your new toolchain by default:
build:my-toolchain --crosstool_top=//my-toolchain:toolchain
build --config=my-toolchain
In its C++ unit testing tutorial, Bazel suggests adding a root level gtest.BUILD file to the workspace root in order to properly integrate Google Test into the test project.
https://docs.bazel.build/versions/master/cpp-use-cases.html
Why would one create a new BUILD file and add gtest prefix to it rather than adding a new build rule to an existing BUILD file in the workspace? Is it just a minor style preference?
Because if you added a BUILD file somewhere in the workspace (e.g. under //third_party/gtest/BUILD) then that file would create a package there.
Then, if you had targets declared in that BUILD file, would their files exist under //third_party/gtest, or would they exist in the zip file that the http_archive downloads? If the former, then there's no need for a http_archive because the files are already in the source tree; if the latter, then the BUILD file references non-existent files in its own package. Both scenarios are flawed.
Better to call gtest's BUILD-file-to-be something that doesn't create a package, but that's descriptive of its purpose.
The build_file attribute of http_archive can reference any file, there's no requirement of the name. The name gtest.BUILD is mostly stylistic, yes, but it also avoids creating a package where it shouldn't. You could say it's an "inactive" BUILD file that will be "active" when Bazel downloads the http_archive, extracts it somewhere, and creates in that directory a symlink called BUILD which points to gtest.BUILD.
Another advantage of having such "inactive" BUILD files is that you can have multiple of them within one package, for multiple http_archives.
Does anyone know why Dart Editor won't allow me to edit files located inside the packages folder? I originally had my library class files outside of that folder, but I thought the right way to do it was to put my library under that folder, so I did it and now I can't modify the files.
Everything in packages/ is (usually) a symlink to a possibly shared copy of a package, so if you edited a file in packages/ you'd be editing it for all your projects, which might be very not what you want.
If you'd like to edit multiple packages together, the best way to do it is to specify a dependency override that uses a path source, like so:
name: my_package
dependency_overrides:
my_other_package:
path: /Users/me/dart/my_other_package
This way any other dependency on that package will also load it from the specified path and pub won't complain that you have different sources for the same package. Then you can open both projects separately in the editor and the my_package will see the changes in my_other_package as you edit.
When I create a sub folder in a Dart Project in Dart Editor, immediately a package subfolder is created inside this sub folder. I have not read anywhere that sub folders have a special meaning for the project structure, but it appears they do. Anybody knows more?
The package subfolder holds symlinks to your Pub packages. You can read more about Pub and Pub packages at http://pub.dartlang.org/doc/.
When you start a non-web project, the editor will automatically create package directories in your bin/ and test/ directories (but not in your lib/ directory). If you create a web project, a package directory is also created in the web/ folder.
If you add a Pub dependency in the pubspec.yaml file and run pub install, your will see that the package folders will contain symlinks to the Pub package you just installed. If you are using Dart Editor, pub install will automatically run once you modify your pubspec,yaml file.
If you create a subfolder inside any directory that contains one of these auto-generated package folders, the subfolder will get its own package directory. This way, you will have access to your Pub packages no matter how deeply you nest your code in a directory.
Shailen's answer is correct. I wanted to add a bit more, as the title of this question is "What relevance to folders have in a Dart project?"
Dart is designed to be very web friendly. Because there is no load path or classpath on the web, Dart apps must run without requiring an installation or pre-configuration of a local environment.
The only way you can link one file to another in Dart is via a URI. These URIs can be file URIs, and they can be relative. That means file A.dart can point to file B.dart via an absolute or relative path.
So, to answer you question, there is nothing special about a folder layout for Dart applications. The app will run as long as your Dart file can reference its dependencies via the same kind of linking rules that exist on the web (think <a href="" or <link src="").
However, pub (the Dart dependency manager) does make a few assumptions about package and application layout. If certain conventions are followed, pub can manage symlinks for you so that it's easier to reference 3rd party dependencies. Do you need to use pub? Nope, you can manually copy files around or manually manage symlinks. But pub certainly does make it easier to use packages, given the constraints of Dart's design (no load path, no classpath).
It seems to me that what I'm trying to achieve is incredibly simple, yet is becoming incredibly painful.
I have ProjectA which is a BlackBerry Application project. I have ProjectB which is a Java library project. I want to refer to ProjectB from ProjectA. I can add a reference but when I run ProjectA, it doesn't work. I have source code for both the projects and both are compiled using Java compiler 1.4
I have tried multiple things but everything fails for some reason:
1. pre-verify.exe on ProjectB
It fails with an error "JAR file creation failed with error -1" I can see that the cod and jar files have been created but when add the jar file to ProjectA and run it, it doesn't work. Not sure if I need to add the .cod file.
2. Create new BlackBerry Library Project and reference it in ProjectA
I create a new project ProjectC and then add the jar of ProjectB to it. Then I add a reference to ProjectC in ProjectA. But I cant import classes from ProjectB
Pls suggest a way out.
I'm using Eclipse Plug-in and relying on Eclipse's build capabilities
Figured out answer myself. Publishing here in case someone stumbles upon this. Here are the steps:
Create your library and export as JAR (or download the 3rd party JAR)
Run preverify.exe on the JAR
preverify.exe -verbose -classpath "C:/Program Files/Research In Motion/BlackBerry JDE 5.0.0/lib/net_rim_api.jar" jarname.jar
If you are lucky, you won't run into any issues and you will be done. But I wasn't lucky enough. I got the below error
Error: No such file or directory. JAR file creation failed with error -1
There are two possible causes of this:
jar.exe is not added to your PATH. If so, add it (found in your JAVA
installation directory) to PATH
cvfm or -cfm option on jar.exe fails to execute. I'm not aware of the reason but the way to fix this is to use -cf option, point to the .class files but don't use the manifest file. here is an
example:
"C:\Program Files\Java\jdk1.6.0_26\bin\jar.exe" -cf "output\json-1.0.jar" tmp12996/
tmp12996 contains the preverified .class files.
You may run into different issues other than the one I've listed above.
Once jar is created from above step, make sure that it's structure is as you anticipate. One way to check is to rename the .jar to .zip, unzip it and then check it. If it is not as you need, you can change the structure and then repack it (I wouldn't do any major changes though)
Then add this newly built jar to your BlackBerry application as a reference i.e. add to Java Build Path in your eclipse and Check it in Order and Export window.
That's it! You are good to go! Run you app!
You may face error indicating that the module contains verification errors when you try to run in the simulator. One possible cause of this issue is that your library (the original JAR) contains APIs that are not compatible with J2ME or BB JRE. You may not get a compiler error when you build your library independently as it is compiled against Java 1.4 (or whatever your version is). Best to figure the issue out is to move all your code into your BB App project and then build it. That will tell you all the issues upfront. You make the changes as required and then move the code back to the library. If you don't have source code for the library you are using (like a 3rd party library), you may be out of luck! Also remember that there could be other issues than what I've hit upon and solved.
I'm documenting this at length as it has taken an awful amount of time for me to figure all this out; and to say the least, was most frustrating!
I found another solution. If you get error -1 while preverifying your JAR file, just run your library application once. Because if you don't run the application, the deliverables folder will be empty. Make sure this folder is not empty.