Linux Make in C

modifedTime.h

#ifndef MODIFIEDTIME_H
#define MODIFIEDTIME_H
#include <sys/types.h>
#include <sys/stat.h>

time_t modifedTime(char *path);

#endif /* MODIFIEDTIME_H */

modifiedTime.c

modifiedTime以time_t返回文件最后一次修改的时间

#include "modifedTime.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>

time_t modifedTime(char *path)
{
  struct stat attr;
  if (stat(path, &attr) == 0)
  {
    return attr.st_mtime;
  }
  exit(1);
  return 0;
}

doCommand.c

doCommand执行Unix命令,无异常返回true,否则false。

#include <stdlib.h>

typedef enum { false, true } bool;

bool doCommand(char *line)
{
  if (system(line) == -1)
  {
    return false;
  }
  return true;
}

hasChanged.c

hasChanged 接受“预编译文件:依赖1 依赖2 依赖3 …” 如有任何一个依赖比预编译更新,则返回true,如果预编译/依赖不存在,也返回true。

#include "modifedTime.h"
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef enum { false, true } bool;

bool hasChanged(char *line)
{
  //Compare the modification time of each depends with this.
  //If any of it's modification time is later than this. regenerate this.
  time_t this_last_modifed, depends_last_modifed;
  int i = 0;
  char str[100];
  strcpy(str, line);
  char *pch;
  pch = strtok(str, ": ");
  long double start, end;
  FILE* fp;

  while (pch != NULL)
  {
    if (i == 0)
    {
      fp = fopen(pch, "r");
      //if .o doesn't exist
      if (fp == NULL)
        return true;
      else
      {
        fclose(fp);
        this_last_modifed = modifedTime(pch);
        i++;
      }
    }
    else
    {
      fp = fopen(pch, "r");
      if (fp == NULL)
        return true;
      fclose(fp);
      depends_last_modifed = modifedTime(pch);
      if (difftime(depends_last_modifed, this_last_modifed) > 0)
      {
        return true;
      }
    }
    pch = strtok(NULL, " \n");
  }
  return false;
}

spcMake.c

主程序接收一个-v用于显示执行的Unix命令

#include "modifedTime.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

typedef enum { false, true } bool;

main(int argC, char* argV[])
{
  FILE* fp;
  char buffer[511];
  const char colon[] = ":";
  bool verbose = false;
  bool execute = false;
  if (argC == 2)
  {
    if (strcmp(argV[1], "-v") == 0)
      verbose = true;
    else
    {
      printf("Option %s isn't supported", argV[1]);
      exit(1);
    }
  }
  else if (argC != 1)
  {
    printf("Error option");
    exit(1);
  }

  fp = fopen("makefile", "r");
  if (fp == NULL) {
    printf("Error: No makefile found. Exiting...\n");
    exit(1);
  }

  while (fgets(buffer, 511, fp))
  {
    if (buffer[0] == '\n')
    {
      execute = false;
    }
    if (execute)
    {
      if (verbose)
        printf("%s", buffer);
      if (!doCommand(buffer))
      {
        printf("Error Excuting %s", buffer);
        exit(1);
      }
    }
    if (strstr(buffer, colon) != NULL)
    {
      if (hasChanged(buffer))
      {
        execute = true;
      }
    }

  }
  fclose(fp);
  exit(0);
}

makefile

doCommand.o: doCommand.c
echo compiling doCommand
gcc -c -o doCommand.o doCommand.c

hasChanged.o: hasChanged.c
echo compiling hasChanged
gcc -c -o hasChanged.o hasChanged.c

modifedTime.o: modifedTime.h modifedTime.c
echo compiling modifedTime
gcc -c -o modifedTime.o modifedTime.c

spcMake: spcMake.c doCommand.c hasChanged.c modifiedTime.c modifiedTime.h spcMake.c
echo compiling/linking prog
gcc -o spcMake doCommand.c hasChanged.c modifedTime.c modifedTime.h spcMake.c

编译:

gcc -o spcMake doCommand.c hasChanged.c modifedTime.c modifedTime.h spcMake.c

Leave a Reply

Your email address will not be published. Required fields are marked *