Archive for the ‘Development’ Category.

telegram bot 테스트 노트

얼마전, telegram 공개 채널을 한번 만들어 보았다.

https://t.me/okkykr

그리고, bot을 다시 한번 테스트 해볼까 시동을 걸었다.

시작은.. 검색 ‘telegram python bot’

https://github.com/python-telegram-bot/python-telegram-bot

git clone 받고, git submodule update 하고, …

… 두둥 …


ImportError: No module named future.backports.urllib

음, … pip install을 피하고자 했는데, …
음, … future란 것도 모듈이네, 이런 건 설치해보자.

https://pypi.python.org/pypi/future/0.16.0
다운로드 받고, setup.py install 사용해서 설치함.

다시한번


>>> import telegram
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "telegram/__init__.py", line 94, in <module>
from .bot import Bot
File "telegram/bot.py", line 34, in <module>
from telegram.utils.request import Request
File "telegram/utils/request.py", line 31, in <module>
import certifi
ImportError: No module named certifi

… 두둥 …

certifi란 것도 필요하구나.
https://pypi.python.org/pypi/certifi/2017.7.27.1
그런데, … .whl 음.. 느낌이 안 좋다.

pip를 설치하자.
https://stackoverflow.com/questions/17271319/how-do-i-install-pip-on-macos-or-os-x

다음. pip install certifi

다시한번


>>> import telegram
>>>

되는 것 같다.

… 잠시 추가로 테스트 …
( bot을 만드는 것도, telegram은 웹 관리자 화면 같은 걸 통하지 않고 봇에게 말을 걸어서 만든다. … 만들었다. )

… 1분 후, …


>>> import telegram
>>> bot = telegram.Bot(token='nnnnnn:alphanumber')
>>> bot.get_me()
<telegram.user.User object at 0x10x10x10x>
>>>

된다.

… 10분 후, …
봇에게 말을 걸어보고, 봇이 응답하게 해보았다.


>>> updates = bot.get_updates()
>>> updates
[]
>>> updates = bot.get_updates()
>>> updates
[<telegram.update.Update object at 0x10x10x10x>, <telegram.update.Update object at 0x10x10x10x>]
>>> chat_id = bot.get_updates()[-1].message.chat_id
>>> chat_id
1x60x39x2
>>> bot.send_message(chat_id=chat_id, text="I'm a bot")
<telegram.message.Message object at 0x10x10x10x>

다음 단계, bot 을 채널에 초대해보자.

https://stackoverflow.com/questions/42674340/how-to-join-my-telegram-bot-to-public-channel
https://stackoverflow.com/questions/33126743/how-do-i-join-my-bot-to-the-channel

관리자가 관리자로 추가할 수 있군.

… 8분 후, …


>>> bot.send_message(chat_id='@dgkimnet', text='hi')
<telegram.message.Message object at 0x10x10x10x>

올, 된다. 지금 만든 것은, 말하기 전용? 이지만. 되긴 된다. 듣고 반응하는 것도 가능하겠지만. 지금 하기에는 dgkim이 너무 나태하다.

ps. 워드프레스에서 코드 활용할 때, lt, gt 넣는 것 참 번거롭네.

심심해서 적어보는, 건축과 프로그래밍 관련 비유.

언어나 프레임워크에 대해서, 뭔가 거창하게 비유할 것은 아니고, 걍 단순하게 분류해본다.

Java : 철근 콘크리트 구조물.
Java + Spring + Spring WebMVC : 철근 콘크리트 아파트에, 4-Bay 설계?

Bootstrap, vuejs, dojo 등 : 인테리어 자재

Django : 컨테이너집? – 뭔가 집으로서의 기능을 패키지로 모두 제공해 주는 느낌이다.

PHP : 목조 주택? – 뭔가 가벼운 재료를 사용해서, 쉽게 뚝딱뚝딱 만들어 붙이면 될 것 같은 느낌이다. – 예전 같으면, 통나무집 느낌이었으나, 요즘은 규격화된 재료를 사용하는 목조 주택이다.

