1. 프로젝트 개요 및 팁
이번 프로젝트는 libc에 있는 일부 모듈을 직접 구현하여 정적 라이브러리로 만드는 것이다. 차후에 정적 라이브러리를 이용할 수 있도록 재사용 가능한 함수들은 최대한 이용하여 내부적으로 유지하는 static 함수를 최소화해보자. 정적 라이브러리라는 의미를 최대한 기억하여 구현하는 것을 목표로 한다.
1) 구현 순서 가이드
1.
memset → bzero → calloc
2.
strlcpy → substr → strjoin → split
3.
memcmp → strnstr
4.
strchr → strtrim
5.
lstnew → lstdelone → lstclear → lstlast → lstadd_back → lstmap
2) const char * vs char const * vs char * const
int main(void)
{
// s1, s2 equivalent -> cannot change value, afford to change address
// s3 -> afford to change value, cannot change address
const char *s1 = "123";
char const *s2 = "456";
char *const s3 = "789";
// upper one error
// *s1 = '0';
// ++s1;
// upper one error
// *s2 = '0';
// ++s2;
// lower one error
// *s3 = '0';
// ++s3;
return (0);
}
C
복사
2. libft.a
1) memset
#include <string.h>
void* memset(void* dest, int c, size_t n);
C
복사
dest 의 주소부터 size 바이트를 value 값으로 채운다. 이 때, value 는 unsigned char 로 형변환되고 바이트 단위로 값을 초기화 하게 된다. 따라서 memset의 char형 초기화는 문제가 없으나, int 값으로 초기화는 불가능하다. int 값 중에서도 memset으로 올바르게 형변환 되어 이용할 수 있는 수는 0과 -1이다.
0은 1 바이트 기준 2진수로 이고, 4 바이트로는 이다. 1 바이트 단위로 쓰여도 0으로 초기화 된다.
-1은 1 바이트 기준 2진수로 이고, 4 바이트로는 이다. 1 바이트 단위로 쓰여도 -1으로 초기화 된다.
int로 초기화 하는 것이 불가능하다는 것에 대해 이해해보자.
int main(void)
{
int memset_with_0[5];
int memset_with_1[5];
memset(memset_with_0, 0, sizeof(memset_with_0));
memset(memset_with_1, 1, sizeof(memset_with_1));
//memset_with_0 출력
printf("memset_with_0 : ");
for (int i = 0; i < 5; i++)
printf("%d ", *(memset_with_0 + i));
//memset_with_1 출력
printf("\nmemset_with_1 : ");
for (int i = 0; i < 5; i++)
printf("%d ", *(memset_with_1 + i));
return 0;
}
C
복사
위와 같이 두 배열을 0과 1로 초기화 한다면 아래와 같이 출력된다. memset 함수는 바이트 단위로 값을 초기화 하기 때문에 예상과는 다른 결과 값을 확인할 수 있다.
0 0 0 0 0
16843009 16843009 16843009 16843009 16843009
Plain Text
복사
memset은 1 바이트 단위로 초기화 시킨다. 따라서 4바이트 크기를 갖는 int 데이터에 각 바이트를 1로 초기화 하게 되면 0000001 00000001 00000001 00000001 과 같은 형태를 띄게 된다.
따라서 2진수로 표현된 값을 확인해보면 위처럼 의 값을 가진채로 int 배열이 초기화 된 것을 확인할 수 있다. memset은 1 바이트 단위의 초기화를 수행한다는 것을 염두에 둬야 하고, 1 바이트 단위의 초기화 때문에 char 형태의 배열에 적합하며 string.h에 들어있는 함수인 것도 이 때문임을 유추할 수 있다.
2) bzero
함수 원형
#include <string.h>
void bzero(void* dest, size_t size);
C
복사
함수 설명
memset과 비슷한 역할을 한다. C 언어 비표준이며 deprecated된 함수이므로 사용하지 않는 것이 좋다. bzero, ZeroMemory 대신에 C 언어 표준으로 이용되는 memset을 이용하는 것이 좋다. 함수 이름처럼 str 주소값부터 메모리 공간을 size 크기의 바이트만큼 0 으로 채운다.
deprecated 함수는 아래 링크를 통해 이해할 수 있다.
3) calloc
함수 원형
#include <stdlib.h>
void* calloc(size_t count, size_t size);
C
복사
함수 설명
Heap 공간으로부터 count * size만큼 메모리를 할당 후, 그 공간으 모두 0으로 초기화한다.
Return Value
할당된 메모리 주소를 가리키는 포인터를 반환
4) memcpy
함수 원형
#include <string.h>
void* memcpy(void* restrict dest, const void* restrict src, size_t size);
C
복사
함수 설명
src가 가리키는 곳 부터 size바이트만큼 dest에 복사한다.
Return Value
dest 를 반환
5) memccpy
함수 원형
#include <string.h>
void* memccpy(void* restrict dest, const void* restrict src, int ch, size_t size);
C
복사
함수 설명
src 가 가리키는 곳 부터 size 바이트만큼 dest에 복사한다. 만약 src에서 문자 ch를 만나면 ch까지만 복사를 진행하고 복제를 중단한다.
Return Value
•
복사된 dest변수에서 복사가 끝난 바로 다음 주소를 반환
•
문자 ch를 만나지 않았다면, size 바이트를 복사하고 NULL을 반환
6) memmove
함수 원형
#include <string.h>
void* memmove(void* dest, const void* src, size_t size);
C
복사
함수 설명
src 가 가리키는 곳 부터 size 바이트 만큼 dest 가 가리키는 곳으로 옮긴다. 버퍼를 이용하므로 dest 와 src 가 겹쳐도 문제 없다.
Return Value
dest를 반환
7) memchr
함수 원형
#include <string.h>
void* memchr(const void* dest, int ch, size_t size);
C
복사
함수 설명
dest 가 가리키는 곳 부터 size 바이트 까지 중 처음으로 ch 와 일치하는 값을 찾는다. ch는 unsigned char로 해석된다.
Return Value
•
문자 ch 를 만났다면 해당 주소를 반환
•
문자 ch를 만나지 않았다면 NULL을 반환
8) memcmp
함수 원형
#include <string.h>
int memcmp(const void* ptr1, const void* ptr2, size_t size);
C
복사
함수 설명
두 메모리 블록을 비교한다. ptr1이 가리키는 size바이트의 데이터와 ptr2가 가리키는 size바이트의 데이터를 비교한다.
Return Value
•
두 메모리 블록이 같으면 0을 반환
•
두 메모리 블록이 같지 않다면 *ptr1 - *ptr2 값을 반환
→ 두 메모리 블록이 다른 곳에서 ptr1의 값이 더 크면 0 보다 큰 값을 반환
→ 두 메모리 블록이 다른 곳에서 ptr2의 값이 더 크면 0 보다 작은 값을 반환
테스트 케이스
const char s1[] = "atoms\0\0\0\0"; // extra null bytes at end
const char s2[] = "atoms\0abc";
C
복사
9) strlcpy
함수 원형
#include <string.h>
size_t strlcpy(char* dest, const char* src, size_t size);
C
복사
함수 설명
•
원리는 strncpy와 비슷하지만 strncpy함수보다 오류가 적은 함수이다.
•
strncpy의 경우 NULL 문자 삽입을 보장하지 않는다.
•
strlcpy는 size가 0이 아닌 경우 size - 1 까지 복사를 진행하고 마지막에 NULL을 삽입해준다.
Return Value
src의 길이를 반환
10) strlen
함수 원형
#include <string.h>
size_t strlen(const char* str);
C
복사
함수 설명
문자열 str의 길이를 구한다. 아래와 같은 구문에서는 100을 리턴하지 않고 12를 리턴하게 된다.
char str[100] = "Hello World!";
C
복사
strlen 함수는 문자열의 마지막 NULL 문자에 의해 길이를 결정하기 때문이다.
Return Value
문자열의 길이를 반환
11) strlcat
함수 원형
#include <string.h>
size_t strlcat(char* dest, const char* src, size_t size);
C
복사
함수 설명
dest의 마지막 위치에 size - strlen(dest) - 1 만큼 복사하고 끝에 NULL을 삽입한다.
Return Valu e
•
size가 dest의 크기보다 작을 때, strlen(src) + size를 반환
•
size가 dest의 크기보다 클 때, strlen(src) + strlen(dest)를 반환
12) strchr
함수 원형
#include <string.h>
char* strchr(const char *s, int c);
C
복사
함수 설명
s가 가리키는 문자열에서 첫 번째 c (char로 변환)를 찾는다. c는 검색할 문자를 의미하고 int로 형 변환 되어서 전달되지만, 함수 내부적으로 다시 char로 처리된다. 마지막 NULL 문자도 문자열의 일부로 간주하기 때문에 이 함수는 문자열의 맨 끝 부분을 가리키는 포인터를 얻기 위해 사용할 수도 있다.
Return Value
•
s에서 문자열의 첫 부분부터 검색하여 찾고자 하는 문자가 가장 먼저 나타나는 주소를 반환
•
해당하는 문자가 없다면 NULL을 반환
13) strrchr
함수 원형
#include <string.h>
char* strrchr(const char *s, int c);
C
복사
함수 설명
s가 가리키는 문자열에서 마지막 c (char로 변환)를 찾는다. c는 검색할 문자를 의미하고 int로 형 변환 되어서 전달되지만, 함수 내부적으로 다시 char로 처리된다. 마지막 NULL 문자도 문자열의 일부로 간주하기 때문에 이 함수는 문자열의 맨 끝 부분을 가리키는 포인터를 얻기 위해 사용할 수도 있다.
Return Value
•
s에서 문자열의 끝 부분부터 검색하여 찾고자 하는 문자가 가장 먼저 나타나는 주소를 반환
•
해당하는 문자가 없다면 NULL을 반환
14) strnstr
함수 원형
#include <string.h>
char* strnstr(const char *haystack, const char *needle, size_t len);
C
복사
함수 설명
문자열 haystack에서 NULL로 끝나는 문자열 needle의 첫 번째 부분을 찾는다. 여기서 haystack 은 len 문자 이하로 검색된다. NULL 문자 뒤에 나타나는 문자는 검색되지 않는다.
Return Value
•
needle값이 비어 있다면 haystack를 반환
•
haystack문자열에서 needle 문자열을 찾지 못하면 NULL을 반환
•
needle 문자열을 찾으면, haystack에서 needle 문자열 시작 부분 위치 주소를 반환
테스트 케이스
#include<string.h>
#include<stdio.h>
int main()
{
char *haystack = "This";
char *needle = "is";
char *k = strnstr(haystack, needle, 4);
printf("%c", *k); // output : i
return (0);
}
C
복사
#include<string.h>
#include<stdio.h>
int main()
{
char *haystack = "This";
char *needle = "is";
char *k = strnstr(haystack, needle, 3);
printf("%c", *k); // output : segmentation fault
return (0);
}
C
복사
#include <stdio.h>
#include <string.h>
int main (void)
{
char str1[10] = "book";
char str2[5] = "oo";
char str3[5] = "o";
char str4[5] = "go";
char str5[5] = "og";
char str5[5] = "ob";
char str6[5] = "ookg";
printf("book - oo : %p\n", strnstr(str1, str2, 4));
printf("book - o : %p\n", strnstr(str1, str3, 4));
printf("book - go : %p\n", strnstr(str1, str4, 4));
printf("book - og : %p\n", strnstr(str1, str5, 4));
printf("book - ob : %p\n", strnstr(str1, str5, 4));
printf("book - ookg : %p\n", strnstr(str1, str6, 4));
printf("book - oo - 0byte : %p\n", strnstr(str1, str2, 0));
return (0);
}
C
복사
book - oo : 0x7ffee3c9daef
book - o : 0x7ffee3c9daef
book - go : 0x0
book - og : 0x0
book - ob : 0x0
book - ookg : 0x0
book - oo - 0byte : 0x0
C
복사
15) strncmp
함수 원형
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
C
복사
함수 설명
strncmp 함수는 문자열을 n자 이하로 비교한다. s1, s2는 각각 서로 비교할 문자열들이다. n은 (처음부터) 비교할 최대 문자의 개수이다. 매뉴얼에 쓰여 있는 lexicographically의 뜻은 아래와 같다. 더 자세한 것은 아래 링크를 참고하자.
DESCRIPTION
The strcmp and strncmp functions lexicographically compare the null-terminated strings s1 and s2.
Return Value
•
만일 n개의 문자가 모두 일치한다면, 0을 반환
•
비교한 n개의 문자 중 최초로 일치하지 않는 문자의 값이 s1이 더 큰 경우 0보다 큰 값을, s2가 더 큰 경우 0보다 작은 값을 반환
테스트 케이스
const char s1[] = "atoms\0\0\0\0"; // extra null bytes at end
const char s2[] = "atoms\0abc";
C
복사
16) atoi
함수 원형
#include <stdlib.h>
int atoi(const char *str);
C
복사
함수 설명
궁극적인 목표는 숫자로 표현되는 문자열의 초기 부분을 str에서 int로 변환하는 것이다. 숫자로 표현할 수 있는 문자가 나오기 전까지 공백 문자들을 모두 무시한다. 공백 문자를 무시한 후, 주어지는 문자들이 부호 혹은 숫자가 아니라면 변환이 이뤄지지 않는다. 또한 문자열이 공백 문자로만 이루어져 있어도 변환이 이루어 지지 않는다. 변환에 숫자를 이용하고, 더 이상 숫자가 나오지 않는다면 변환을 마치게 된다.
Return Value
부호를 처리한 int형 정수를 반환
테스트 케이스
printf("%d", ft_atoi("22433723768547758107"));
printf("%d", ft_atoi("9223372036854775808"));
printf("%d", ft_atoi("9223372036854775808"));
C
복사
17) isalpha
함수 원형
#include <ctype.h>
int isalpha(int c);
C
복사
함수 설명
c가 알파벳인지 판단한다. 이 때 매개 변수의 자료형이 char가 아닌 int인 이유는 EOF를 처리 해야하기 때문이다. char은 -128에서 127까지의 범위를 갖고 있으므로, 총 256개의 표현을 할 수 있는 타입이다. 따라서 char를 받게 되면 총 256가지의 경우로 반환을 할 수 있게 되는데, 이에 대해선 아스키 코드 및 확장에 대해서만 표현할 수 있기 때문에 EOF에 대해서는 처리 불가하게 된다. 결국, 256가지 (아스키 코드 및 확장)에 추가로 1가지 (EOF)를 처리하기 위해서는 int 타입이 필요하다.
EOF란 End Of File의 약자로 더 이상 데이터가 없음을 지칭한다. 따라서 파일의 끝을 나타내기 위해 사용되며, 파일의 끝에 도달했을 때 언제나 특별한 값을 반환하도록 만들어져 있다. (보통 -1을 반환한다.)
Return Value
•
알파벳이 아니라면 0을 반환
•
알파벳이라면 0이 아닌 정수를 반환 (이는 Implementation Defined Behavior이다. 따라서 대문자인 경우 1을 반환하고, 소문자인 경우 2를 반환하는 식으로 구현하는 것도 가능하다. 이를 통해 c가 소문자인지 대문자인지 한번에 파악하는 것이 가능하기도 하다.)
18) isdigit
함수 원형
#include <ctype.h>
int isdigit(int c);
C
복사
함수 설명
매개 변수 c에 들어오는 값이 숫자를 지칭하는 문자인지 판단한다.
Return Value
•
숫자를 지칭하는 문자가 아니라면 0을 반환
•
숫자를 지칭하는 문자라면 1을 반환
19) isalnum
함수 원형
#include <ctype.h>
int isalnum(int c);
C
복사
함수 설명
c가 알파벳 또는 숫자인지 확인한다.
Return Value
•
알파벳 또는 숫자이면 0이 아닌 값을 반환
•
둘 다 해당하지 않으면 0 반환
테스트 케이스
#include <ctype.h>
#include <stdio.h>
int main(void)
{
printf("%d\n", isalnum('a'));
printf("%d\n", isalnum('!'));
printf("%d\n", isalnum('1'));
printf("%d\n", isalnum(1));
printf("%d\n", isalnum(49));
return (0);
}
C
복사
1
0
1
0
1
C++
복사
20) isascii
함수 원형
#include <ctype.h>
int isascii(int c);
C
복사
함수 설명
c가 0 ~ 127 사이 값인 아스키 문자인지 확인한다.
Return Value
•
아스키 문자라면 0이 아닌 값을 반환
•
아스키 문자가 아니라면 0을 반환
테스트 케이스
#include <ctype.h>
#include <stdio.h>
int main(void)
{
printf("%d\n", isascii('a'));
printf("%d\n", isascii('!'));
printf("%d\n", isascii('1'));
printf("%d\n", isascii(0));
printf("%d\n", isascii(49));
printf("%d\n", isascii(128));
return (0);
}
C
복사
1
1
1
1
1
0
C
복사
21) isprint
함수 원형
#include <ctype.h>
int isprint(int c);
C
복사
함수 설명
c가 공백을 포함하여 출력 가능한 문자인지 확인한다. 32 ~ 126 사이의 값을 말한다.
Return Value
•
출력 가능한 문자이면 0이 아닌 정수를 반환
•
그렇지 않으면 0을 반환
테스트 케이스
#include <ctype.h>
#include <stdio.h>
int main(void)
{
printf("%d\n", isprint('a'));
printf("%d\n", isprint('!'));
printf("%d\n", isprint('1'));
printf("%d\n", isprint(0));
printf("%d\n", isprint(49));
printf("%d\n", isprint(128));
printf("%d\n", isprint(127));
printf("%d\n", isprint(32));
return (0);
}
C++
복사
1
1
1
0
1
0
0
1
C
복사
22) toupper
함수 원형
#include <ctype.h>
int toupper(int c);
C
복사
함수 설명
c로 들어온 값이 소문자에 해당한다면 이를 대문자로 변환한다. 이 때 매개 변수의 자료형이 char가 아닌 int인 이유는 EOF를 처리 해야하기 때문이다. char은 -128에서 127까지의 범위를 갖고 있으므로, 총 256개의 표현을 할 수 있는 타입이다. 따라서 char를 받게 되면 총 256가지의 경우로 반환을 할 수 있게 되는데, 이에 대해선 아스키 코드 및 확장에 대해서만 표현할 수 있기 때문에 EOF에 대해서는 처리 불가하게 된다. 결국, 256가지 (아스키 코드 및 확장)에 추가로 1가지 (EOF)를 처리하기 위해서는 int 타입이 필요하다.
EOF란 End Of File의 약자로 더 이상 데이터가 없음을 지칭한다. 따라서 파일의 끝을 나타내기 위해 사용되며, 파일의 끝에 도달했을 때 언제나 특별한 값을 반환하도록 만들어져 있다. (보통 -1을 반환한다.)
Return Value
•
소문자에 대응하는 대문자
•
소문자에 대응하는 대문자가 없으면, 매개 변수를 그대로 반환
23) tolower
함수 원형
#include <ctype.h>
int tolower(int c);
C
복사
함수 설명
c로 들어온 값이 대문자에 해당한다면 이를 소문자로 변환한다. 이 때 매개 변수의 자료형이 char가 아닌 int인 이유는 EOF를 처리 해야하기 때문이다. char은 -128에서 127까지의 범위를 갖고 있으므로, 총 256개의 표현을 할 수 있는 타입이다. 따라서 char를 받게 되면 총 256가지의 경우로 반환을 할 수 있게 되는데, 이에 대해선 아스키 코드 및 확장에 대해서만 표현할 수 있기 때문에 EOF에 대해서는 처리 불가하게 된다. 결국, 256가지 (아스키 코드 및 확장)에 추가로 1가지 (EOF)를 처리하기 위해서는 int 타입이 필요하다.
EOF란 End Of File의 약자로 더 이상 데이터가 없음을 지칭한다. 따라서 파일의 끝을 나타내기 위해 사용되며, 파일의 끝에 도달했을 때 언제나 특별한 값을 반환하도록 만들어져 있다. (보통 -1을 반환한다.)
Return Value
•
대문자에 대응하는 소문자
•
대문자에 대응하는 소문자가 없으면, 매개 변수를 그대로 반환
3. libft.h
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* libft.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jseo <jseo@student.42seoul.kr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/12/22 15:13:53 by jseo #+# #+# */
/* Updated: 2020/12/25 20:20:54 by jseo ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef LIBFT_H
# define LIBFT_H
# include <stdlib.h>
# include <unistd.h>
typedef struct s_list
{
void *content;
struct s_list *next;
} t_list;
int ft_atoi(const char *s);
void ft_bzero(void *s, size_t n);
void *ft_calloc(size_t cnt, size_t n);
int ft_isalnum(int c);
int ft_isalpha(int c);
int ft_isascii(int c);
int ft_isdigit(int c);
int ft_isprint(int c);
char *ft_itoa(int n);
void *ft_memccpy(void *dst, const void *src, int c, size_t n);
void *ft_memchr(const void *s, int c, size_t n);
int ft_memcmp(const void *s1, const void *s2, size_t n);
void *ft_memcpy(void *dst, const void *src, size_t n);
void *ft_memmove(void *dst, const void *src, size_t n);
void *ft_memset(void *s, int c, size_t n);
void ft_putchar_fd(char c, int fd);
void ft_putendl_fd(char *s, int fd);
void ft_putnbr_fd(int n, int fd);
void ft_putstr_fd(char *s, int fd);
char **ft_split(char const *s, char c);
char *ft_strchr(const char *s, int c);
char *ft_strdup(const char *s);
char *ft_strjoin(char const *s1, char const *s2);
size_t ft_strlcat(char *dst, const char *src, size_t dstsize);
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize);
size_t ft_strlen(const char *s);
char *ft_strmapi(char const *s, char (*f)(unsigned int, char));
int ft_strncmp(const char *s1, const char *s, size_t n);
char *ft_strnstr(const char *s1, const char *set, size_t n);
char *ft_strrchr(const char *s, int c);
char *ft_strtrim(char const *s1, char const *set);
char *ft_substr(char const *s, unsigned int start, size_t len);
int tolower(int c);
int toupper(int c);
int ft_lstsize(t_list *lst);
void ft_lstadd_back(t_list **lst, t_list *new);
void ft_lstadd_front(t_list **lst, t_list *new);
void ft_lstclear(t_list **lst, void (*del)(void *));
void ft_lstdelone(t_list *lst, void (*del)(void *));
void ft_lstiter(t_list *lst, void (*f)(void *));
t_list *ft_lstlast(t_list *lst);
t_list *ft_lstmap(t_list *lst, void *(*f)(void *),
void (*del)(void *));
t_list *ft_lstnew(void *content);
#endif
C
복사
4. Makefile
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: jseo <jseo@student.42seoul.kr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/12/22 14:44:25 by jseo #+# #+# #
# Updated: 2021/01/01 00:47:04 by jseo ### ########.fr #
# #
# **************************************************************************** #
NAME = libft.a
SRCS = ft_atoi.c \
ft_bzero.c \
ft_calloc.c \
ft_isalnum.c \
ft_isalpha.c \
ft_isascii.c \
ft_isdigit.c \
ft_isprint.c \
ft_itoa.c \
ft_memccpy.c \
ft_memchr.c \
ft_memcmp.c \
ft_memcpy.c \
ft_memmove.c \
ft_memset.c \
ft_putchar_fd.c \
ft_putendl_fd.c \
ft_putnbr_fd.c \
ft_putstr_fd.c \
ft_split.c \
ft_strchr.c \
ft_strdup.c \
ft_strjoin.c \
ft_strlcat.c \
ft_strlcpy.c \
ft_strlen.c \
ft_strmapi.c \
ft_strncmp.c \
ft_strnstr.c \
ft_strrchr.c \
ft_strtrim.c \
ft_substr.c \
ft_tolower.c \
ft_toupper.c
BNS_SRCS = ft_lstsize.c \
ft_lstadd_back.c \
ft_lstadd_front.c \
ft_lstclear.c \
ft_lstdelone.c \
ft_lstiter.c \
ft_lstlast.c \
ft_lstmap.c \
ft_lstnew.c
OBJS = $(SRCS:%.c=%.o)
BNS_OBJS = $(BNS_SRCS:%.c=%.o)
FLAGS = -Wall -Wextra -Werror
$(NAME) : $(OBJS)
gcc $(FLAGS) -c $(SRCS) -I./
ar rc $(NAME) $(OBJS)
all : $(NAME)
bonus : $(NAME)
gcc $(FLAGS) -c $(BNS_SRCS) -I./
ar rc $(NAME) $(BNS_OBJS)
clean :
rm -f $(OBJS) $(BNS_OBJS)
fclean : clean
rm -f $(NAME)
re : fclean all
.PHONY : all clean fclean re
Plain Text
복사