وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

چگونه یک Makefile بنویسیم – تنظیم خودکار پایتون، کامپایل و آزمایش

0 32
زمان لازم برای مطالعه: 6 دقیقه


معرفی

هنگامی که می خواهید پروژه ای را اجرا کنید که دارای چندین منبع، منابع و غیره است، باید مطمئن شوید که تمام کدها قبل از کامپایل یا اجرا شدن برنامه اصلی دوباره کامپایل شده اند.

به عنوان مثال، تصور کنید نرم افزار ما چیزی شبیه به این است:

main_program.source -> uses the libraries `math.source` and `draw.source`
math.source -> uses the libraries `floating_point_calc.source` and `integer_calc.source`
draw.source -> uses the library `opengl.source`

بنابراین اگر تغییری در آن ایجاد کنیم opengl.source به عنوان مثال، ما باید هر دو را دوباره کامپایل کنیم draw.source و main_program.source زیرا می خواهیم پروژه ما به روز باشد روی همه به پایان می رسد

این کار بسیار خسته کننده و زمان بر است process. و از آنجایی که همه چیزهای خوب در دنیای نرم افزار ناشی از تنبلی برخی مهندسان برای تایپ چند دستور اضافی است، Makefile متولد شد

Makefile از make ابزار، و اگر بخواهیم کاملاً دقیق باشیم، Makefile فقط فایلی است که کدی را در خود جای داده است که make استفاده های سودمند با این حال، نام Makefile بسیار بیشتر قابل تشخیص است.

Makefile اساساً پروژه شما را با بازسازی تنها قسمت های ضروری کد منبع شما به روز نگه می دارد children قدیمی هستند. همچنین می تواند کامپایل، ساخت و آزمایش را خودکار کند.

در این زمینه، الف child یک کتابخانه یا تکه ای از کد است که برای اجرای کد والد آن ضروری است.

این مفهوم بسیار مفید است و معمولاً با آن استفاده می شود تدوین شده است زبانهای برنامه نویسی. حالا ممکن است از خود بپرسید:

پایتون نیست تفسیر کرد زبان؟

خوب، پایتون از نظر فنی هر دو تفسیر شده است و زبان کامپایل شده، زیرا برای اینکه بتواند یک خط کد را تفسیر کند، باید آن را به صورت کد بایتی از پیش کامپایل کند که برای یک CPU خاص کدگذاری نشده است و می تواند پس از آن اجرا شود.

توضیح مفصل تر و در عین حال مختصرتری می توان یافت روی وبلاگ ند بچلدر. همچنین، اگر نیاز به تجدید کننده دارید روی روش عملکرد پردازشگرهای زبان برنامه نویسی، ما شما را تحت پوشش قرار داده ایم.

تفکیک مفهوم

از آنجایی که Makefile تنها ترکیبی از چندین مفهوم است، برای نوشتن یک Makefile باید چند چیز را بدانید:

  1. اسکریپت Bash
  2. عبارات با قاعده
  3. نشانه گذاری هدف
  4. درک ساختار فایل پروژه شما

با در دست داشتن این ها، می توانید دستورالعمل هایی برای آن بنویسید make کامپایل خود را کاربردی و خودکار کنید.

ضربه شدید هست یک زبان فرمان (این نیز یک است پوسته یونیکس اما در حال حاضر واقعاً مرتبط نیست)، که ما از آن برای نوشتن دستورات واقعی یا تولید خودکار فایل استفاده خواهیم کرد.

مثلاً اگر بخواهیم echo تمام نام های کتابخانه به کاربر:

DIRS=project/libs
for file in $(DIRS); do
    echo $$file
done

نشانه گذاری هدف روشی برای نوشتن است که فایل ها وابسته هستند روی فایل های دیگر به عنوان مثال، اگر بخواهیم وابستگی های مثال گویا در بالا را با نماد هدف مناسب نشان دهیم، می نویسیم:

main_program.cpp: math.cpp draw.cpp
math.cpp: floating_point_calc.cpp integer_calc.cpp
draw.cpp: opengl.cpp

تا آنجایی که ساختار فایل می رود، بستگی دارد روی زبان برنامه نویسی و محیط شما برخی از IDE ها به طور خودکار نوعی Makefile را نیز تولید می کنند و نیازی به نوشتن آن از ابتدا نخواهید داشت. با این حال، اگر می خواهید آن را تغییر دهید، درک نحو بسیار مفید است.