그래서, 내가 회사를 꾸민다고 하면, 시스템들은 Java로 단단하게 만든 주요 시스템과, 그때 그때 필요에 따라 만드는 카페 같은 Django를 놓기도 하고, 뭔가 새로운 형태를 만들고 싶으면 PHP 등을 사용해서, 전혀 새로운 형태도 만들어 보기도 할 것 같다.


현재, 나는 경험이 가장 많은 것은 Java Spring이지만, 주력 언어로 4개는 기본으로 가져가려 한다. Java, Python, PHP, Javascript … 선호도로는 Javascript가 앞에 서야 하지만.

ps. django가 특징이 있어 넣었는데, … python은 위에 PHP 자리에 넣어도 설명은 바뀌지 않는다, … php보다는 python 언어가 끌리는데, … 뭔가 두서 없는 …

북마크 프로그램 만들려 하면서, …

일전 포스트에서 적었듯, SiteBar( http://sitebar.org/ ) 대신할 프로그램을 만들어볼까 고민중인데, …

기술적인 구현도 문제지만 ( RESTful Server, 인증 )

개념적인 구현도, 막상 닥쳐보니 고민할 것이 많다.

우선, Tag 개념은 넣을려고 하는데, 이건 그리 복잡하지 않을 수 있겠다 싶기도 한데, …
( 실제 데이터 모델을 생각하니 복잡할 수도. … )

먼저, Category 혹은 Directory 개념은 있어야 할 듯 하고, 바로 막막하네, …
그래서, 잠시 ownCloud 같은 클라우드를 백으로 활용할까 생각하고, …

Directory 개념은 Tree 구조로 가져가는 것이 복잡할 것 같지만, 향후를 생각해도 기본적인 것 같아 복잡하다.

추가로, … public, private 개념을 두려고 하니, … 또 하나, ACL 넣기가 필요하다.

역시나 기존에 구현된 filesystem의 권한 및 tree 구조를 바로 활용하면 편한데, …
이번 프로젝트는 직접 구현해 보는 것이 목표라서 re-inventing wheel은 하려고 한다.

firefox의 bookmark API는 우선 고려 대상에서 제외하고, ( bookmark를 사용할 분들은 잘 사용하시고, 나는 따로 서버에 두고, bookmark와는 별개의 sidebar와 web interface, 앱 인터페이스로 가려고 한다 … )

그래서 생각하는 것이, sidebar를 사용하고, 거기에 SiteBar와 유사하게 디렉토리 구조를 표현하면서, drag and drop을 편하게 해 보고자 한다.

drag and drop은 내 블로그에 전에 테스트하던 것을 참조하면서도, 오늘 추가로 아래 자료도 보고,
https://developer.mozilla.org/en-US/docs/Web/Events/drop
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations
https://24ways.org/examples/marking-up-a-tag-cloud/example.html

게시판도 하나 직접 만들어보지 않은 dgkim이라, directory, acl, tag, 인증을 적절하게 만들어보면, 다른 업무용 프로그램 만드는데도 쉽게 재활용할 수 있지 않을까 기대하는데, …
기존 구현된 tree나 relation, rdb 구조를 보면 어렵지는 않을 것 같은데, 로직 코드를 그다지 꺼내쓰듯 하지 못하니 어려움으로 다가오는듯 하다.

ps. 그리고, 만들고 나서는 현재의 2900여개의 북마크를 이전해야 하는데, …
여전히, 내 자료 저장은 좀 다양한 도구에 의존하는데, 개선해야 하나 싶기도 하고, … 메일, 블로그, 클라우드, 파일서버, 북마크, 노트, …

그러고 보니, 북마크를 만들고 나면, 자신감을 가지고 노트도 대신할 것을 만들까 싶지만, 거기에는 문서 표현(wiki? or html?)이라는 어려운 벽이 또 하나 있다.

firefox sidebar를 준비해보다…

아래 삽질 기록이 좀 있습니다만.

우선, 기본적인 클라이언트측 컨셉은 가능하겠다는 판단까지 왔습니다.

우선, webextension 예제에서 2가지를 테스트하였고, 조합하면 동작할 것 같습니다.

https://github.com/mdn/webextensions-examples/tree/master/annotate-page
위 예제를 통해서, sidebar를 띄우는 방법이 나왔습니다.
단, sidebar 내용이 서버측 내용이 아닌 로컬 내용인데, 로컬에서 커버할지 웹을 띄울지 고민이 필요한 것 같습니다.

https://github.com/mdn/webextensions-examples/tree/master/bookmark-it
bookmark에 바로 접근하는 것이 가능한 것으로 나오는데,
이걸 활용하고, 로컬 북마크와 서버측 북마크를 연동할 것인지는 고민이 필요합니다.

annotate-page는 sidebar에 뭔가 표시가 가능하다는 것을 의미하며,
bookmark-it은 currentTab.url에 접근 가능하고, XHR 요청이 가능하다는? 것이 테스트되었습니다.

이제 이걸 쓸만하도록 클라이언트 앱을 만드는 것이 필요한데, …
먼저 해결해야할 산이 남은 것이 아래 적은 것과 같이. codeigniter restful 서버 만드는 것, 그 전에 인증 문제 해결하는 것 등이 남았네요. 웹에 표현하는 tag cloud 같은 건 논외로 하더라도, …

어쨌든, firefox extension 완성되면, codeigniter 버전도 만들어 보고, django 버전도 만들어 보면 좋겠다는 계획입니다. … 이 계획이 언제 실현되어 제품으로 나올지는 모르겠지만 … spring에서는 restful API나, spring-security가 경험이 있어 model만 만들면 바로 동작하는 것은 만들 수 있겠다고 생각하지만,, …. 무엇보다 큰 문제는, 사용자 웹 인터페이스가 …


예전에는 SiteBar라는 프로그램을 사용하여 북마크를 관리?했었습니다.

그러던 중, SiteBar가 PHP7과 호환성 문제가 있어 사용하지 못하게 되었습니다.

그래서 이번에는 한번 만들어 볼까? 고민하고 있었지요.

간편한 시작을 위해서 웹서버쪽을 PHP + CodeIgniter사용하고,
클라이언트는 Firefox Sidebar를 사용해 보고자 했습니다.

Firefox Sidebar를 만드는 방법이 역사가 있고, 바뀌어 가기도 하는데, 그중 최신인,
web extension을 사용해서 틀을 잡아보기로 하였습니다.

https://github.com/mdn/webextensions-examples/

그런데, …

XHR을 통해서 링크를 서버로 보내는 것을 준비하다가, …

심각한 상황에 빠졌느데, … CI에서 log_message 걸다보니, httpd가 hang 걸리고, …

그러다가, gdb, lsof, debuginfo-install httpd-2.4.6-45.el7.centos.x86_64
하는 상황까지 오게된. …

그나 저나, 해야 할 일들은 아래와 같이 시작도 못했는데, …

1. firefox web extension 사용하여 sidebar 활용 등의 클라이언트 프로그램 준비
2. 서버측 bookmark 모델 설계
3. 서버측 codeigniter LDAP 및 인증 모듈 개발
4. 서버측 codeigniter bookmark RESTful 인터페이스 개발
5. 서버측 codeigniter web 인터페이스 개발 ( bootstrap 사용할까? )

참조 URL
https://developer.mozilla.org/en-US/docs/Mozilla/Creating_a_Firefox_sidebar
https://github.com/kyoshino/simple-sidebar
https://developer.mozilla.org/en-US/Add-ons/WebExtensions
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/user_interface/Sidebars
https://github.com/mdn/webextensions-examples/

ps. 헐, 위에 적은 debuginfo-install은 시작이었고, 아래와 같은 엄청난 메시지가 나오는데, 포기할까 싶은 생각이 바로 …
debuginfo-install bzip2-libs-1.0.6-13.el7.x86_64 cyrus-sasl-lib-2.1.26-20.el7_2.x86_64 elfutils-libelf-0.166-2.el7.x86_64 elfutils-libs-0.166-2.el7.x86_64 file-libs-5.11-33.el7.x86_64 freetype-2.4.11-12.el7.x86_64 gmp-6.0.0-12.el7_1.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.14.1-27.el7_3.x86_64 libX11-1.6.3-3.el7.x86_64 libXau-1.0.8-2.1.el7.x86_64 libXpm-3.5.11-3.el7.x86_64 libattr-2.4.46-12.el7.x86_64 libcap-2.22-8.el7.x86_64 libcom_err-1.42.9-9.el7.x86_64 libcurl-7.29.0-35.el7.centos.x86_64 libgcc-4.8.5-11.el7.x86_64 libgcrypt-1.5.3-13.el7_3.1.x86_64 libgpg-error-1.12-3.el7.x86_64 libidn-1.28-4.el7.x86_64 libjpeg-turbo-1.2.90-5.el7.x86_64 libpng-1.5.13-7.el7_2.x86_64 libssh2-1.4.3-10.el7_2.1.x86_64 libstdc++-4.8.5-11.el7.x86_64 libuuid-2.23.2-33.el7.x86_64 libxcb-1.11-4.el7.x86_64 libxml2-2.9.1-6.el7_2.3.x86_64 libxslt-1.1.28-5.el7.x86_64 libzip-0.10.1-8.el7.x86_64 mariadb-libs-5.5.52-1.el7.x86_64 mod_dav_svn-1.7.14-10.el7.x86_64 mod_wsgi-3.4-12.el7_0.x86_64 nspr-4.11.0-1.el7_2.x86_64 nss-3.21.3-2.el7_3.x86_64 nss-softokn-freebl-3.16.2.3-14.4.el7.x86_64 nss-util-3.21.3-1.1.el7_3.x86_64 openldap-2.4.40-13.el7.x86_64 openssl-libs-1.0.1e-60.el7.x86_64 php-5.4.16-42.el7.x86_64 php-common-5.4.16-42.el7.x86_64 php-gd-5.4.16-42.el7.x86_64 php-ldap-5.4.16-42.el7.x86_64 php-mbstring-5.4.16-42.el7.x86_64 php-mysql-5.4.16-42.el7.x86_64 php-pdo-5.4.16-42.el7.x86_64 php-process-5.4.16-42.el7.x86_64 php-xml-5.4.16-42.el7.x86_64 python-libs-2.7.5-48.el7.x86_64 sqlite-3.7.17-8.el7.x86_64 subversion-libs-1.7.14-10.el7.x86_64 t1lib-5.1.2-14.el7.x86_64 xz-libs-5.2.2-1.el7.x86_64
지금 서버가 테스트 개발 서버라면 몰라도, 준 운용 서버인데, 위와 같은 짓을 하기는 싫은데, …

ps. 환장할 일일쎼… Java는 보통 hang상황에서 thread dump라는 편리한 도구를 사용했었고, apache는 server-status 활용하고, tcpdump나 lsof 등으로 대충 찍으면, 뭔짓을 하는지 나왔었는데, … 지금 버그인지, 뭔지는, gdb로 찾아야 하다니 하면서, …

ps. 정확한 원인은 모르겠으나, 우선 보이는 것부터 잡아보려고, …
#9 0x00007f01cba6a344 in php_verror (docref=, params=params@entry=0x7f01cbb81ce5 “”, type=type@entry=2,
format=format@entry=0x7f01cbb7bb08 “It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you”…,
args=args@entry=0x7fff62819750) at /usr/src/debug/php-5.4.16/main/main.c:862

