CMake reads like a bash script, so try to understand how an existing library is built before attempting to convert it to a Bii compatible format.
Setting a variable in a subdirectory doesn't set it in parent scope. e.g. setting BII_path_to_main_SRC from a subdirectory will not set it in the parent scope. You need to explicitly tell it to.
Biicode needs the source files for its targets to be declared in the relevant BII_artifactname_SRC variables before the ADD_BIICODE_TARGETS() function is called. This means the path to generated files must be known before the target is added. If there is special processing required for a biicode target in a subdirectory, but that subdirectory is added before ADD_BIICODE_TARGETS() is called, you can't do it. Either:
- create a different static library target in the subdirectory, and link this to the biicode target instead, OR
- perform that special processing in the parent directory's CMake configuration after the biicode targets are added
Targets cannot be declared twice.
Biicode is clever enough to work out from #includes that a source file X depends on source file Y, given X has a #include "Y". However, if there is no explicit inclusion, but there is a dependency, you have to declare this in two places: biicode.conf, and the CMakeLists.txt.
The former is to tell Biicode, given a different block depends on source file X, also download source file Y. The latter defines the actual files on the build path.
Tip: Use bii deps or bii deps --details to find out which dependencies biicode has worked out. If there are any other undeclared dependencies, that's when you need to specify them.
Tip: Unresolved inclusions may show up as warnings. This is fine if you know that those inclusions are either not used (e.g. operating system specific inclusion), or it is a generated header inclusion that is not in the source tree.
Have a look at the variables in <project>/cmake/bii_user_block_vars.cmake for the variables you can use. Don't be too alarmed if an executable is given a lot of source files that have nothing to with it - you can override it with the actual required source files in your block's CMakeLists.txt.
Read Logs carefully, and understand them.
You are using layers of tools to build your code. Biicode, CMake, Make, and the compiler (and linker) (g++, clang, cl). When something fails, understand why it fails. It's not always the lowest layer's fault. Perhaps some CMake configuration wasn't written to tell ld that a particular library needs to be linked. Perhaps Biicode is being too loose with what should be included as source files for a particular executable, and you need to restrict what it is using.
There's different ways of doing this depending on which tool you are invoking, and whether you are invoking it from a higher level tool.
# from bii:
bii cpp:build -- --trace
# from cmake
cmake --trace
# from make
VERBOSE=1 make all
Apart from building the project independent of Biicode, you should build your block in the following manners:
- From the repository checkout (e.g. git clone)
- From bii open user/block
- From a block that depends on it
Before you build with biicode, make sure you clean out any output from a non-biicode build (e.g. CMakeCache.txt, generated files).
git clean -fd # warning: this removes all untracked files, so commit / stage them before running this command
Tip: you can use cmake -Bbuild -H. to have an "out of source" build. After, run cd build && make all && cd .. to compile your code. Just delete the build directory to clean up your working directory.
If your block should support different operating systems, you should build it on each to ensure it works. This also lets you discover how the block must be built. For example, CMake may default to the MINGW compiler on Windows,but your block may only support the MSVC compiler. This means you need to add an argument to the build command, e.g. bii cpp:configure -G "Visual Studio 12 2013 Win64"".
Tip: CMake does not detect your MSVC compiler if "Express 2013 for Windows" is installed, but it does if "Express 2013 for Windows Desktop" is installed.
After publishing a block as stable, the next time you publish, your ancestor version for your block is bumped. Remember to commit this change shortly after.