OpenJDKをビルドしてみた
環境はMac。
基本ソースをMercurialでクローンしてREADME読めばできる。
READMEにもあるけど、詳しいビルド方法はここを参照すればいい。
http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html
以下、作業手順。
デバッグ版が欲しい場合は Configure時に--enable-debug するとよい。
% hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8_src requesting all changes adding changesets adding manifests adding file changes added 942 changesets with 1309 changes to 136 files updating to branch default 82 files updated, 0 files merged, 0 files removed, 0 files unresolved % cd jdk8_src % ./get_source.sh # Repositories: corba jaxp jaxws langtools jdk hotspot nashorn corba: hg clone http://hg.openjdk.java.net/jdk8/jdk8/corba corba jaxp: hg clone http://hg.openjdk.java.net/jdk8/jdk8/jaxp jaxp jaxp: requesting all changes corba: requesting all changes corba: adding changesets jaxp: adding changesets Waiting 5 secs before spawning next background command. jaxp: adding manifests corba: adding manifests jaxws: hg clone http://hg.openjdk.java.net/jdk8/jdk8/jaxws jaxws langtools: hg clone http://hg.openjdk.java.net/jdk8/jdk8/langtools langtools jaxws: requesting all changes langtools: requesting all changes jaxws: adding changesets langtools: adding changesets 〜 中略 〜 .: cd . && hg pull -u ./corba: cd ./corba && hg pull -u ./hotspot: cd ./hotspot && hg pull -u ./jaxp: cd ./jaxp && hg pull -u ./jaxws: cd ./jaxws && hg pull -u ./jdk: cd ./jdk && hg pull -u ./langtools: cd ./langtools && hg pull -u ./nashorn: cd ./nashorn && hg pull -u ./hotspot: pulling from http://hg.openjdk.java.net/jdk8/jdk8/hotspot ./nashorn: pulling from http://hg.openjdk.java.net/jdk8/jdk8/nashorn ./jaxws: pulling from http://hg.openjdk.java.net/jdk8/jdk8/jaxws ./jaxp: pulling from http://hg.openjdk.java.net/jdk8/jdk8/jaxp ./langtools: pulling from http://hg.openjdk.java.net/jdk8/jdk8/langtools .: pulling from http://hg.openjdk.java.net/jdk8/jdk8 ./corba: pulling from http://hg.openjdk.java.net/jdk8/jdk8/corba ./jdk: pulling from http://hg.openjdk.java.net/jdk8/jdk8/jdk ./hotspot: searching for changes ./hotspot: no changes found ./jaxws: searching for changes ./jaxws: no changes found ./jaxp: searching for changes ./jaxp: no changes found ./nashorn: searching for changes ./nashorn: no changes found ./langtools: searching for changes ./langtools: no changes found ./corba: searching for changes ./corba: no changes found .: searching for changes .: no changes found ./jdk: searching for changes ./jdk: no changes found % bash ./configure --enable-debug --with-target-bits=64 Running generated-configure.sh configure: Configuration created at Sat Oct 4 01:07:52 JST 2014. configure: configure script generated at timestamp 1389186094. checking for basename... /usr/bin/basename checking for bash... /bin/bash checking for cat... /bin/cat checking for chmod... /bin/chmod checking for cmp... /usr/bin/cmp 〜 中略 〜 checking if build directory is on local disk... yes configure: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/config.status config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/spec.gmk config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/hotspot-spec.gmk config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/bootcycle-spec.gmk config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/compare.sh config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/spec.sh config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/Makefile config.status: creating /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug/config.h ==================================================== A new configuration has been successfully created in /Users/plugram/Desktop/jvm/jdk8_src/build/macosx-x86_64-normal-server-fastdebug using configure arguments '--enable-debug --with-target-bits=64'. Configuration summary: * Debug level: fastdebug * JDK variant: normal * JVM variants: server * OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64 Tools summary: * Boot JDK: java version "1.8.0_20" Java(TM) SE Runtime Environment (build 1.8.0_20-b26) Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) (at /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home) * C Compiler: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build) version 2335.15.00) (at /usr/llvm-gcc-4.2/bin/llvm-gcc-4.2) * C++ Compiler: i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build) version 2335.15.00) (at /usr/llvm-gcc-4.2/bin/llvm-g++-4.2) Build performance summary: * Cores to use: 2 * Memory limit: 4096 MB * ccache status: not installed (consider installing) Build performance tip: ccache gives a tremendous speedup for C++ recompilations. You do not have ccache installed. Try installing it. % make all Building OpenJDK for target 'all' in configuration 'macosx-x86_64-normal-server-fastdebug' ## Starting langtools Compiling 2 files for BUILD_TOOLS Compiling 31 properties into resource bundles Compiling 777 files for BUILD_BOOTSTRAP_LANGTOOLS Creating langtools/dist/bootstrap/lib/javac.jar Updating langtools/dist/lib/src.zip Compiling 780 files for BUILD_FULL_JAVAC Creating langtools/dist/lib/classes.jar ## Finished langtools (build time 00:01:02) ## Starting hotspot make[2]: warning: -jN forced in submake: disabling jobserver mode. INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 Creating Makefile ... Creating directory list ../shared_dirs.lst Creating flags.make ... Creating flags_vm.make ... Creating vm.make ... Creating adlc.make ... Creating jvmti.make ... Creating trace.make ... Creating sa.make ... Creating dtrace.make ... INFO: ENABLE_FULL_DEBUG_SYMBOLS=1 Creating Makefile ... Creating flags.make ... Creating flags_vm.make ... Creating vm.make ... Creating adlc.make ... Creating jvmti.make ... Creating trace.make ... 〜 中略 〜 ## Finished docs (build time 00:03:48) ----- Build times ------- Start 2014-10-04 01:10:54 End 2014-10-04 01:39:25 00:00:50 corba 00:01:00 demos 00:03:48 docs 00:12:07 hotspot 00:01:27 images 00:00:30 jaxp 00:00:44 jaxws 00:06:44 jdk 00:01:02 langtools 00:00:18 nashorn 00:28:31 TOTAL ------------------------- Finished building OpenJDK for target 'all' % make install Building OpenJDK for target 'install' in configuration 'macosx-x86_64-normal-server-fastdebug' ## Starting langtools ## Finished langtools (build time 00:00:01) ## Starting hotspot ## Finished hotspot (build time 00:00:00) ## Starting corba ## Finished corba (build time 00:00:00) ## Starting jaxp ## Finished jaxp (build time 00:00:01) ## Starting jaxws ## Finished jaxws (build time 00:00:00) ## Starting jdk ## Finished jdk (build time 00:00:03) ## Starting demos ## Finished demos (build time 00:00:00) ## Starting nashorn ## Finished nashorn (build time 00:00:00) ## Starting images Copying images/j2re-bundle/jre1.8.0.jre/Contents/Home/release Copying images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/.DS_Store Copying images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/jre Copying images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/jre/.DS_Store Copying images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home/release ## Finished images (build time 00:00:04) ## Starting install Installing jdk image into /usr/local/jvm/openjdk-1.8.0-internal-fastdebug and creating 40 links from /usr/local/bin into the jdk. ## Finished install (build time 00:00:04) ----- Build times ------- Start 2014-10-04 01:54:51 End 2014-10-04 01:55:04 00:00:00 corba 00:00:00 demos 00:00:00 hotspot 00:00:04 images 00:00:04 install 00:00:01 jaxp 00:00:00 jaxws 00:00:03 jdk 00:00:01 langtools 00:00:00 nashorn 00:00:13 TOTAL -------------------------
インストールしたら /usr/local/bin に入った。
さっそく実験。
以下のようなソースを書いて実行。
class Hello { public static void main(String[] args) { new Hello().hello(); } public int hello() { int result = 1 + 2; return result; } }
% /usr/local/bin/javac Hello.java % /usr/local/bin/java -client -Xcomp -XX:+PrintIRWithLIR -XX:CompileOnly="Hello.hello" Hello __bci__use__tid____instr____________________________________ . 0 0 4 B1 [0, 0] -> B2 sux: B2 label [label:0xec065838] . 0 0 7 std entry B2 std_entry move [rsi|L] [R177|L] move [metadata:0xa1684420|M] [R178|M] move [Base:[R178|M] Disp: 108|I] [R179|I] add [R179|I] [int:8|I] [R179|I] move [R179|I] [Base:[R178|M] Disp: 108|I] move [metadata:0xa16842f0|M] [R180|M] logic_and [R179|I] [int:0|I] [R179|I] cmp [R179|I] [int:0|I] branch [EQ] [CounterOverflowStub: 0xec067718] label [label:0xec067740] branch [AL] [B2] __bci__use__tid____instr____________________________________ . 0 0 5 B2 (S) [0, 0] -> B0 dom B1 sux: B0 pred: B1 label [label:0xec065b48] . 0 0 6 goto B0 branch [AL] [B0] __bci__use__tid____instr____________________________________ . 0 0 0 B0 (SV) [0, 3] dom B2 pred: B2 label [label:0xec064e38] . 3 0 i3 ireturn i2 move [int:3|I] [rax|I] return [rax|I] __bci__use__tid____instr____________________________________ . 0 0 4 B1 [0, 0] -> B0 sux: B0 label [label:0xec8a8a38] . 0 0 5 std entry B0 std_entry move [rsi|L] [R177|L] branch [AL] [B0] __bci__use__tid____instr____________________________________ . 0 0 0 B0 (SV) [0, 3] dom B1 pred: B1 label [label:0xec8a8038] . 3 0 i3 ireturn i2 move [int:3|I] [rax|I] return [rax|I]
とりあえず今日はここまで。
友達から「これ無料で作ってよ」って言われたときに注意したいこと
最近あまりにもひどいので、今後同じような経験をしないよう備忘録として書いておきます。
プログラマとかデザイナーの人は一度は必ず経験があると思うのですが、
友人から「こんなアイデアがあるんだけど」「うちの会社のサイトがダサくてね」という切り出しで、
「"ちょっと"やってくれない?」って頼まれることがあります。
この"ちょっと"が曲者で、
・"ちょっと" だからお金を払わなくていいよね?
・"ちょっと" だからまた頼むね
って感じで友人という立場上、依頼者は頼みやすいので
最初は自分も特に嫌ではなく、やってしまうことがあります。
ですが、この次の "ちょっと" を "何となく" やってしまったため、
次もまた次も頼まれることになります。
こうなってくると、最初は無料で感謝してた友人の依頼者も
なぜか「当たり前にやってくれる」ものとして依頼してきて、
こちらがやりたいと思わないことも要求してきます。
こういうパターンを何回か経験しているので、いい加減自分も学習しろと思うのですが、
こうなってくるともう相手は自分のやりたいと思っていることも聞いてくれず、
また自分的にも単なる作業にしかならない仕事を休日を使ってやることになります。
土日作業し休みを費やしてやっても感謝されず(実際はありがとうの一言ぐらいは言ってもらえる)
一文も儲からないし技術的にもやりたいこととは違うので、やりたくないと思い始めるのですが、
問題はここで「やめる」といっても、依頼者は自分にはできないので「困る」としか言えません。
なので、とりあえず引き継ぐ方向性を探るのですが、そもそも無料でこんなことやりたい人なんかいないので、もちろん誰も見つかりません。
こうなってくるとその友人に会うのすら苦痛になり、友人関係も崩壊します。
そんな経緯が度々あったので、今後誰に頼まれても「無料で」なにかのアプリとかサイトを作るつもりは一切ありません。
勉強会で発表するのは続けたいですが、あくまで「自分がやりたいこと」と「終了期限や終了条件」が明確であることが前提です。
たぶん同じような状況になったことのある人も結構いると思うし、
現在こんな感じの状況の人も結構いると思う。
なのでそういう状況でいま困っている人は最初に「無料」でやる仕事の「終了条件」を
必ず依頼者と合意しておくことをお勧めします。
あと、アプリやサイトを無料で依頼してる人は「タダより高いものはない」ということ、
「アプリを作る」「サイトを運営する」には一定以上の覚悟と投資がないとできないと思っておいたほうがよいと思います。
PhpStormでisset()を使う時の注意点
ちょっとした凡ミスを防ぐためのメモ書きです。
PhpStormは(多分)他のどのPHPエディタ・IDEより賢いので、未定義な変数があるとちゃんとエラーをハイライトして「ここは使ってないよ」って教えてくれます。
ただ、PHPには元々 isset()っていう未定義かどうか判断できるメソッドがあり、
if条件文にこれを使ってしまうとPhpStormのエラーハイライトが効かない場合があります。
例えばこんな場合、
13行目のように直接 isset() を使わずラップしたメソッドを使用すればエラーはハイライト表示されるのですが、
9行目のように癖で直接 isset() を使ってしまうと当たり前ですがエラーはハイライトしません。
※ここを && ではなく || にするとエラーはハイライトされます。
結論
PhpStorm使う場合は、無意識のうちにエラーチェックをIDEに依存してしまっているので、
できるだけissetなどの未定義チェックはラップしたメソッドで行なうようにしましょう。
CakePHP2でFixtureのデータをCSVから任意のタイミングで変更する
CakePHPのFixtureは個人的に使い辛いと常々感じていて、理由としては
- 1Fixtureクラスに対して1データしか用意できない
- 状況によりデータを変えたい場合1Modelに対して複数のFixtureクラスを用意する必要がある
といったことなどから基本CakePHPではできるだけFixtureを使わずモックで済ませてきました。
ですが列数が多いDBのデータをモックで返すことや、DBも参照してテストしたい場面があったので、CSVからFixtureのデータを読み込むのをさくっと作ってみました。
この方法以外にも、PHPUnit_Extensions_Database_DataSet_CsvDataSet使うとか Fabricate 使うとか状況によって色々あるかと覆いますが参考までにコード載せときます。
app/Test/AppTestCase.php
<?php App::uses('FileUtil', 'Utility'); App::uses('CakeTestFixture', 'TestSuite/Fixture'); class AppTestCase extends CakeTestCase { /** * CSVファイルを読込んでファイル内容を返します。<br> * CSVファイルは実行するテストクラスと同じディレクトリに配置します。<br> * ※1.CSVファイルのファイルサイズは1MBまで<br> * ※2.CSVファイルの文字コーディングはShift_JIS<br> * ※3.ヘッダー行には列名が必要<br> * * @param string ファイル名 * @return array 配列の配列を返します */ protected function readCsv($filename) { $class = new ReflectionClass($this); $testPath = pathinfo($class->getFileName()); $csv = $testPath['dirname'] . DS . $filename; if (!file_exists($csv)) { throw new CakeException("Could not find CSV file. [$csv]"); } $size = filesize($csv); if ($size > 1048576) { // 最大1MBまで throw new CakeException("CSV File is over maximum size. [$csv]-[$size]"); } $data = array(); $fp = fopen($csv, "r"); // ヘッダー行取得 $header = fgetcsv($fp); while ($row = fgetcsv($fp)) { mb_convert_variables('UTF-8', 'SJIS-win', $row); $array = array(); foreach ($header as $index => $column) { if (array_key_exists($index, $row)) { $array[$column] = $row[$index] != 'NULL' ? $row[$index] : null; } else { $array[$column] = null; } } $data[] = $array; } return $data; } protected function loadCsvFixture($fixtureName, $filename) { $fixture = substr($fixtureName, strlen('app.')); $fixturePath = TESTS . 'Fixture'; $className = Inflector::camelize($fixture); if (is_readable($fixturePath . DS . $className . 'Fixture.php')) { $fixtureFile = $fixturePath . DS . $className . 'Fixture.php'; require_once $fixtureFile; $fixtureClass = $className . 'Fixture'; } else { throw new CakeException('Could not read fixture class. ' . $fixtureName); } $fixture = new $fixtureClass(); $data = $this->readCsv($filename); $fixture->records = $data; /** @var $fixtureManager AppFixtureManager */ require_once TESTS . 'AppFixtureManager.php'; $fixtureManager = new AppFixtureManager(); $fixtureManager->loadSingle($fixture); } /** * プライベートメソッドを実行します。 * * @param object $obj インスタンス * @param string $methodName メソッド名 * @return mixed 返り値 * @throws CakeException */ protected function invoke($obj, $methodName) { if (!isset($obj) || !is_object($obj)) { throw new CakeException('The parameter obj is not an object.'); } $clazz = new ReflectionClass($obj); $method = $clazz->getMethod($methodName); $method->setAccessible(true); $countArgs = func_num_args() - 2; if ($countArgs > 0) { $array = array(); $args = func_get_args(); for ($i = 0; $i < $countArgs; $i++) { $index = $i + 2; $array[] = $args[$index]; } $result = $method->invokeArgs($obj, $array); } else { $result = $method->invoke($obj); } return $result; } }
app/Test/AppFixtureManager.php
<?php App::uses('CakeFixtureManager', 'TestSuite/Fixture'); App::uses('CakeTestFixture', 'TestSuite/Fixture'); class AppFixtureManager extends CakeFixtureManager { /** * @see CakeFixtureManager::loadSingle */ public function loadSingle(CakeTestFixture $fixture, $db = null, $dropTables = true) { if(isset($fixture)) { if (!$db) { $db = ConnectionManager::getDataSource($fixture->useDbConfig); } $this->_setupTable($fixture, $db, $dropTables); $fixture->truncate($db); $fixture->insert($db); } else { throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class is not found')); } } }
使い方
- AppTestCase.phpを継承したクラスを作成
class XxxTest extends AppTestCase {}
- テストメソッド内で呼び出す
$this->loadCsvFixture('app.Xxx', Xxx.csv');
この場合、XxxTest.phpと同じディレクトリにXxx.csvを配置します。
Xxx.csvのファイル内容の1行目には列名、2行目以降にデータを入力しておきます。
loadCsvFixture実行時にCSVからデータを読込み、DBの値を更新します。
SourceTreeのマージツールにPhpStormを使う
去年ぐらいから仕事のリポジトリもGitに移行しています。
Subversionと比べるとGitが小回り効くのがすごく気に入ってるのですが、
たまにマージ時にコンフリクトが起こったときにPhpStormファイルが読みにくくなってちょっと不便でした。
他のグラフィカルにマージできるmergetool使えばいいっちゃいいのですが、
せっかくだからPhpStormでDiffとかマージもしたい。
色々調べたのですが、diffはできてもmergeできたという人がいない。。
Gistでやってそうな人を見つけたので試しにやってみたらできました。
https://gist.github.com/lvl-svasseur/7837523
設定は以下のようにします。
※Macです
1. SourceTree -> 環境設定
2. Diff を選択
3. 外部Diff / Merge にそれぞれ以下の値を入力
差分表示ツール
その他
Diffコマンド
/Applications/PhpStorm.app/Contents/MacOS/phpstorm
引数
diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE")
マージツール
その他
Mergeコマンド
/Applications/PhpStorm.app/Contents/MacOS/phpstorm
引数
merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED")
いじょ。
2014年の抱負
明けてましたのでおめでとうございます。
今年は色々と慌ただしくなる感じがするので、抱負でも書いて初心を忘れないようにしておきたいと思います。
あんま色々やろうとしても無理なのは分かっているので心がけ程度ですが。
・仕事を丁寧にする
速度よりも時間がなくても丁寧な仕事をするように心がけたいです。
できるだけ使いやすいように。「仕様通り作った」とかいう言い訳は自他ともになしの方向で。
・万全を期して準備する
準備はしっかりしておく。準備しておかないと勝てるものも勝てないって去年やっと悟った。
・遊ぶ
やりたいと思ったことはやる。楽しむことが大事。
少ない感じですが以上かな。
今まで結構このへんのことが疎かになってたので、今年は気を引き締めていきたい。