오늘은 가볍게, vuejs 시작해보기. … 그러다가, bootstrap으로 …

어제, vuejs, reactjs, angularjs 관련 글을 보고, …

angular 같은 경우, typescript 압박에 … 시작하다 말았고, … react도 나중에 보기로 하면서, …

그나마 가볍게 시작하기 좋지 않을까 생각에 vuejs를 시작해 본다. … test 서버를 빨리 만들면 좋은데, 돈이 없어서, …

시작 글을 적어 두고, 차근 차근 시작 …

{{ }} 구문으로 데이터를 전달하는 것이 쉽게 이해되긴하는데, …
v-bind 까지도 쉬운데, … v-if v-for 넘어가니 뭔가 새로운 세상이 열리는 듯 하다. …
일부러 오류를 일으켜 보아야지…
구문 오류나 이름 오류도 잘 잡아내긴 하네, … 역시나 스크립트 영역이다 보니, 이런 특징 때문에 싫어할 사람도 있을 듯.

component까지 오니, 다른 느낌이 있다.
jquery 같은 경우, DOM은 그대로 두고, 거기에 붙여서 쓸 수 있게 해 뒀다고 한다면,
vuejs 같은 경우, DOM에 대한 통제를 완전히 가져가 버린 듯.

참 좋은데, 개념도 알겠고, 코드와 뷰를 엮어 준다는 것까지는 알겠는데, …
extjs 같은 실제 화면 디자인을 품고 있는 것은 아닌 듯 하다,
dgkim은 바로 제품으로(?) 쓸 수 있는 디자인 및 CSS가 포함된 것이 필요한데, …

