No More than a C build system for clang, gcc and msvc.
Let’s start …
# run bootstrap from github, it will generate a configure file in current directory
$ curl https://raw.githubusercontent.com/junjiemars/nore/master/bootstrap.sh -sSfL | sh
# generate a C application skeleton
$ ./configure --new
# build and test
$ make test
done.
Why we need another C build system?
Frequently, I want to know how things works in machine level, so I need to try something in C on popular platforms, but sadly, there are no handy weapons to do that.
I known there are already aswsome tools exists, but the key question is how to easy build C code in varied OS by varied Compilers, among those things I just pick the most critical ones: Make and Shell.
So the story begins …
- Keep things simple: classic workflow (configure, make and make install).
- Write, Build, Test and Run on anywhere: Linux, Darwin, Windows.
- Easy to try some new ideas but have no more unnecessaries.
This section describes how to use Nore in details.
There are no installation process just configure sh and make environment.
The most simplest way to configure is go into your C application directory and run:
$ curl https://raw.githubusercontent.com/junjiemars/nore/master/bootstrap.sh -sSfL | sh
configure Nore on Linux ...
+ checking make ... yes
+ checking nore ... yes
+ generating configure ... ok
+ generating ~/.nore/cc-env.sh ... ok
... elpased 0 seconds.
Requirements on Windows:
- Shell, because there are no sh by default, so we need to install
one, Git Bash easy to install and use. When installating Git Bash,
select
unix compatible tools
option box. - MSVC environment, C/C++ Build Tools installer is enough, and select Windows SDK.
In any CMD
or Git Bash
, run:
$ curl https://raw.githubusercontent.com/junjiemars/nore/master/bootstrap.sh -sSfL | sh
configure Nore on MINGW64_NT-10.0 ...
+ checking make ... no
+ downloading make ... yes
+ checking nore ... yes
+ generating configure ... yes
+ generating ~/.nore/cc-env.sh ... yes
... elpased 9 seconds.
# generate ~/.cc-env.bat for MSVC environment
$ ~/.nore/cc-env.sh
Put %USERPROFILE%\.nore
into your Windows’ %PATH%
let life more
easier.
screenshots:
If you want to try new features of Nore, try the edge
branch.
$ curl https://raw.githubusercontent.com/junjiemars/nore/edge/bootstrap.sh -sSfL | sh -s -- --branch=edge
$ ./configure --help
All Nore’s options are orthographic.
On Unix-like operating systems, there are no more things need to do. But on Windows, if using MSVC environment, we need host MSVC environment first.
In sh:
# switch to cmd
$ cmd
REM host msvc environment
> %userprofile%/.nore/cc-env.bat
REM switch to sh
> sh -i
Or in cmd:
REM host msvc environment
> %userprofile%/.nore/cc-env.bat
REM switch to sh
> sh -i
screenshots:
Using –new option to make a testable skeleton, you can easy to try some new idea from scratch. Don’t warry, it is the same processing on Windows, Darwin and Linux.
# generate a new project's skeleton
$ ./configure --new
checking for OS
+ MSYS_NT-10.0 2.10.0(0.325/5/3) x86_64
checking for C compiler ... yes
+ using Microsoft C/C++ compiler
+ msvc version: 19.16.27025.1 for x64
checking for WinNT-10.0-x86_64 specific features
creating out/Makefile
+ generating c.c file ... yes
+ generating version file ... yes
+ generating auto file ... yes
+ generating Makefile file ... yes
Configuration summary
platform: WinNT-10.0-x86_64
compiler: msvc 19.16.27025.1 for x64
symbol-table=
prefix= dist
out= out
src= .
has= .
new= YES
error= YES: -WX
warn= YES: -W4
verbose= NO
debug= YES
symbol= YES: -Z7
arch= NO
std= YES
optimize= NO: -Od
# after --new a skeleton, configure skeleton and make
$ ./configure
$ make clean test
screenshots:
For existing C project
$ cd <existing-c-project-root>
$ ./configure --src-dir=<source-directory>
$ ./configure
$ make
$ make test
Following the prompt of configure and make, change the options of configure or modify src/Makefile.
Suppose project P has A, B and C three individual subprojects. And A, B and C has individual Makefile. The directory layout looks like:
P ├── src │ ├── A │ │ ├── Makefile │ │ └── ... │ ├── B │ │ ├── Makefile │ │ └── ... │ └── C │ ├── Makefile │ └── ... └── ...
You can make them all at once:
$ ./configure --has-A --has-B --has-C
All projects can share only one Nore clone.
Suppose there are A, B and C projects, those projects sharing only one Nore clone.
# clone Nore in a directory, and annoted it as <Nore>
# in A project directory:
$ cd <A>
$ <Nore>/bootstrap.sh
# in B project directory:
$ cd <B>
$ <Nore>/bootstrap.sh
# in C project directory:
$ cd <C>
$ <Nore>/bootstrap.sh
Nore’s builtin exportable symbols can be replaced via –symbol-table option, which let Nore easy port to existing C projects.
For example: some tools annote DARWIN symbol in C source code or
make file as __DARWIN__
, but the default in Nore is DARWIN
, you
can change that to __DARWIN__
.
$ ./configure --symbol-table=<favored-symbols>
# if <favored-symbols> does not existing, Nore will dump the symbol
# table into it. Otherwise, Nore will import <favored-symbols>
# change the <favored-symbols> then
$ ./configure --symbol-table=<favored-symbols> --has-<A>
$ make clean test
Write a sh script named auto and put it into --src-dir
directory. The errors of auto will be recorded into the auto.err
file in your --out-dir
directory.
# check header file exiting
#----------------------------------------
echo " + checking C99 header files ..."
include="complex.h" . ${NORE_ROOT}/auto/include
include="fenv.h" . ${NORE_ROOT}/auto/include
include="inttypes.h" . ${NORE_ROOT}/auto/include
include="stdint.h" . ${NORE_ROOT}/auto/include
include="tgmath.h" . ${NORE_ROOT}/auto/include
# check machine features
#----------------------------------------
nm_feature="endian"
nm_feature_name="nm_have_little_endian"
nm_feature_run=value
nm_feature_h="#include <stdio.h>"
nm_feature_flags=
nm_feature_test='int i=0x11223344;
char *p = (char *)&i;
int le = (0x44 == *p);
printf("%i", le);'
. ${NORE_ROOT}/auto/feature
nm_feature_run
should be no
, yes
, value
and dumb
.
no
is the default.yes
will run thenm_feature_test
.value
will runnm_feature_test
and returnnm_feature_value
.dumb
will runnm_feature_test
except output to screen.
# check compiler features
#----------------------------------------
case "$CC_NAME" in
clang)
;;
gcc)
nm_feature="$CC_NAME -Wl,-E|--export-dynamic"
nm_feature_name=
nm_feature_run=no
nm_feature_h=
nm_feature_flags='-Wl,-E'
nm_feature_test=
. ${NORE_ROOT}/auto/feature
if [ yes = $nm_found ]; then
flag=LDFLAGS op="+=" value=$nm_feature_flags \
. ${NORE_ROOT}/auto/make_define
fi
;;
msvc)
;;
esac
# check OS features
# ----------------------------------------
case $NM_SYSTEM in
Darwin|Linux)
nm_feature="mmap fn"
nm_feature_name="nm_have_mmap_fn"
nm_feature_run=no
nm_feature_h='#include <sys/mman.h>'
nm_feature_flags=
nm_feature_test='mmap(0, 16, 1, 0, 3, 0);'
. ${NORE_ROOT}/auto/feature
;;
WinNT)
;;
*)
;;
esac
# check ENV features
# ----------------------------------------
case "$NM_SYSTEM" in
Darwin)
nm_feature="libuv"
nm_feature_name="nm_have_libuv"
nm_feature_indent=yes
nm_feature_run=no
nm_feature_h="#include <uv.h>"
nm_feature_flags="`pkg-config --cflags --libs libuv`"
nm_feature_test=
. ${NORE_ROOT}/auto/feature
;;
Linux)
;;
WinNT)
;;
*)
;;
esac
The where command used to review your current Nore’s environment.
After configuration, Nore should generate the cc-env.sh
shell script
file at your $HOME/.nore
or %UERPROFILE%/.nore
directory. Run
cc-env.sh
will generate some auxiliary files to help you setup your
C programming environment.
The cc-env.sh
will generates the following files:
cc-env.bat
file: only for msvc on Windowscc-inc.lst
file: a list of C include pathcc-inc.vimrc
file:vimrc
file ifvim
already been instaslled
On Unix-like platform, the output of where command looks like:
$ ~/.nore/cc-env.sh
$ ./configure where
NORE_ROOT=/opt/apps/c/.nore
NORE_BRANCH=master
configure=@./configure
make=@/usr/bin/make
shell=@/bin/sh
cc-env.sh=@/home/ubuntu/cc-env.sh
cc-inc.lst=@/home/ubuntu/cc-inc.lst
cc-inc.vimrc=@/home/ubuntu/cc-inc.vimrc
On Windows platform, the output of where command looks like:
$ ~/.nore/cc-env.sh
$ ./configure where
NORE_ROOT=/c/opt/apps/nore
NORE_BRANCH=edge
configure=@./configure
make=@/c/opt/open/gmake/4.2.90/make
shell=@/usr/bin/sh
cc-env.sh=@/c/Users/junjie/cc-env.sh
cc-env.bat=@/c/Users/junjie/cc-env.bat
cc-inc.lst=@/c/Users/junjie/cc-inc.lst
cc-inc.vimrc=@/c/Users/junjie/cc-inc.vimrc
Upgrade current Nore via upgrade command.
$ ./configure upgrade
configure Nore on MSYS_NT-10.0 ...
+ checking make ... yes
+ checking nore ... yes
+ upgrading nore ... yes
+ generating configure ... yes
+ generating ~/.nore/cc-env.sh ... yes
... elpased 13 seconds.
Clone the existing Nore into current directory.
Trace Nore processing.
This section introduces how Nore interactive with your favored Editors.
On any platform, don’t warry about C include path, Nore should
generate a shell script named ~/.nore/cc-env.sh
for you (for
details see where command).
On any Unix-like platform:
- M-x shell-command <your-c-app-dir>/configure --has-x
- M-x compile make -C <your-c-app-dir> clean test
On Window:
- M-x shell-command cc-env.bat && sh <your-c-app-dir>/configure --has-x or M-x compile cc-env.bat && sh <your-c-app-dir>/configure --has-x
- M-x compile cc-env.bat && make -C <your-c-app-dir> clean test
Nore Emacs has awsome C programming experience, including C source code and makefile editing, syntax highlight, auto completion, interactive debugger(gdb, lldb, cdb), interactive shell, all those excellently smooth.
Troubleshotting is more easier than other ones, because merely Makefile and shell script. And Nore provides a command for debugging purpose.
# review out/auto.err
$ less out/auto.err
# review out/Makefile
$ less out/Makefile
# trace Nore processing
$ ./configure trace
$ ./configure trace --without-error
# make debugging options: --just-print --print-data-base --warn-undefined-variables --debug=b
$ make --just-print