Cube
is a C project with a project structure (Cube
project structure) aim to be modular,
in which Cube
project could easily embedded into other Cube
projects with 0 configuration.
What it is:
- Building desktop application and static library on a unix-like environment.
- Targeting Windows, Linux and Mac OS.
- Include other
Cube
projects as thirdparties with 0 configuration. - Focus on modularity.
Basic Unix-like environment with basic C tools installed. These are the application required:
ar
clang
mkdir
cp
echo
make
cat
rm
git
cd
Cube
projects must be a git
repository.
Note
Though Windows is not a Unix-like, there are tools like Cygwin that
set up a Unix-like environment.
You could also give an equivalent application to be use as the tools on specific platform by
overriding Makefile variables in platform/toolchain
, it is useful in cross-compiling.
Directory | Description |
---|---|
build |
Store distributable files of the project and its thirdparty Cube projects. |
build/bin |
Stores built binary of the project and its thirdparty Cube projects. (<BIN_NAME> ). |
build/include |
Stores header files of the project and its thirdparty Cube projects. The header files is stored in their own directory with its project's name (build/include/<PROJECT_NAME>/ ). |
build/lib |
Stores built binary with the file with the naming format as lib<PROJECT_NAME>.a . |
cube |
Stores all the thirdparty Cube projects. It is handled by the Cube Makefile. |
gen |
Stores the generated object files of the project. |
include |
Stores the header files to be distributed, it will be copied to the build/include directory. |
platform |
Stores platform specific configuration. |
platform/flag |
Stores .flag text files record compiler flags required for building binary that depends on the current Cube projects (e.g. system library to be linked to for each platform). |
platform/toolchain |
Stores configuration Makefiles for overriding build tools for specific platform, useful for cross-compiling. |
source |
Stores all the .c source files. |
source/bin |
Stores source files that will be build into executables. Each source file compiles to an executable with the same name and output to build/bin . The executable is linked to library in build/lib . |
source/lib |
Stores source files that will be build into a static library, output to build/lib . |
Note
Project name (<PROJECT_NAME>
) is the name of the directory your project resided.
The Cube
Makefile resides at the root of the project.
It should:
- Build in
release
ordebug
mode, - Output the distributed files to the root
build
directory (more onCube
project structure), - Clean the build,
- Signal the thirdparty
Cube
projects.
The Cube
Makefile should have these phony targets:
release
- build in release mode.DEBUG
macro is defined.debug
- build in debug mode.RELEASE
macro is defined.
The Cube
Makefile should build the thirdparty Cube
projects before building itself.
All the distributed files are stored in the root build
directory as stated in the Cube
project structure.
The Cube
Makefile should have a clean
phony target that delete the files in its own gen
directory.
The root Cube
project should be the one to clean up the root build
directory.
The Cube
Makefile should clean the thirdparty Cube
projects before cleaning itself.
The Cube
Makefile should have these phony targets:
build-cube-release
- signaling to build all the thirdpartyCube
projects in release mode (calling therelease
phony target).build-cube-debug
- signaling to build all the thirdpartyCube
projects in release debug (calling thedebug
phony target).clean-cube
- signaling to clean all the thirdpartyCube
projects (calling theclean
phony target).
The root Cube
project pass these Makefile variables to the thirdparty Cube
projects:
ROOT_DIR
- Path of the rootCube
project.ROOT_BUILD_DIR
- Path of the rootbuild
directory.ROOT_BUILD_BIN_DIR
- Path of the rootbuild/bin
directory.ROOT_BUILD_INCLUDE_DIR
- Path of the rootbuild/include
directory.ROOT_BUILD_LIB_DIR
- Path of the rootbuild/lib
directory.ROOT_DEPENDENCIES_FILE
- Path of a text file records dependencies and its sequence.ROOT_FLAG_FILE
- Path of a text file records compiler flags when compiling binary (e.g. shared library to be linked to).
the thirdparty Cube
projects output to the root build
directory using the given variables.
The Cube
Makefile should record the library's output path to ROOT_DEPENDENCIES_FILE
once it is compiled in order to record the sequence of the dependencies.
Duplicates in ROOT_DEPENDENCIES_FILE
is prohibited.
The ROOT_DEPENDENCIES_FILE
is named <PROJECT_NAME>.DEPENDENCIES
and reside in ROOT_BUILD_LIB_DIR
.
In the ROOT_DEPENDENCIES_FILE
, The libraries depends on the libraries before itself.
The ROOT_FLAG_FILE
is named <PROJECT_NAME>.FLAG
and reside in ROOT_BUILD_LIB_DIR
.
In the ROOT_FLAG_FILE
, it stores the list of compiler flags.
Copy the Cube
project to cube
folder. Clean the project after adding, removing, modifying thirdparty libraries.
Add the flag links to the system library name into the .flag
text file under flag
directory according to the platform.
For an example, to link the pthread
and m
library for linux build, in flag/linux.flag
:
-lpthread
-lm
Clean the project after adding, removing, modifying the .flag
text files.
Cross-compiling can be achieve by providing the appropriate tools to the Makefile.
The programmer should install the appropriate tools and then provide it via the toolchain Makefiles in platform/toolchain
.
You could either:
- provide compilers native to each platforms and compile it on their own platform, or,
- provide a cross-compiler for all the toolchain Makefiles of other platforms and only compile from your native platform.
It is not advisible to use the second option as you could only compile from your native platform, which prevents other user from compiling on their own. It would only be useful when you are targeting a platform in which you cannot compile on it (e.g. mobile / embedded system), but it usually not the case as we are targeting desktops. Still, you are free to do whatever you want.
To use the toolchain Makefile of a specific platform with a specific arch. You can set PLATFORM
Makefile variable for the target platform and ARCH
Makefile variable for the target architecture. It will default to the host system if no value given.