bootstrap을 파 보아야 할까?

그래서, 바로 bootstrap으로 전환하여 이어 나가본다.

bootstrap 시작하고, navigation bar 따라해 보았다. …

그런데, .. 머리속에 아직 만들고 싶은 것의 스케치가 없어서 이어나가지 못한다.

NodeJS, MongoDB 볼까?

javascript가 참 끌리는 언어이다.

nodejs의 한계도 있는데…

MongoDB document db 개발자에게 유리한 것은 많은데, ….

성능이 문제가 안 될까 싶은데, 아래 인용구가 답

The RDBMS optimizes data for storage efficiency (as it was conceived at a time when storage was the most expensive component of the system).

MongoDB’s document model is optimized for how the application accesses data (as developer time and speed to market are now more expensive than storage).

조직도 JavaScript 실험. recursive function. 연습.

커뮤니티에 javascript를 사용하여, 조직도를 구현하는 것에 대한 질문이 올라왔다.
그래서, 나는 프로그래밍 연습을 하기 위해서, 한 번 만들어보기로 결심하고, 답변을 올렸다.

https://okky.kr/article/389606

올리자마자 다시 봐도, 코드 상에 잘못된 부분은 보이지만, 그런 것들은 나중에 시간날지 고칠지 하고, 우선 코드를 내 블로그에 복사해 놓는다.