گاهی اوقات تغییر Makefile پیش فرض حتی اجباری است، مانند زمانی که می خواهید OpenGL و CLion را با هم خوب بازی کنند.

اسکریپت Bash

Bash بیشتر برای اتوماسیون استفاده می شود روی توزیع های لینوکس، و برای تبدیل شدن به یک “جادوگر” لینوکس کاملاً قدرتمند ضروری است. همچنین یک زبان اسکریپت ضروری است که آن را بسیار خوانا و آسان می کند. توجه داشته باشید که می توانید بدوید bash روی سیستم های ویندوز، اما واقعاً مورد استفاده رایجی نیست.

ابتدا اجازه دهید یک برنامه ساده “Hello World” در Bash را مرور کنیم:






echo "Hello world!"

هنگام ایجاد یک اسکریپت، بسته به روی جریان شما umask، ممکن است خود اسکریپت قابل اجرا نباشد. با اجرای خط کد زیر می توانید این مورد را تغییر دهید terminal:

chmod +x name_of_script.sh

این اجازه اجرا را به فایل هدف اضافه می کند. با این حال، اگر می خواهید مجوزهای خاص تری بدهید، می توانید چیزی شبیه به دستور زیر را اجرا کنید:

chmod 777 name_of_script.sh

اطلاعات بیشتر روی chmod روی این لینک.

در مرحله بعد، اجازه دهید به سرعت برخی از اصول اولیه را با استفاده از ساده مرور کنیم if– بیانیه ها و متغیرها:

#!/bin/bash

echo "What's the answer to the ultimate question of life, the universe, and everything?"
read -p "Answer: " number

echo "Your answer: $number computing..."


if (( number == 42 ))
then
    echo "Correct!"
    
elif (( number == 41 || number == 43 )); then
    echo "So close!"
    
else
    echo "Incorrect, you will have to wait 7 and a half million years for the answer!"
fi

اکنون، یک روش جایگزین برای نوشتن کنترل جریان وجود دارد که در واقع رایج‌تر از دستورات if است. همانطور که همه ما می دانیم عملگرهای بولی را می توان برای تنها هدف ایجاد عوارض جانبی استفاده کرد، چیزی مانند:

++a && b++  

به این معنی که ما ابتدا افزایش می دهیم a، و سپس بسته به روی زبانی که از آن استفاده می کنیم، بررسی می کنیم که آیا مقدار عبارت به آن ارزیابی می شود یا خیر True (به طور کلی اگر یک عدد صحیح باشد >0 یا =/=0 به معنای آن است boolean ارزش است True). و اگر باشد True، سپس افزایش می دهیم b.

این مفهوم نامیده می شود اجرای مشروط و بسیار رایج در bash اسکریپت نویسی، به عنوان مثال:

#!/bin/bash


echo "Checking if project is generated..."


if ( -d project_dir )
then
    echo "Dir already generated."
else
    echo "No directory found, generating..."
    mkdir project_dir
fi

این را می توان با استفاده از یک اجرای شرطی بازنویسی کرد:

echo "Checking if project is generated..."
( -d project_dir ) || mkdir project_dir 

یا، می‌توانیم آن را با عبارات تودرتو فراتر ببریم:

echo "Checking if project is generated..."
( -d project_dir ) || (echo "No directory found, generating..." && mkdir project_dir)

سپس دوباره، عبارات تودرتو می توانند به سوراخ خرگوش منتهی شوند و می توانند بسیار پیچیده و ناخوانا شوند، بنابراین توصیه نمی شود حداکثر بیش از دو عبارت در تودرتو قرار گیرند.

ممکن است با چیزهای عجیب گیج شوید ( -d ) نماد استفاده شده در قطعه کد بالا، و شما تنها نیستید.

دلیل این امر این است که عبارات شرطی اولیه در Bash با استفاده از عبارت نوشته شده اند test (EXPRESSION) فرمان اما زمانی که مردم شروع به نوشتن عبارات شرطی در پرانتز کردند، Bash، البته با یک هک بسیار ناآگاهانه، فقط با ترسیم مجدد ( شخصیت به test فرمان، با ) به معنای پایان عبارت است که به احتمال زیاد بعد از واقعیت اجرا می شود.

