Skip to content

junjiemars/nore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nore

No More than a C build system for clang, gcc and msvc.

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.

Story

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.

Recipe

This section describes how to use Nore in details.

Configuration

On Unix-like Platform

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.

On Windows Platform

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:

From Edge Branch

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

Getting Started

$ ./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:

New a Skeleton

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:

Configure existing one

For existing C project

$ cd <existing-c-project-root>

$ ./configure --src-dir=<source-directory>

Build and Test

$ ./configure

$ make

$ make test

Following the prompt of configure and make, change the options of configure or modify src/Makefile.

Multiple Targets

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

Multiple Projects

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

Symbol Table

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

Feature Testing

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.

Header File Exists Testing

# 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

Machine Feature Testing

# 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 the nm_feature_test.
  • value will run nm_feature_test and return nm_feature_value.
  • dumb will run nm_feature_test except output to screen.

Compiler Switch Testing

# 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

OS Feature Testing

# 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

ENV Feature Testing

# 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

Commands

where

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 Windows
  • cc-inc.lst file: a list of C include path
  • cc-inc.vimrc file: vimrc file if vim 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

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

Clone the existing Nore into current directory.

trace

Trace Nore processing.

Examples

Make an executable

Make a library

All stages of compiling

Editor

This section introduces how Nore interactive with your favored Editors.

Vim

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).

Emacs

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.

Visual Stduio Code

Troubleshoting

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