var depth1 = [];
var depth2 = [];
var depth3 = [];
var depth4 = [];

depth1.push(
    {
        GROUP_ID: 1,
        GROUPNAME: '본사',
	children: []
    },
    {
        GROUP_ID: 2,
        GROUPNAME: '지사',
	children: []
    }
);

depth2.push(
    {
        GROUP_ID: 10,
        GROUP_ID_P: 1,
        GROUPNAME: '기술지원본부',
	children: []
    },
    {
        GROUP_ID: 20,
        GROUP_ID_P: 1,
        GROUPNAME: '연구소',
	children: []
    },
    {
        GROUP_ID: 30,
        GROUP_ID_P: 2,
        GROUPNAME: '영업부',
	children: []
    }
);

console.log(depth1);
console.log("========================================");
console.log(depth2);
console.log("========================================");

/*
var datasource = { children: [] };

for(var i=0; i < depth1.length; i++){
	datasource['children'].push({'name': depth1[i]['GROUPNAME'], 'gid': depth1[i]['GROUP_ID'],'children': []});
	for(var j=0; j < depth2.length; j++){
		if(depth1[i]['GROUP_ID'] == depth2[j]['GROUP_ID_P']){
			datasource['children'][i]['children'].push({'name': depth2[j]['GROUPNAME'], 'gid': depth2[j]['GROUP_ID'], 'children':[]});
			for(var k=0; k < depth3.length; k++){
				if(depth2[j]['GROUP_ID'] == depth3[k]['GROUP_ID_P']){
					for(var l=0; l < datasource['children'][i]['children'].length; l++){
						if(depth2[j]['GROUP_ID'] == datasource['children'][i]['children'][l]['gid']){
							datasource['children'][i]['children'][l]['children'].push({'name': depth3[k]['GROUPNAME'], 'gid': depth3[k]['GROUP_ID'], 'children':[]});
							for(var m=0; m < depth4.length; m++){
								if(depth3[k]['GROUP_ID'] == depth4[m]['GROUP_ID_P']){
									for(var n=0; n < datasource['children'][i]['children'][l]['children'].length; n++){
										if(depth3[k]['GROUP_ID'] == datasource['children'][i]['children'][l]['children'][n]['gid']){
											datasource['children'][i]['children'][l]['children'][n]['children'].push({'name': depth4[m]['GROUPNAME'], 'gid': depth4[m]['GROUP_ID'], 'children':[]});
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

console.log("===== FINAL =====");
console.log(JSON.stringify(datasource));
*/

/**
 * tree에서 gid를 가지는 객체를 반환한다.
 * 못 찾으면 undefined를 반환한다.
 */
function findById(tree, gid) {

	//console.log("========================================");
	//console.log(new Error().stack);
	//console.log("========================================");

	if ( tree['GROUP_ID'] == gid ) {
		return tree;
	} else if ( tree.children.length == 0 ) {
		return undefined;
	} else {
		for ( var i = 0 ; i < tree.children.length ; i ++ ) {
			var found = findById(tree.children[i], gid);
			if ( found !== undefined ) {
				return found;
			}
		}
		return undefined;
	}
}

var ROOT = {
	'GROUP_ID': 0,
	'GROUPNAME': 'ROOT',
	'children': []
}

depth1 = depth1.concat(depth2);
for ( var i = 0 ; i < depth1.length ; i ++ ) {
	if ( depth1[i]['GROUP_ID_P'] === undefined ) {
		ROOT.children.push(depth1[i]);
	} else {
		var parent = findById(ROOT, depth1[i]['GROUP_ID_P']);
		if ( parent !== undefined ) {
			parent.children.push(depth1[i]);
		}
	}
}

console.log("FINAL");

console.log(JSON.stringify(ROOT));

tomcat parallel deployment

톰캣이 이미 8.0까지 나온 시점에 인터넷에서 흥미를 끄는 내용을 하나 접했습니다.

parallel deployment라는 제목에서는

전략을 얘기하는 것인 줄 알았는데, 기능이었습니다.

tomcat 7.0 부터 지원하는 기능으로 무중단 배포를 할 수 있는 기능입니다.

즉, app v1 운용중에 app v2를 배포할 수 있고,
기존 세션 사용자는 v1을 사용하고 신규 접속자는 v2로 접근하게 됩니다.

저는 weblogic에서 production redeployment로 접했던 기능입니다.

상세내용은 위 링크에서 참조하십시오.

‘Objective-C for absolute Beginners’를 봅니다.

2013-002 – 2013/04/30 – Objective-C for absolute Beginners – Gary Bennett 외 2 – 공학 – 전자책 – 링크 – 읽는중

gcc로 몇가지 연습 -c -S -E

gcc로 c언어 컴파일을 몇 가지 실습해 보았습니다.

-c 옵션

gcc 명령에 -c 옵션을 주면, .c파일을 컴파일만하고 링크를 하지 않습니다. 결과물로는 .o 파일이 생성됩니다.

