2/01/2016

GNU Make 의 Makefile 구성 (추후 문서 작성)

1. GNU Make를 이용하여 Makefile 구성 

이전에 알아두었던 내용으로, 이제 각각의 Makefle을 구성을 해보자.
하지만, 각각의 Makefile의 구성마다 구성방법을 다르게 하겠다.

일단, Main Source 맨 위에 존재하고, 각각의 directory 안에 source가 함수가 존재하며, 이는 이는 Main 함수에 종속이 된다고 가정하겠다.
그리고, 이에 기반으로 Makefile을 만들어 보겠다.


2. 기본 Makefile 만들기 

보통 Makefile을 만든다고 하면 Build를 위해 만들것이며, 아래와 같이 두 부류로 구성이 가능할 것 같다.
보통 이렇게 많이들 사용하는 것 같다.


이를 이해 하기전에 Static/Shared Library 및 관련사항을 알고 가자.
  • Linux Static 와 Shared Library의 기본이해 
아래에서 GCC를 이용하여 Static Library와 Shared Library를 생성하는 법을  간단히 익혀보자.
      http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
      http://blog.naver.com/PostView.nhn?blogId=xogml_blog&logNo=130138049704

    간단하고, 속도가 요하는 부분 Static library 하고 Shared library는 대부분 open source때문에 사용할게 될 것이다.

    • Binutils Manual (ar/ranlib/nm ... so on)
    상위 Library 와 이해하기 위해서 GCC Manual과 Binutil Manual 은 대충을 알아두자.
      https://sourceware.org/binutils/docs/binutils/index.html#Top


    2.1  Makefile (Library 기반구축)

    하부 Directory 존재하여 이를 재귀호출하여 매번 Library로 만들어 구성하고
    Main에서는 만들어진 Library를  하나로 통합하는 방식을 구축하는 방식이다.
    여기서 핵심은 Library를 만드는 법이 핵심이다.

    우선 Linux의 Library의 개념을 정확히 이해를 하고 이를 진행하도록 하자
    개발자라면, ELF(Executable and Linkable Format) 대해서도 알 것이며,
    만약 모르다면,  Library 개념도 대충 알고 넘어가자.

    • Shared Library 사용할 경우 설정 
    Shared Library를 사용하기 위해서는 링킹로더가 Shared Library 찾기 위해서 아래의 설정을 해주자.


    1. LD_LIBRARY_PATH 별도 설정 
    2. Shared Library 기존에 존재하던 Shared Library Directory에 복사

      http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html


    • Sample Makefile 
    내가 아래와 같이 Linux에서 Static/Shared Library 와 함께 사용 가능하도록 Sample Makefile을 만들어보았다.

      https://github.com/JeonghunLee/make_ex_libs
                          (Download)


    아래가 최종적으로 실행되는 프로그램이며, ./libs 참조하여 -lsub1, -lsub2 참조하고
    tst1.o와 tst2.o를 참조하여 Test Program을 완성하였다.

     // libsub1 만드는 과정 
    libsub1
    ar  rv libsub1.a sub1.o sub2.o     //v는 verbose version 기능 과 r은 static library 기능을 수행  
    r - sub1.o
    r - sub2.o
    ranlib libsub1.a                   // 만들어진 library의 index를 만들어준다. (심볼테이블)
    install libsub1.a ../libs          // 만들어진 library를 ../libs 이동 
    
    // libsub2 만드는 과정              // 상위와 동일 
    libsub2
    ar  rv libsub2.a sub1.o sub2.o
    r - sub1.o
    r - sub2.o
    ranlib libsub2.a
    install libsub2.a ../libs
    
    // 만들어진 /libs 디렉토리에 안에 아래와 같이 두개의 library와  별도의 두개의 tst1.o, tst2.o 와 묶어 
    // MainTest.o 빌드하여 Program 완성 
    
    gcc -Iinclude -o MainTest MainTest.o  tst1.o tst2.o -L. -L./libs -lsub1 -lsub2  


    2.2  Makefile ( object 기반)

    하부 Directory가 많이 존재하지만, 이 전체를 전부 object로 빌드 한 후 Main에서 통합하여 관리하는 방식이다.
    상위 방식하고 차이라면, Library를 구성하지 않는 다는 것이며, 어떻게 보면, Static Library이다.

    이곳에서 구성할때 문제라고 하면 바로 sub directory의 include의 종속사항이다.
    그러므로 Makefile에서 그런부분을 선언을 별도로 해줘야한다.

    • Sample Makefile 

      아래와 같이 동일하게 Sample Makefile을 만들어 보았다.
      https://github.com/JeonghunLee/makefile_exmple_with_objs
                          (Download)


    ti-processor-sdk-linux-am335x-evm-03.00.00.04/example-applications/arm-benchmarks-1.3/dhrystone
    ~/am335x/ti-processor-sdk-linux-am335x-evm-03.00.00.04/example-applications/omapconf-1.72


    3. 관리용 Makefile  (재귀호출)

    상위 처럼 직접 Build용으로 Makefile을 만들기도 하지만, 다른 Makefile을 호출하여,
    즉 관리용 Makefile로 구성이 가능하다.

    Make의 재귀호출을 이용하여, 여러 Opensource 관리하거나, Make 후, Install을 하여,
    각각의 파일들을 관리하는 방법에 대해 기본적으로 알아보자.
    이는 보통 하위 Makefile이 많을 경우 단계를 나누어서 생각을 하는 것이 좋다.


    • 일반적인 재귀 호출들

    아래와 같이 구성을 하면, SubMake가  빌드가 될 것은 되겠지만, 한가지씩 문제점들이 발생한다.
    바로 install 문제점 이며, Make간의 변수통신일 것이다.
    그리고 대체적으로 PATH 문제도 많이 발생할 것이다 왜냐하면, 절대 PATH를 사용하지 않고 사용하는 Make가 존재하여, 이 문제들을 해결해보자.


    BASE_DIR := $(shell pwd)        # Sub Make도 이렇게 사용한다면 문제가 발생 할 것이다. 
    
    subsystem:
            cd subdir && $(MAKE)   # directory 변경하여 make 시도 
    
    subsystem:
            cd subdir && $(MAKE)  -l ../RuleMake       # -l include 다른 Make 참조 
    
    subsystem:
            cd subdir && $(MAKE)  -sk   # -s  silent, -k keep going, s와 k 만 다음 subMake에 전달됨 주의. 
    
    subsystem:
            cd subdir && $(MAKE)  -j 3  # 동시 작업수  
    
    subsystem:
            $(MAKE) -C subdir   ARCH=arm CROSS_COMPILE=$(ARM_PREFIX)    # directory 변경하여 make 시도  
            $(MAKE)  install   
    
    subsystem:
            $(MAKE) -f Makefile.mk   # -f file을 이용하여 외부 Makefile 적용한다.
    
    subsystem:
            cd subdir && $(MAKE) -f Makefile.mk clean    # -f file을 이용하여 외부 Makefile 적용한다.
    
    

    • Make 재귀호출 Manual
      https://www.gnu.org/software/make/manual/html_node/Recursion.html



    target: 
            @echo test start 
            -rm -f *.o                
            -chown -R jhlee:jhlee ./    # root 에서 문제 발생 , 원래는 sudo make 실행  
            @echo test end 
    

    target: 
            @echo test start 
            mkdir -p $(SUBDIRS)      # directory 생성 
            @echo test end  
    

    
    
    • Recipes의 에러무시 
      관리를 하다보면, 상대방의 Makefile 파일이기때문에 Recipes 중 에러가 발생했지만,
      이 에러를 무시하고 싶을 경우가 발생한다. 특히 중간 하나만,

      그럴 경우 recipes의 앞에 '-'을 붙혀주고 실행하거나, make의 옵션 '-k'를 이용하자

      https://www.gnu.org/software/make/manual/html_node/Errors.html#Errors

      https://stackoverflow.com/questions/17834582/run-make-in-each-subdirectory



    MainMake 과  SubMake의 분리하고 사용하고 이를 재귀호출할 경우 발생되는 부분이 바로 통신 부분이다.
    Main Make에서는 골치아픈지만, 위 사실을 알고 사용해야 한다.

    또 한가지는 바로 성능부분과 타겟의 이름충돌를 고려해서 PHONY를 이용하는 것이다.
    솔직히 이름충돌보다는 성능부분이 더 고려가 되겠다.



    • SubMake와 통신방법 
        SubMake와 통신은 두가지로 나누어 볼수 있다.

    1. Makefile 내부의 변수 문제부분  (export 와 unexport 로 해결)
    2. Make가 재귀 호출이 되어서 Make의 Option이 지속적으로 전달되는 부분

      https://www.gnu.org/software/make/manual/html_node/Variables_002fRecursion.html
      https://www.gnu.org/software/make/manual/html_node/Options_002fRecursion.html#Options_002fRecursion



    다음으로 make에 줄 수 있는 옵션들이며, 이는 관리용 make를 만들경우 중요하다.
    이를 이용하여, 관리용 makefile을 만들어보자.
    아래와 같이 Make의 재귀를 이용하여 Main에서 Sub Make를 관리가 가능하다.

    • Make의 호출시 다양한 옵션 소개 
      Make를 호출 할 경우, 옵션을 주어 기능을 확장이 가능하다,
      아래에서 각 기능을 확인하자.

      https://www.gnu.org/software/make/manual/html_node/Options-Summary.html




    ~/am335x/ti-processor-sdk-linux-am335x-evm-03.00.00.04/example-applications/arm-benchmarks-1.3

    댓글 없음 :