به همین دلیل می توانیم از دستور استفاده کنیم test -d FILENAME که بررسی می کند آیا فایل ارائه شده وجود دارد و یک دایرکتوری است، مانند این ( -d FILENAME ).

عبارات با قاعده

عبارات منظم (به اختصار regex) یک راه آسان برای تعمیم کد به ما می دهد. یا بهتر بگوییم برای تکرار یک عمل برای زیرمجموعه خاصی از فایل ها که معیارهای خاصی را دارند. ما برخی از اصول regex و چند مثال را در قطعه کد زیر پوشش خواهیم داد.

توجه داشته باشید: وقتی می گوییم که یک عبارت صید می کند ( -> ) یک کلمه، به این معنی است که کلمه مشخص شده در زیر مجموعه کلماتی است که عبارت منظم تعریف می کند:


rasanegar -> rasanegar
rasanegar -> rasanegar


Stack|Abuse -> Stack
            -> Abuse
Stack(Abuse|Overflow) -> rasanegar
                      -> StackOverflow


The answer to life the universe and everything is( 42)?...
    -> The answer to life the universe and everything is...
    -> The answer to life the universe and everything is 42...
    



He is my( great)+ uncle Brian. -> He is my great uncle Brian.
                               -> He is my great great uncle Brian.

He is my great( great)* uncle Brian.

این فقط حداقل چیزی است که برای آینده نزدیک با Makefile نیاز دارید. اگر چه، روی در دراز مدت، یادگیری عبارات با قاعده یک است واقعا ایده خوبی است.

نشانه گذاری هدف

پس از همه اینها، اکنون می‌توانیم در نهایت وارد دستور Makefile شویم. نشانه گذاری هدف فقط راهی برای نمایش تمام وابستگی هایی است که بین فایل های منبع ما وجود دارد.

بیایید به مثالی نگاه کنیم که ساختار فایلی مشابه مثال ابتدای مقاله دارد:


main_program.pyc: main_program.py
    python compile.py $<
math.pyc: math.py
    python compile.py $<	
draw.pyc: draw.py
    python compile.py $<


main_program.pyc: main_program.py math.pyc draw.pyc
    python compile.py $<
math.pyc: math.py floating_point_calc.py integer_calc.py
    python compile.py $<	
draw.pyc: draw.py opengl.py
    python compile.py $<

به خاطر داشته باشید که موارد فوق صرفاً به منظور روشن شدن روش عملکرد نماد هدف است. در پروژه های پایتون مانند این بسیار به ندرت استفاده می شود، زیرا تفاوت در عملکرد در بیشتر موارد ناچیز است.

در بیشتر مواقع از Makefiles برای راه اندازی یک پروژه، پاکسازی آن، شاید کمک و آزمایش ماژول های شما استفاده می شود. در زیر نمونه‌ای از Makefile پروژه بسیار واقعی‌تر پایتون است:



PYTHON = python3



.PHONY = help setup test run clean


FILES = input output



.DEFAULT_GOAL = help


help:
    @echo "---------------HELP-----------------"
    @echo "To setup the project type make setup"
    @echo "To test the project type make test"
    @echo "To run the project type make run"
    @echo "------------------------------------"



setup:
    
    @echo "Checking if project files are generated..."
    ( -d project_files.project ) || (echo "No directory found, generating..." && mkdir project_files.project)
    for FILE in ${FILES}; do \
        touch "project_files.project/$${FILE}.txt"; \
    done



test:
    ${PYTHON} -m pytest
    
run:
    ${PYTHON} our_app.py


clean:
    rm -r *.project

با در نظر گرفتن آن، اجازه دهید تا را باز کنیم terminal و اجرا کنید Makefile برای کمک به ما در تولید و کامپایل یک پروژه پایتون:

در حال اجرا make with makefile

نتیجه

Makefile and make می تواند زندگی شما را بسیار آسان تر کند و تقریباً با هر فناوری یا زبانی قابل استفاده است.

این می تواند بیشتر ساختمان و آزمایش شما و بسیاری موارد دیگر را خودکار کند. و همانطور که از مثال بالا مشاهده می شود، می توان آن را با هر دو زبان تفسیر شده و کامپایل استفاده کرد.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-17 00:52:04

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید