SMake
is a simple tool that helps developers automatically generate Makefile
for C/C++ projects by only typing smake
in the project directory. See the file src/info.h
to check out what release version you have.
Use included scripts to build and clean the project.
git clone https://github.com/kala13x/smake.git --recursive
cd smake && ./build.sh --install --cleanup
To use the Makefile
generator you need to go into your project directory and type smake
, it will automatically try to scan the project and generate the Makefile
for you.
Here is a brief overview of all available command line arguments that smake
supports:
-f <'flags'>
- Specify compiler flags.-l <'libs'>
- Specify libraries to be linked with your program.-L <'libs'>
- Specify custom libraries (LD_LIBS).-c <path>
- Set the path to the config file.-b <path>
- Set the install destination for the binary.-i <path>
- Set the install destination for the includes.-e <path>
- Exclude specific files or directories.-o <path>
- Set the object output destination.-p <name>
- Set the program or library name.-s <path>
- Set the path to the source files.-V
- Print version and exit.-I
- Initialize a new project.-j
- Generate a config file.-d
- Enable the use of a virtual directory.-v
- Adjust the verbosity level of the output.-x
- Use the CPP compiler.-h
- Print version and usage information.
Each argument is optional and can be used in combination with others to suit your project's specific needs.
Please ensure you replace the placeholders (<'flags'>, , etc.) with actual values relevant to your project.
For example, if your project requires lrt
and lpthread
linking and you need to compile it with -Wall
flag, the command will be the following:
smake -f '-Wall' -l '-lrt -lpthread'
With option -p
, you can specify program name for your project, if you run smake
without this argument, smake will scan your files to search main
function and your program name will be that filename where main()
is located.
Also if you specify the program name with .a
or .so
extensions (smake -p example.so
), smake will generate Makefile
to compile your project as the static or shared library.
This is an example of generating Makefile
for a static library and specifying the install location for the library and headers:
smake -p mylib.a -l '-lpthread' -b /usr/lib -i /usr/include
The Makefile
of this project is generated with the command:
smake -jw \
-o ./obj \
-b /usr/bin \
-e './xutils' \
-l '-lpthread' \
-L './xutils/build/lib/libxutils.a' \
-f '-g -O2 -Wall -I./xutils/build/include' \
With argument -j
it also generates the json
config file, which can be used in the future to avoid using command line arguments every time.
The config file was generated and used by this project.
{
"build": {
"flags": "-g -O2 -Wall",
"libs": "-lpthread",
"ldLibs": "./xutils/build/lib/libxutils.a",
"outputDir": "./obj",
"overwrite": true,
"name": "smake",
"cxx": false,
"verbose": 0,
"includes": [
"./src",
"./xutils/build/include"
],
"excludes": [
"./xutils"
]
},
"install": {
"binaryDir": "/usr/bin"
}
}
Anything that can be passed as an argument can also be parsed from the config file. SMake
will search the config file at a current working directory with the name smake.json
or you can specify the path for the file with the argument -c
.
Example:
{
"build": {
"name": "myproj.a",
"outputDir": "./obj",
"flags": "-g -O2 -Wall",
"libs": "-lpthread",
"compiler": "gcc",
"overwrite": true,
"verbose": 2,
"cxx": false,
"excludes": [
"./examples"
"./cmake"
],
"find": {
"libssl.so:libcrypto.so": {
"found": {
"append" : {
"path": "/usr/local/ssl/lib:/usr/local/ssl/lib64",
"flags": "-D_PROJ_USE_SSL",
"libs": "-lssl -lcrypto"
}
}
},
"libz.so": {
"found": {
"append" : {
"flags": "-D_PROJ_USE_LIBZ",
"libs": "-lz"
}
}
},
"any_file.txt": {
"path": "/opt/examples/smake",
"thisPathOnly": true,
"insensitive": false,
"recursive": false,
"found": {
"append" : {
"flags": "-D_OPTIONAL_FLAGS",
"libs": "-loptional -lexample"
}
},
"notFound": {
"append": {
"flags": "-D_NO_OPTIONAL_FLAGS",
},
"set": {
"libs": "-lonlythis"
}
}
}
}
},
"install": {
"binaryDir": "/usr/lib",
"headerDir": "/usr/include/myproj"
}
}
As you can see in the example above, find
JSON object can be used to find files and libraries in the system. Each entry in the find section is a key-value pair where the key is the file (or a colon-separated list of files) you want to locate and the value is another object describing how to handle the dependency.
The keys in the nested objects describe how smake
should handle each dependency:
path
(optional): A colon-separated list of directories wheresmake
should look for the files. If a file is found in these directories, the corresponding flags and libs will be applied.thisPathOnly
(optional): If set to true, smake will only look for the file in the specified path and not in the default locations.insensitive
(optional): If set to true, the file search will be case-insensitive.recursive
(optional): If set to true, smake will search recursively in the directories specified by path.
In the example above, smake
will try to find libssl.so
and libcrypto.so
in either /usr/local/ssl/lib
or /usr/local/ssl/lib64
, if both of them are found, it will append -D_PROJ_USE_SSL
to the compiler flags and -lssl -lcrypto
to the linked libraries. The options for libz.so
and any_file.txt
are handled in a similar manner, with the additional thisPathOnly
, insensitive
, and recursive
options.
Without thisPathOnly
option, smake
will first look for files in the provided path
. If not found there, it will search in the following default locations:
/lib
/lib64
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib64
smake -I
When running the above command, smake
will generate a "Hello, World!" project in the current working directory. The name of the project will be the same as the name of the current working directory. If you wish to provide a custom name for the executable, you can do so by passing the name as an argument using -p
.
Any remaining arguments can also be used to initialize the project, for example:
smake -I -f '-Wall' -p test
The following command will create a compilable test.c
file in the current working directory with "Hello, World!" content inside and a Makefile
that compiles the project with -Wall
flag.
You can fork, modify and change the code under the MIT license. The project contains a LICENSE file to see the full license description.