test.c 파일

int test(int a, int b) {
    return a + b;
}

int main(int argc, char* argv[]) {
    test(3,4);
    return 0;
}
[dgkim@dgkim asm]$ ls -al
합계 12
drwxr-xr-x   2 dgkim users 4096 2013-01-03 19:37 .
drwxrwxrwt. 18 root  root  4096 2013-01-03 19:34 ..
-rw-r--r--   1 dgkim users  112 2013-01-03 18:12 test.c
[dgkim@dgkim asm]$ gcc -c test.c
[dgkim@dgkim asm]$ ls -l
합계 8
-rw-r--r-- 1 dgkim users  112 2013-01-03 18:12 test.c
-rw-r--r-- 1 dgkim users 1464 2013-01-03 19:37 test.o
[dgkim@dgkim asm]$

-c 옵션으로 생성된 .o 파일을 gcc를 통해 링크하려면 아래와 같이 할 수 있습니다.
여러 개의 .c 파일을 가지는 프로그램 및 링크 과정 및 순서에 따라, -c 옵션으로 컴파일만하고, 마지막에 .o 파일들을 묶는 일은 자주 있을 것입니다.

[dgkim@dgkim asm]$ gcc -o test test.o
[dgkim@dgkim asm]$ ls -l
합계 16
-rwxr-xr-x 1 dgkim users 6379 2013-01-03 19:39 test
-rw-r--r-- 1 dgkim users  112 2013-01-03 18:12 test.c
-rw-r--r-- 1 dgkim users 1464 2013-01-03 19:37 test.o
[dgkim@dgkim asm]$

-S 옵션

gcc에서 -S 옵션을 주고 실행하면, .c파일에서 .s파일, 즉 어셈블러 소스가 생성됩니다.

[dgkim@dgkim asm]$ ls -al
합계 28
drwxr-xr-x   2 dgkim users 4096 2013-01-03 19:41 .
drwxrwxrwt. 18 root  root  4096 2013-01-03 19:39 ..
-rwxr-xr-x   1 dgkim users 6379 2013-01-03 19:39 test
-rw-r--r--   1 dgkim users  112 2013-01-03 18:12 test.c
-rw-r--r--   1 dgkim users 1464 2013-01-03 19:37 test.o
-rw-r--r--   1 dgkim users  807 2013-01-03 19:41 test.s
[dgkim@dgkim asm]$

위의 간단하고 짧던 .c 파일은 아래와 같은 복잡한 .s 파일을 만들었습니다.

        .file   "test.c"
        .text
.globl test
        .type   test, @function
test:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        movl    -8(%rbp), %eax
        movl    -4(%rbp), %edx
        leal    (%rdx,%rax), %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   test, .-test
.globl main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    %edi, -4(%rbp)
        movq    %rsi, -16(%rbp)
        movl    $4, %esi
        movl    $3, %edi
        call    test
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)"
        .section        .note.GNU-stack,"",@progbits

-E 옵션

gcc에서 -E 옵션을 주면, preprocessor 처리가 된 c파일의 내용을 볼 수 있습니다.

preprocessor 처리를 위해서 test.c 파일에서 #define 사용하여 작은 수정을 한 결과입니다.

[dgkim@dgkim asm]$ cat test.c
#define a alpha
#define b bravo

int test(int a, int b) {
    return a + b;
}

int main(int argc, char* argv[]) {
    test(3,4);
    return 0;
}
[dgkim@dgkim asm]$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"



int test(int alpha, int bravo) {
    return alpha + bravo;
}

int main(int argc, char* argv[]) {
    test(3,4);
    return 0;
}
[dgkim@dgkim asm]$

ps. 다음에는 -m32 옵션을 통해서 x86_64 머신에서 x86 i686용 빌드를 테스트한 글을 올려볼까요? glibc-devel.i686
ps2. 그리고, gdb를 통해서 위 파일을 디버깅하였는데, 그 글도 올려볼까요?