原文在这里:
http://hi.baidu.com/magic475/blog/item/e8b82139020ae622b8998f96.html
忙活了一周,基本完成了Crypto++库中关于RSA加解密的API封装!这一周里,查了很多Crypto++的相关资料,感觉这方面的内容乏善可陈, 或者太简单,或者太笼统!本文希望能给使用Crypto++的朋友带来一些帮助,主要还是源代码了,实在没有时间码文字!在测试过程中,感觉 Crypto++还是非常高效的,期待更多的人使用Crypto++。此外,Crypto++的源代码极富研究价值,是深入学习C++的经典材料!爱好 C++的你,千万别错过了~
本文提供的C++源代码已在Redhat Enterprise Server 5.0和Windows XP平台编译链接成功,使用的编译器分别是g++ 3.4.6、Visual C++ 6.0 (SP 6)。由于两个平台的代码差别不大,仅提供Linux平台的代码!如果你需要Windows平台的代码,可以向我索取,留下你的邮件地址即可!如果你在使 用过程中,遇到任何问题,也欢迎你给我留言!
源程序主要包括五个文件:MyRSA.h、 MyRSA.cpp、Main.h、Main.cpp、makefile;两个目录:lib目录包含libcryptopp.a,include目录包含 Crypto++5.5.2中的所有.h头文件。对了,上述五个文件与lib,include目录在同一层目录!需要说明的是,makefile是借用了 一个兄弟的,忘记名字了,不好意思:-)
哈,还是贴代码吧!
/************************** MyRSA.h ********************************/
#ifndef __MYRSA_H__
#define __MYRSA_H__
#include <string>
#include "files.h"
#include "filters.h"
#include "hex.h"
#include "randpool.h"
#include "rsa.h"
using namespace std;
using namespace CryptoPP;
class CMyRSA
{
public:
CMyRSA(void);
virtual ~CMyRSA(void);
//You must set the KeyLength 512, 1024, 2048 ...
void GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub);
void GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub);
//use public key to encrypt
void EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext);
void EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext);
//use private key to decrypt
void DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext);
void DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext);
private:
static RandomPool & RNG(void);
private:
static RandomPool m_sRandPool;
};
#endif /* End of __MYRSA_H__ */
/************************** MyRSA.cpp ********************************/
#include "MyRSA.h"
CMyRSA::CMyRSA()
{
}
CMyRSA::~CMyRSA(void)
{
}
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
//generate private key
Priv = RSAES_OAEP_SHA_Decryptor(RandPool, KeyLength);
//generate public key using private key
Pub = RSAES_OAEP_SHA_Encryptor(Priv);
}
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
//generate private key
RSAES_OAEP_SHA_Decryptor Priv(RandPool, KeyLength);
HexEncoder PrivateEncoder(new StringSink(strPriv));
Priv.DEREncode(PrivateEncoder);
PrivateEncoder.MessageEnd();
//generate public key using private key
RSAES_OAEP_SHA_Encryptor Pub(Priv);
HexEncoder PublicEncoder(new StringSink(strPub));
Pub.DEREncode(PublicEncoder);
PublicEncoder.MessageEnd();
}
void CMyRSA::EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
int MaxMsgLength = Pub.FixedMaxPlaintextLength();
for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)
{
string PartPlaintext = Plaintext.substr(j, MaxMsgLength);
string PartCiphertext;
StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));
Ciphertext += PartCiphertext;
}
}
void CMyRSA::EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext)
{
StringSource PublicKey(strPub, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor Pub(PublicKey);
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
int MaxMsgLength = Pub.FixedMaxPlaintextLength();
for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)
{
string PartPlaintext = Plaintext.substr(j, MaxMsgLength);
string PartCiphertext;
StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));
Ciphertext += PartCiphertext;
}
}
void CMyRSA::DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext)
{
//indicate the ciphertext in hexcode
int CiphertextLength = Priv.FixedCiphertextLength() * 2;
for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)
{
string PartCiphertext = Ciphertext.substr(j, CiphertextLength);
string PartPlaintext;
StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));
Plaintext += PartPlaintext;
}
}
void CMyRSA::DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext)
{
StringSource PrivKey(strPriv, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor Priv(PrivKey);
//indicate the ciphertext in hexcode
int CiphertextLength = Priv.FixedCiphertextLength() * 2;
for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)
{
string PartCiphertext = Ciphertext.substr(j, CiphertextLength);
string PartPlaintext;
StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));
Plaintext += PartPlaintext;
}
}
RandomPool & CMyRSA::RNG(void)
{
return m_sRandPool;
}
RandomPool CMyRSA::m_sRandPool;
/************************** Main.h ********************************/
#ifndef __MAIN_H__
#define __MAIN_H__
#endif /* End of __MAIN_H__ */
/************************** Main.cpp ********************************/
#include <unistd.h>
#include <iostream>
#include "Main.h"
#include "MyRSA.h"
/***** STATIC VARIABLES *****/
static RSAES_OAEP_SHA_Encryptor g_Pub;
static RSAES_OAEP_SHA_Decryptor g_Priv;
static string g_strPub;
static string g_strPriv;
int main(int argc, char *argv[])
{
try
{
char Seed[1024], Message[1024], MessageSeed[1024];
unsigned int KeyLength;
CMyRSA MyRSA;
cout << "Key length in bits: ";
cin >> KeyLength;
cout << "\nRandom Seed: ";
ws(cin);
cin.getline(Seed, 1024);
cout << "\nMessage: ";
ws(cin);
cin.getline(Message, 1024);
cout << "\nRandom Message Seed: ";
ws(cin);
cin.getline(MessageSeed, 1024);
MyRSA.GenerateKey(KeyLength, Seed, g_Priv, g_Pub);
//MyRSA.GenerateKey(KeyLength, Seed, g_strPriv, g_strPub);
//If generate key in RSAES_OAEP_SHA_Encryptor and RSAES_OAEP_SHA_Decryptor, please note four lines below
/*
cout << "g_strPub = " << g_strPub << endl;
cout << endl;
cout << "g_strPriv = " << g_strPriv << endl;
cout << endl;
*/
string Plaintext(Message);
string Ciphertext;
MyRSA.EncryptString(g_Pub, MessageSeed, Plaintext, Ciphertext);
//MyRSA.EncryptString(g_strPub, MessageSeed, Plaintext, Ciphertext);
cout << "\nCiphertext: " << Ciphertext << endl;
cout << endl;
string Decrypted;
MyRSA.DecryptString(g_Priv, Ciphertext, Decrypted);
//MyRSA.DecryptString(g_strPriv, Ciphertext, Decrypted);
cout << "\nDecrypted: " << Decrypted << endl;
return 0;
}
catch(CryptoPP::Exception const &e)
{
cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
return -1;
}
catch(std::exception const &e)
{
cout << "\nstd::exception caught: " << e.what() << endl;
return -2;
}
return -3;
}
/************************** Makefile ********************************/
# The executable file name.
PROGRAM := myrsa
# The directories in which source files reside.
SRCDIRS := . # current directory
# The source file types (headers excluded).
SRCEXTS := .cpp
# The flags used by the cpp (man cpp for more).
CPPFLAGS :=
# The compiling flags used only for C.
# If it is a C++ program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C parts.
CFLAGS :=
CFLAGS +=
# The compiling flags used only for C++.
# If it is a C program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C++ parts.
CXXFLAGS := -g -O2 -I./include
CXXFLAGS +=
# The library and the link options ( C and C++ common).
LDFLAGS := -L./lib -lcryptopp
LDFLAGS +=
## Implict Section: change the following only when necessary.
##=============================================================================
# The C program compiler. Uncomment it to specify yours explicitly.
#CC = gcc
# The C++ program compiler. Uncomment it to specify yours explicitly.
CXX = g++
# Uncomment the 2 lines to compile C programs as C++ ones.
CC = $(CXX)
CFLAGS = $(CXXFLAGS)
# The command used to delete file.
RM = rm -f
## Stable Section: usually no need to be changed. But you can add more.
##=============================================================================
SHELL = /bin/sh
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
OBJS = $(foreach x,$(SRCEXTS), \
$(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))
DEPS = $(patsubst %.o,%.d,$(OBJS))
.PHONY : all objs clean cleanall rebuild
all : $(PROGRAM)
# Rules for creating the dependency files (.d).
#---------------------------------------------------
%.d : %.c
@$(CC) -MM -MD $(CFLAGS) $<
%.d : %.C
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cc
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cpp
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.CPP
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.c++
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cp
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cxx
@$(CC) -MM -MD $(CXXFLAGS) $<
# Rules for producing the objects.
#---------------------------------------------------
objs : $(OBJS)
%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<
%.o : %.C
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.CPP
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.c++
$(CXX -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cxx
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
# Rules for producing the executable.
#----------------------------------------------
$(PROGRAM) : $(OBJS)
ifeq ($(strip $(SRCEXTS)), .c) # C file
$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
else # C++ file
$(CXX) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
endif
-include $(DEPS)
rebuild: clean all
clean :
@$(RM) *.o *.d
cleanall: clean
@$(RM) $(PROGRAM) $(PROGRAM).exe
本文提供的C++源代码已在Redhat Enterprise Server 5.0和Windows XP平台编译链接成功,使用的编译器分别是g++ 3.4.6、Visual C++ 6.0 (SP 6)。由于两个平台的代码差别不大,仅提供Linux平台的代码!如果你需要Windows平台的代码,可以向我索取,留下你的邮件地址即可!如果你在使 用过程中,遇到任何问题,也欢迎你给我留言!
源程序主要包括五个文件:MyRSA.h、 MyRSA.cpp、Main.h、Main.cpp、makefile;两个目录:lib目录包含libcryptopp.a,include目录包含 Crypto++5.5.2中的所有.h头文件。对了,上述五个文件与lib,include目录在同一层目录!需要说明的是,makefile是借用了 一个兄弟的,忘记名字了,不好意思:-)
哈,还是贴代码吧!
/************************** MyRSA.h ********************************/
#ifndef __MYRSA_H__
#define __MYRSA_H__
#include <string>
#include "files.h"
#include "filters.h"
#include "hex.h"
#include "randpool.h"
#include "rsa.h"
using namespace std;
using namespace CryptoPP;
class CMyRSA
{
public:
CMyRSA(void);
virtual ~CMyRSA(void);
//You must set the KeyLength 512, 1024, 2048 ...
void GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub);
void GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub);
//use public key to encrypt
void EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext);
void EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext);
//use private key to decrypt
void DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext);
void DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext);
private:
static RandomPool & RNG(void);
private:
static RandomPool m_sRandPool;
};
#endif /* End of __MYRSA_H__ */
/************************** MyRSA.cpp ********************************/
#include "MyRSA.h"
CMyRSA::CMyRSA()
{
}
CMyRSA::~CMyRSA(void)
{
}
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, RSAES_OAEP_SHA_Decryptor &Priv, RSAES_OAEP_SHA_Encryptor &Pub)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
//generate private key
Priv = RSAES_OAEP_SHA_Decryptor(RandPool, KeyLength);
//generate public key using private key
Pub = RSAES_OAEP_SHA_Encryptor(Priv);
}
void CMyRSA::GenerateKey(const unsigned int KeyLength, const char *Seed, string &strPriv, string &strPub)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
//generate private key
RSAES_OAEP_SHA_Decryptor Priv(RandPool, KeyLength);
HexEncoder PrivateEncoder(new StringSink(strPriv));
Priv.DEREncode(PrivateEncoder);
PrivateEncoder.MessageEnd();
//generate public key using private key
RSAES_OAEP_SHA_Encryptor Pub(Priv);
HexEncoder PublicEncoder(new StringSink(strPub));
Pub.DEREncode(PublicEncoder);
PublicEncoder.MessageEnd();
}
void CMyRSA::EncryptString(const RSAES_OAEP_SHA_Encryptor &Pub, const char *Seed, const string &Plaintext, string &Ciphertext)
{
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
int MaxMsgLength = Pub.FixedMaxPlaintextLength();
for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)
{
string PartPlaintext = Plaintext.substr(j, MaxMsgLength);
string PartCiphertext;
StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));
Ciphertext += PartCiphertext;
}
}
void CMyRSA::EncryptString(const string &strPub, const char *Seed, const string &Plaintext, string &Ciphertext)
{
StringSource PublicKey(strPub, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor Pub(PublicKey);
RandomPool RandPool;
RandPool.IncorporateEntropy((byte *)Seed, strlen(Seed));
int MaxMsgLength = Pub.FixedMaxPlaintextLength();
for (int i = Plaintext.size(), j=0; i > 0; i -= MaxMsgLength, j += MaxMsgLength)
{
string PartPlaintext = Plaintext.substr(j, MaxMsgLength);
string PartCiphertext;
StringSource(PartPlaintext, true, new PK_EncryptorFilter(RandPool, Pub, new HexEncoder(new StringSink(PartCiphertext))));
Ciphertext += PartCiphertext;
}
}
void CMyRSA::DecryptString(const RSAES_OAEP_SHA_Decryptor &Priv, const string &Ciphertext, string &Plaintext)
{
//indicate the ciphertext in hexcode
int CiphertextLength = Priv.FixedCiphertextLength() * 2;
for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)
{
string PartCiphertext = Ciphertext.substr(j, CiphertextLength);
string PartPlaintext;
StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));
Plaintext += PartPlaintext;
}
}
void CMyRSA::DecryptString(const string &strPriv, const string &Ciphertext, string &Plaintext)
{
StringSource PrivKey(strPriv, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor Priv(PrivKey);
//indicate the ciphertext in hexcode
int CiphertextLength = Priv.FixedCiphertextLength() * 2;
for (int i = Ciphertext.size(), j=0; i > 0; i -= CiphertextLength, j += CiphertextLength)
{
string PartCiphertext = Ciphertext.substr(j, CiphertextLength);
string PartPlaintext;
StringSource(PartCiphertext, true, new HexDecoder(new PK_DecryptorFilter(RNG(), Priv, new StringSink(PartPlaintext))));
Plaintext += PartPlaintext;
}
}
RandomPool & CMyRSA::RNG(void)
{
return m_sRandPool;
}
RandomPool CMyRSA::m_sRandPool;
/************************** Main.h ********************************/
#ifndef __MAIN_H__
#define __MAIN_H__
#endif /* End of __MAIN_H__ */
/************************** Main.cpp ********************************/
#include <unistd.h>
#include <iostream>
#include "Main.h"
#include "MyRSA.h"
/***** STATIC VARIABLES *****/
static RSAES_OAEP_SHA_Encryptor g_Pub;
static RSAES_OAEP_SHA_Decryptor g_Priv;
static string g_strPub;
static string g_strPriv;
int main(int argc, char *argv[])
{
try
{
char Seed[1024], Message[1024], MessageSeed[1024];
unsigned int KeyLength;
CMyRSA MyRSA;
cout << "Key length in bits: ";
cin >> KeyLength;
cout << "\nRandom Seed: ";
ws(cin);
cin.getline(Seed, 1024);
cout << "\nMessage: ";
ws(cin);
cin.getline(Message, 1024);
cout << "\nRandom Message Seed: ";
ws(cin);
cin.getline(MessageSeed, 1024);
MyRSA.GenerateKey(KeyLength, Seed, g_Priv, g_Pub);
//MyRSA.GenerateKey(KeyLength, Seed, g_strPriv, g_strPub);
//If generate key in RSAES_OAEP_SHA_Encryptor and RSAES_OAEP_SHA_Decryptor, please note four lines below
/*
cout << "g_strPub = " << g_strPub << endl;
cout << endl;
cout << "g_strPriv = " << g_strPriv << endl;
cout << endl;
*/
string Plaintext(Message);
string Ciphertext;
MyRSA.EncryptString(g_Pub, MessageSeed, Plaintext, Ciphertext);
//MyRSA.EncryptString(g_strPub, MessageSeed, Plaintext, Ciphertext);
cout << "\nCiphertext: " << Ciphertext << endl;
cout << endl;
string Decrypted;
MyRSA.DecryptString(g_Priv, Ciphertext, Decrypted);
//MyRSA.DecryptString(g_strPriv, Ciphertext, Decrypted);
cout << "\nDecrypted: " << Decrypted << endl;
return 0;
}
catch(CryptoPP::Exception const &e)
{
cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
return -1;
}
catch(std::exception const &e)
{
cout << "\nstd::exception caught: " << e.what() << endl;
return -2;
}
return -3;
}
/************************** Makefile ********************************/
# The executable file name.
PROGRAM := myrsa
# The directories in which source files reside.
SRCDIRS := . # current directory
# The source file types (headers excluded).
SRCEXTS := .cpp
# The flags used by the cpp (man cpp for more).
CPPFLAGS :=
# The compiling flags used only for C.
# If it is a C++ program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C parts.
CFLAGS :=
CFLAGS +=
# The compiling flags used only for C++.
# If it is a C program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C++ parts.
CXXFLAGS := -g -O2 -I./include
CXXFLAGS +=
# The library and the link options ( C and C++ common).
LDFLAGS := -L./lib -lcryptopp
LDFLAGS +=
## Implict Section: change the following only when necessary.
##=============================================================================
# The C program compiler. Uncomment it to specify yours explicitly.
#CC = gcc
# The C++ program compiler. Uncomment it to specify yours explicitly.
CXX = g++
# Uncomment the 2 lines to compile C programs as C++ ones.
CC = $(CXX)
CFLAGS = $(CXXFLAGS)
# The command used to delete file.
RM = rm -f
## Stable Section: usually no need to be changed. But you can add more.
##=============================================================================
SHELL = /bin/sh
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
OBJS = $(foreach x,$(SRCEXTS), \
$(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))
DEPS = $(patsubst %.o,%.d,$(OBJS))
.PHONY : all objs clean cleanall rebuild
all : $(PROGRAM)
# Rules for creating the dependency files (.d).
#---------------------------------------------------
%.d : %.c
@$(CC) -MM -MD $(CFLAGS) $<
%.d : %.C
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cc
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cpp
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.CPP
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.c++
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cp
@$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cxx
@$(CC) -MM -MD $(CXXFLAGS) $<
# Rules for producing the objects.
#---------------------------------------------------
objs : $(OBJS)
%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<
%.o : %.C
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.CPP
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.c++
$(CXX -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cxx
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
# Rules for producing the executable.
#----------------------------------------------
$(PROGRAM) : $(OBJS)
ifeq ($(strip $(SRCEXTS)), .c) # C file
$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
else # C++ file
$(CXX) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
endif
-include $(DEPS)
rebuild: clean all
clean :
@$(RM) *.o *.d
cleanall: clean
@$(RM) $(PROGRAM) $(PROGRAM).exe