私の会社(Acme Technologyと呼びましょう)には、Acme Labsの研究グループからの約1,000のソースファイルのライブラリがあり、開発グループで2年間インキュベートされ、最近では、以下の少数の顧客に提供されています。非開示。 Acmeは、おそらくコードの75%をオープンソースコミュニティにリリースする準備をしています。残りの25%は後でリリースされますが、現時点では、顧客が使用する準備ができていないか、競合他社の手に渡らないようにする必要がある将来のイノベーションに関連するコードが含まれています。
現在、コードは#ifdefsでフォーマットされており、オープンソースに移行すると、大学の研究者やはるかに幅広い商用顧客が利用できるプリプロダクションプラットフォームで同じコードベースを使用できるようになります。実験とプロトタイピング、および将来のプラットフォームとの上位互換性テストに利用できます。単一のコードベースを維持することは、2つのコピーを並行して維持するのに苦労する私のグループの経済性(および健全性)にとって不可欠であると考えられています。
現在のベースのファイルは次のようになります。
> // Copyright 2012 (C) Acme Technology, All Rights Reserved.
> // Very large, often varied and restrictive copyright license in English and French,
> // sometimes also embedded in make files and Shell scripts with varied
> // comment styles.
>
>
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> #ifdef UNDER_RESEARCH
> holographicVisualization(on);
> #endif
> }
そして、それらを次のようなものに変換したいと思います。
> // GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
> // Acme appreciates your interest in its technology, please contact [email protected]
> // for technical support, and www.acme.com/emergingTech for updates and RSS feed.
>
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> }
著作権を置き換え、#ifdefsだけでなく#if defined(UNDER_RESEARCH)などのバリエーションを取り除くことができるツール、解析ライブラリ、または一般的なスクリプトはありますか?
コードは現在Gitにあり、Gitを使用する場所でホストされる可能性があります。リポジトリを安全にリンクして、改善点をオープンソースバージョンと効率的に再統合できるようにする方法はありますか?他の落とし穴についてのアドバイスは大歓迎です。
スクリプトを記述してプリプロセッサを解析し、それらを定義済み定数のリスト(UNDER_RESEARCH
、FUTURE_DEVELOPMENT
など)と比較することはそれほど難しくないと思われます。定義されている内容を考慮してfalseと評価され、次の#endif
までのすべてを削除します。
Pythonでは、私は次のようなことをします、
import os
src_dir = 'src/'
switches = {'UNDER_RESEARCH': True, 'OPEN_SOURCE': False}
new_header = """// GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
// Acme appreciates your interest in its technology, please contact [email protected]
// for technical support, and www.acme.com/emergingTech for updates and RSS feed.
"""
filenames = os.listdir(src_dir)
for fn in filenames:
contents = open(src_dir+fn, 'r').read().split('\n')
outfile = open(src_dir+fn+'-open-source', 'w')
in_header = True
skipping = False
for line in contents:
# remove original header
if in_header and (line.strip() == "" or line.strip().startswith('//')):
continue
Elif in_header:
in_header = False
outfile.write(new_header)
# skip between ifdef directives
if skipping:
if line.strip() == "#endif":
skipping = False
continue
# check
if line.strip().startswith("#ifdef"):
# parse #ifdef (maybe should be more elegant)
# this assumes a form of "#ifdef SWITCH" and nothing else
if line.strip().split()[1] in switches.keys():
skipping = True
continue
# checking for other forms of directives is left as an exercise
# got this far, nothing special - echo the line
outfile.write(line)
outfile.write('\n')
もっとエレガントな方法があると思いますが、これは迅速で汚く、仕事を成し遂げているようです。
コードをプリプロセッサに渡してマクロのみを展開し、#ifdef
sの重要な部分のみを出力することを考えていました。
このようなものが機能するはずです:
gcc -E yourfile.c
だが:
-CC
を使用してそれらを(一種の)保存することができますが、それでも古い著作権表示を取り除く必要があります#include
sも展開されるため、インクルードされたヘッダーファイルのすべてのコンテンツを含む大きなファイルになります。展開されるマクロを制限する方法があるかもしれません。ただし、ここでの私の提案は、ファイルに対して(潜在的に危険な)処理を行うのではなく、物事を分割することです(ちなみに、後でそれらをどのように維持する予定ですか?たとえば、オープンソースバージョンからクローズドソースにコードを再導入しますか?)。
つまり、オープンソースにしたいコードをできるだけ外部ライブラリに入れてから、他の「カスタム」クローズドソースライブラリと統合して、他のライブラリと同じように使用してみてください。
物事を再構築する方法を理解するのに最初は少し時間がかかるかもしれませんが、それは間違いなくこれを達成するための正しい方法です。
解決策はありますが、少し作業が必要です
pypreprocessorは、GPP(汎用プリプロセッサ)としても使用できるpython)用の純粋なcスタイルのプリプロセッサを提供するライブラリです。プロセッサ)他のタイプのソースコード用。
基本的な例は次のとおりです:
from pypreprocessor import pypreprocessor
pypreprocessor.input = 'input_file.c'
pypreprocessor.output = 'output_file.c'
pypreprocessor.removeMeta = True
pypreprocessor.parse()
プリプロセッサは非常にシンプルです。ソースを通過し、定義に基づいて条件付きでソースをコメントアウトします。
定義は、ソースの#defineステートメントを介して、またはpypreprocessor.definesリストで設定することによって設定できます。
入出力パラメータを設定すると、開く/閉じるファイルを明示的に定義できるため、必要に応じて、単一のプリプロセッサをセットアップして多数のファイルをバッチ処理できます。
RemoveMetaパラメータをTrueに設定すると、プリプロセッサはすべてのプリプロセッサステートメントを自動的に抽出し、後処理されたコードのみを残します。
注:pythonバイトコードへのコンパイル中にコメント付きコードが自動的に削除されるため、通常、これを明示的に設定する必要はありません。
Edgeケースが1つだけ表示されます。 Cソースを前処理しようとしているので、プロセッサ定義を明示的に(つまり、pypreprocessor.definesを介して)設定し、ソース内の#defineステートメントを無視するように指示することができます。これにより、プロジェクトのソースコードで使用する可能性のある定数が誤って削除されるのを防ぐことができます。現在、この機能を設定するためのパラメーターはありませんが、追加するのは簡単です。
これは簡単な例です:
from pypreprocessor import pypreprocessor
# run the script in 'production' mode
if 'commercial' in sys.argv:
pypreprocessor.defines.append('commercial')
if 'open' in sys.argv:
pypreprocessor.defines.append('open')
pypreprocessor.removeMeta = True
pypreprocessor.parse()
その後、ソース:
#ifdef commercial
// Copyright 2012 (C) Acme Technology, All Rights Reserved.
// Very large, often varied and restrictive copyright license in English and French,
// sometimes also embedded in make files and Shell scripts with varied
// comment styles.
#ifdef open
// GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
// Acme appreciates your interest in its technology, please contact [email protected]
// for technical support, and www.acme.com/emergingTech for updates and RSS feed.
#endif
注:明らかに、入出力ファイルを設定する方法を整理する必要がありますが、それはそれほど難しいことではありません。
開示:私はpypreprocessorの原作者です。
脇:私はもともと恐ろしいpython 2k/3xメンテナンス問題の解決策としてそれを書きました。私のアプローチは、同じソースファイルで2と3の開発を行い、プリプロセッサディレクティブを使用して、違いを含める/除外するだけです。残念ながら、pythonで真の純粋な(つまり、cを必要としない)プリプロセッサを書くことが不可能であるという難しい方法を発見しました。プリプロセッサが実行される前に互換性のないコードでエラーが発生します。どちらの方法でも、あなたを含む幅広い状況で役立ちます。
おそらくそれは良い考えでしょう
1。:のようなコメントタグを追加します
> // *COPYRIGHT-BEGIN-TAG*
> // Copyright 2012 (C) Acme Technology, All Rights Reserved.
> // Very large, often varied and restrictive copyright license in English and French,
> // sometimes also embedded in make files and Shell scripts with varied
> // comment styles.
> // *COPYRIGHT-ENG-TAG*
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> #ifdef UNDER_RESEARCH
> holographicVisualization(on);
> #endif
> }
2。オープンソースビルダーがすべてのファイルを調べ、COPYRIGHT-BEGIN-TAGおよびCOPYRIGHT-ENG-TAGタグ
私はあなたのコードベースを変換するツールをあなたに示すつもりはありません、たくさんの答えがすでにそれをしました。むしろ、このためのブランチの処理方法についてのあなたのコメントに答えています。
2つのブランチが必要です。
プリプロセッサは存在すべきではありません。 2つの異なるバージョンがあります。そして、全体的にクリーンなコードベース。
2つのコピーを並行して維持することを恐れていますか?心配しないで、マージできます!
コミュニティブランチに変更を加える場合は、それらをプロフェッショナルブランチにマージするだけです。 Gitはこれを処理します本当にうまく。
このようにして、コードベースの2つの維持されたコピーを保持します。そして、オープンソース用にリリースするのは簡単です。