開放封閉原則(OCP,Open Closed Principle)是所有面向對象原則的核心。軟件設計本身所追求的目標就是封裝變化、降低耦合,而開放封閉原則正是對這一目標的最直接體現。
在軟件架構中,模塊化編程思想將系統分成很多的模塊,模塊內部關注自身需要實現的核心業務。模塊間的低耦合,而模塊內的高聚合。
在Windows、Linux及unix等操作系統中,我們常常看見動態鏈接庫(.dll/.so),靜態庫(.lib/.a)身影。動態鏈接庫和靜態庫也就是我們所說的模塊化設計思想。
共享庫的主要特徵是實現資源共享,信息封裝隱蔽,這樣會帶來這樣的優勢:
1) 當開發商業化軟件時,保護了自己的知識產權;
2) 軟件架構清晰,減少軟件測試的難度;
3) 模塊化軟件升級便捷。
在VxWorks6.X之後,Workbench3.0工程中有了Shared library project功能。互聯網上這方面內容不知道爲何那麼少?這一點我感覺比較迷惑?
本文從Windows環境下開發常用的動態鏈接庫和靜態庫兩點出發,解決我們初學者首次在開發過程中可能出現各種的問題(如有)。考慮到我們在動態編譯過程中,使用蒼白的文本可能並不能完全清晰地說明問題。因此,本文使用了大量的截圖,描述編譯中需要的配置。
儘管本文使用C++編寫的測試範例很簡單,但對於入門VxWorks共享庫編程還是有所幫助的,希望此文能對你將來開發複雜的系統提供微薄之力。
下面的內容可能顯得比較簡單,而有些編譯過程中碰到的問題,網絡上也需求不到答案,也許你也曾經困惑過。
一、目錄組織
WorkSapce:“D:\casco800A\fep\code\test_sys”
文件組織:--d:/casco800A
---------------------/fep
---------------------------/bin
---------------------------/lib
---------------------------/code
----------------------------------/test_sys
二、設置環境變量FEPROOT
注意:在文件路徑書寫上,除了Windows相關的操作系統,其他操作系統中,我建議你統一使用反斜槓,否則在後面使用該環境變量時出現不能識別的問題。
圖2.1 環境變量設置
三、創建動態鏈接庫(.so)
我們首先建立一個名稱爲“libdemo”動態鏈接庫。根據嚮導按照如下步驟執行即可,其餘選項都按系統默認。
圖3.1 新建so動態鏈接庫
圖3.2 選擇動態鏈接庫
圖3.3 完成嚮導
圖3.4 生成後的框架
圖2.4生成的框架,在沒有編譯之前只有兩個目錄,此時我們不要急着編譯,否則你可能出現沒法編譯生成期望的libdemo.so文件。
關於爲何加入的新文件,workbench不能生成*.so,這一點我在網絡上查找了很多文檔都沒提示說明,也許WorkBench就是這麼設計的。
其實具體的原因很簡單,該開發環境選擇的工程一旦編譯,自動生成MakeFile就不因爲新加的文件而自動修改。當前我們要添加相應的資源文件*.cpp和*.h文件,具體內容在後面會講到。
圖3.5 添加兩個文件夾inc和src,並建立相應的文件
1)stdafx.h實現代碼:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__E5CE9468_AAF9_46A6_979B_9C125F6E9D00__INCLUDED_)
#define AFX_STDAFX_H__E5CE9468_AAF9_46A6_979B_9C125F6E9D00__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__E5CE9468_AAF9_46A6_979B_9C125F6E9D00__INCLUDED_)
2)stdafx.cpp實現代碼:
// stdafx.cpp : source file that includes just the standard includes
// libdemo.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
3)demo.h實現代碼:
#ifndef _DEMO_H_
#define _DEMO_H_
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the AE_DEMO_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// AE_DEMO_ENTRY functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef WIN32
#ifdef AE_DEMO_EXPORTS
#define AE_DEMO_ENTRY__declspec(dllexport)
#else
#define AE_DEMO_ENTRY__declspec(dllimport)
#endif
#else
#define AE_DEMO_ENTRY
#endif
// This class is exported from the libdemo.dll
class AE_DEMO_ENTRY CTest
{
public:
CTest();
virtual ~CTest();
public:
int Add(int a,int b);
protected:
int m_nCount;
};
extern AE_DEMO_ENTRY int nTest;
AE_DEMO_ENTRY int fnTest();
#endif // _DEMO_H_
4)demo.cpp實現代碼:
#include "stdafx.h"
#include "demo.h"
// This is an example of an exported variable
AE_DEMO_ENTRY int nTest = 0x64;
// This is an example of an exported function.
AE_DEMO_ENTRY int fnTest()
{
return 64;
}
// This is the constructor of a class that has been exported.
// see demo.h for the class definition
CTest::CTest()
{
}
CTest::~CTest()
{
}
int CTest::Add(int a,int b)
{
return (a + b);
}
當然我們實現的代碼資源已經存在,我們可以直接導入關聯的文件即可:
圖3.6 直接導入資源文件
圖3.7 選擇“File System”
圖3.8 導入相應的資源
圖3.9 編譯工程
我們發現“build console”出現如下錯誤,主要原因是包含路徑問題:
Build Started in Project 'libdemo': 2015-02-07 21:35:56
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1
Working Directory: D:/casco800A/fep/code/test_sys/libdemo/SIMPENTIUMdiab_RTP
if [ ! -d "`dirname "libdemo/Debug/Objects/libdemo/src/demo.sho"`" ]; then mkdir -p "`dirname "libdemo/Debug/Objects/libdemo/src/demo.sho"`"; fi;echo "building libdemo/Debug/Objects/libdemo/src/demo.sho"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo/Debug/Objects/libdemo/src/demo.sho" -c "D:/casco800A/fep/code/test_sys/libdemo/src/demo.cpp"
building libdemo/Debug/Objects/libdemo/src/demo.sho
"D:/casco800A/fep/code/test_sys/libdemo/src/demo.cpp", line 1: catastrophic error (etoa:4005):
could not open source file "stdafx.h"
#include "stdafx.h"
^
1 catastrophic error detected in the compilation of "D:/casco800A/fep/code/test_sys/libdemo/src/demo.cpp".
Compilation terminated.
C:\WindRiver-GPPVE-3.6-PPC-Eval\workbench-3.0\x86-win32\bin\make.exe: *** [libdemo/Debug/Objects/libdemo/src/demo.sho] Error 1
Build Failed in Project 'libdemo' (Process Exit Value was 2): 2015-02-07 21:35:57 (Elapsed Time: 00:01)
解決方法:
熟悉微軟VS開發環境的人基本都很清楚,怎麼讓自己生成的目標文件和對象拷貝到何方,包括引用的動態庫和引用目錄,這一切都是從project->setting內設置。
1)增加copy功能,我們通常把動態庫與運行程序放在bin目錄下。
echo "copy $@ to $(FEPROOT)/bin"; cp -f "$@" $(FEPROOT)/bin/libdemo.so
也可以這樣寫,讓系統生成默認的文件,其中$@可以不加“”:
echo "copy $@ to $(FEPROOT)/bin"; cp -f $@ $(FEPROOT)/bin
圖3.10 增加copy功能命令
2)增加路徑包含功能,注意相對目錄層次。
圖3.11 增加“inc”目錄,可以寫成“-I$(PRJ_ROOT_DIR/inc”
3)再次編譯即可通過
Build Started in Project 'libdemo': 2015-02-07 21:41:55
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1
Working Directory: D:/casco800A/fep/code/test_sys/libdemo/SIMPENTIUMdiab_RTP
if [ ! -d "`dirname "libdemo/Debug/Objects/libdemo/src/demo.sho"`" ]; then mkdir -p "`dirname "libdemo/Debug/Objects/libdemo/src/demo.sho"`"; fi;echo "building libdemo/Debug/Objects/libdemo/src/demo.sho"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo/Debug/Objects/libdemo/src/demo.sho" -c "D:/casco800A/fep/code/test_sys/libdemo/src/demo.cpp"
building libdemo/Debug/Objects/libdemo/src/demo.sho
if [ ! -d "`dirname "libdemo/Debug/Objects/libdemo/src/stdafx.sho"`" ]; then mkdir -p "`dirname "libdemo/Debug/Objects/libdemo/src/stdafx.sho"`"; fi;echo "building libdemo/Debug/Objects/libdemo/src/stdafx.sho"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo/Debug/Objects/libdemo/src/stdafx.sho" -c "D:/casco800A/fep/code/test_sys/libdemo/src/stdafx.cpp"
building libdemo/Debug/Objects/libdemo/src/stdafx.sho
if [ ! -d "`dirname "libdemo/Debug/libdemo.so"`" ]; then mkdir -p "`dirname "libdemo/Debug/libdemo.so"`"; fi;echo "building libdemo/Debug/libdemo.so";SONAME=`basename ""libdemo/Debug/libdemo.so""`;if [ "" != "" ]; then SONAME=$SONAME.;fi; dplus -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -Wl, -Xshared -Wl, -Xdynamic -soname="$SONAME" -o "libdemo/Debug/libdemo.so" libdemo/Debug/Objects/libdemo/src/demo.sho libdemo/Debug/Objects/libdemo/src/stdafx.sho -lstlstd -LC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/lib/simpentium/SIMPENTIUM/common/PIC && if [ "0" = "1" ]; then mv -f "libdemo/Debug/libdemo.so" "libdemo/Debug/libdemo.so.unstripped" && strippentium -g -o "libdemo/Debug/libdemo.so" "libdemo/Debug/libdemo.so.unstripped";fi && if [ "0" = "1" ]; then plink "libdemo/Debug/libdemo.so";fi && if [ "" != "" ]; then cp -f "libdemo/Debug/libdemo.so" "libdemo/Debug/libdemo.so.";fi;echo "copy libdemo/Debug/libdemo.so to d:/casco800A/fep/bin"; cp -f "libdemo/Debug/libdemo.so" d:/casco800A/fep/bin/libdemo.so
building libdemo/Debug/libdemo.so
copy libdemo/Debug/libdemo.so to d:/casco800A/fep/bin
make: built targets of D:/casco800A/fep/code/test_sys/libdemo/SIMPENTIUMdiab_RTP
Build Finished in Project 'libdemo': 2015-02-07 21:41:56 (Elapsed Time: 00:01)
圖3.12 工程生成之後的目錄狀況
4)當然您還可以通過shell直接編譯
圖3.13 shell編譯工程
當然如果你直接修改MakeFile也是可以的,但是我建議你不要這麼費工夫,讓系統按照它自己的規則定義是最好的(我是這麼看的)。因此,只要執行下面的操作,然後再次編譯工程即可。
圖3.14 刪除選擇的文件夾,讓系統重新生成MakeFile
使用圖3.14這種方式,對於剛新建而加入的文件(*.cpp)特別適合。
四、創建RTP測試程序(testdemo)
圖4.1 創建testdemo工程(RTP)
圖4.2 選擇SIMPENTIUMdiab_RTP
圖4.3 選擇Linker編譯工具
圖4.4 新建文件testdemo.cpp
(stdafx.cpp和stdafx.h與上面類似)
// testdemo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "demo.h"
int main(int argc,char* argv[])
{
CTest test;
int nSum = test.Add(1, 2);
printf("a=1,b=2,sum=%d\n", nSum);
printf("nTest=%d\n", nTest);
printf("int fnTest() return %d\n", fnTest());
return 0;
}
項目屬性設置:
1)增加copy功能,我們通常把動態庫與運行程序放在bin目錄下。
echo "copy $@ to $(FEPROOT)/bin"; cp -f "$@" $(FEPROOT)/bin/testdemo.so
也可以寫成這樣:
echo "copy $@ to $(FEPROOT)/bin"; cp -f $@ $(FEPROOT)/bin
圖4.5增加“copy”功能
圖4.6增加“copy”功能
圖4.7 增加libdemo.so動態鏈接庫引用
如果我們不按照圖4.7指定方法添加,那麼你還可以按照下列(圖4.8—圖4.10)設置完成,這樣我們可以把動態鏈接庫和靜態庫統一使用這樣配置:
圖4.8 常規增加libdemo.so動態鏈接庫引用
圖4.9 設置編譯選項:-Xdynmaic
圖4.10選中:Create a dynamic executable
圖4.11 bin目錄下的動態庫與運行程序
五、DEBUG程序
圖5.1 Debug調試環境設置
圖5.2 Debug控制檯輸出內容
輸出的結果:
a=1,b=2,sum=3
nTest=100
int fnTest() return 64
圖5.3 vxsim0控制檯輸出內容
六、創建靜態庫(.a)
上面我們已經實現了動態鏈接庫,並通過測試相應的範例程序。下面準備用兩種方法生成靜態庫:
第1種常見方法:
依據工程嚮導,我們按照前面動態鏈接庫的步驟即可,只要注意下面的設置選項:
圖6.1 創建libdemo1靜態庫(.a)
圖6.2 選擇靜態庫編譯工具
添加上述靜態庫的文件,並編譯工程libdemo1:
Build Started in Project 'libdemo1': 2015-02-10 10:11:42
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1 clean all
Working Directory: D:/casco800A/fep/code/test_sys/libdemo1/SIMPENTIUMdiab_RTP
make: removing targets and objects of D:/casco800A/fep/code/test_sys/libdemo1/SIMPENTIUMdiab_RTP
if [ -d "libdemo1" ]; then cd "libdemo1"; rm -rf Debug; fi
if [ ! -d "`dirname "libdemo1/Debug/Objects/libdemo1/src/demo.sho"`" ]; then mkdir -p "`dirname "libdemo1/Debug/Objects/libdemo1/src/demo.sho"`"; fi;echo "building libdemo1/Debug/Objects/libdemo1/src/demo.sho"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo1/Debug/Objects/libdemo1/src/demo.sho" -c "D:/casco800A/fep/code/test_sys/libdemo1/src/demo.cpp"
building libdemo1/Debug/Objects/libdemo1/src/demo.sho
if [ ! -d "`dirname "libdemo1/Debug/Objects/libdemo1/src/stdafx.sho"`" ]; then mkdir -p "`dirname "libdemo1/Debug/Objects/libdemo1/src/stdafx.sho"`"; fi;echo "building libdemo1/Debug/Objects/libdemo1/src/stdafx.sho"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -Xpic -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo1/Debug/Objects/libdemo1/src/stdafx.sho" -c "D:/casco800A/fep/code/test_sys/libdemo1/src/stdafx.cpp"
building libdemo1/Debug/Objects/libdemo1/src/stdafx.sho
if [ ! -d "`dirname "libdemo1/Debug/libdemo1.a"`" ]; then mkdir -p "`dirname "libdemo1/Debug/libdemo1.a"`"; fi;echo "building libdemo1/Debug/libdemo1.a"; dar crus "libdemo1/Debug/libdemo1.a" libdemo1/Debug/Objects/libdemo1/src/demo.sho libdemo1/Debug/Objects/libdemo1/src/stdafx.sho ; echo "copy libdemo1/Debug/libdemo1.a to d:/casco800A/fep/lib";cp -f libdemo1/Debug/libdemo1.a d:/casco800A/fep/lib;
building libdemo1/Debug/libdemo1.a
copy libdemo1/Debug/libdemo1.a to d:/casco800A/fep/lib
make: built targets of D:/casco800A/fep/code/test_sys/libdemo1/SIMPENTIUMdiab_RTP
Build Finished in Project 'libdemo1': 2015-02-10 10:11:42 (Elapsed Time: 00:01)
設置testdemo工程配置項:
圖6.3 配置引用的路徑和靜態庫文件
重新編譯testDemo工程:
Build Started in Project 'testdemo': 2015-02-10 10:14:02
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1 clean all
Working Directory: D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
make: removing targets and objects of D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
if [ -d "testdemo" ]; then cd "testdemo"; rm -rf Debug; fi
if [ ! -d "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`" ]; then mkdir -p "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`"; fi;echo "building testdemo/Debug/Objects/testdemo/testdemo.o"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -Id:/casco800A/fep/code/include -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "testdemo/Debug/Objects/testdemo/testdemo.o" -c "D:/casco800A/fep/code/test_sys/testdemo/testdemo.cpp"
building testdemo/Debug/Objects/testdemo/testdemo.o
if [ ! -d "`dirname "testdemo/Debug/testdemo.vxe"`" ]; then mkdir -p "`dirname "testdemo/Debug/testdemo.vxe"`"; fi;echo "building testdemo/Debug/testdemo.vxe"; dplus -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -f 0x90,1,1 -o "testdemo/Debug/testdemo.vxe" testdemo/Debug/Objects/testdemo/testdemo.o -L d:/casco800A/fep/lib -lstlstd -ldemo1 -LC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/lib/simpentium/SIMPENTIUM/common && if [ "0" = "1" ]; then mv -f "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped" && strippentium -g -o "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped";fi && if [ "0" = "1" ]; then plink "testdemo/Debug/testdemo.vxe";fi; echo "copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin";cp -f testdemo/Debug/testdemo.vxe d:/casco800A/fep/bin;
building testdemo/Debug/testdemo.vxe
dld: warning: Undefined symbol '__GOTT_BASE__' in file 'demo.sho(d:/casco800A/fep/lib\libdemo1.a)'
dld: warning: Undefined symbol '__GOTT_INDEX__' in file 'demo.sho(d:/casco800A/fep/lib\libdemo1.a)'
dld: error: Undefined symbols found - no output written
copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin
cp: cannot stat `testdemo\\Debug\\testdemo.vxe': No such file or directory
C:\WindRiver-GPPVE-3.6-PPC-Eval\workbench-3.0\x86-win32\bin\make.exe: *** [testdemo/Debug/testdemo.vxe] Error 1
Build Failed in Project 'testdemo' (Process Exit Value was 2): 2015-02-10 10:14:03 (Elapsed Time: 00:01)
爲什麼這樣,網絡上也無語?
圖6.4 C++編譯器中有編譯選項-Xpic
解決方法:
圖6.5 去除C++編譯選項-Xpic
重新編譯libDemo1工程,重新編譯testDemo工程:
Build Started in Project 'testdemo': 2015-02-10 10:27:25
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1 clean all
Working Directory: D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
make: removing targets and objects of D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
if [ -d "testdemo" ]; then cd "testdemo"; rm -rf Debug; fi
if [ ! -d "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`" ]; then mkdir -p "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`"; fi;echo "building testdemo/Debug/Objects/testdemo/testdemo.o"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -Id:/casco800A/fep/code/include -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "testdemo/Debug/Objects/testdemo/testdemo.o" -c "D:/casco800A/fep/code/test_sys/testdemo/testdemo.cpp"
building testdemo/Debug/Objects/testdemo/testdemo.o
if [ ! -d "`dirname "testdemo/Debug/testdemo.vxe"`" ]; then mkdir -p "`dirname "testdemo/Debug/testdemo.vxe"`"; fi;echo "building testdemo/Debug/testdemo.vxe"; dplus -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -f 0x90,1,1 -o "testdemo/Debug/testdemo.vxe" testdemo/Debug/Objects/testdemo/testdemo.o -L d:/casco800A/fep/lib -lstlstd -ldemo1 -LC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/lib/simpentium/SIMPENTIUM/common && if [ "0" = "1" ]; then mv -f "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped" && strippentium -g -o "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped";fi && if [ "0" = "1" ]; then plink "testdemo/Debug/testdemo.vxe";fi; echo "copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin";cp -f testdemo/Debug/testdemo.vxe d:/casco800A/fep/bin;
building testdemo/Debug/testdemo.vxe
copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin
make: built targets of D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
Build Finished in Project 'testdemo': 2015-02-10 10:27:25 (Elapsed Time: 00:01)
編譯通過,調試testDemo:
圖6.6 測試結果
關於PIC補充一點說明:
縮寫pic代表位置獨立代碼(position independent code)。
-Xpic:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼,是位置相關的。所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。–shared:指明編譯成動態庫。
選項-Xpic表示輸出的對象模塊式按照可重定位地址(relocatable addressing)方式生成的。
第2種特殊方法:
這一種方法主要使用Real Time Process工程創建靜態庫,請注意下面的選項。
圖6.7 創建libdemo2靜態庫
圖6.8 選擇靜態庫項
包含路徑與libdemo一樣即可,導入inc和src相關文件,再次編譯libedem2:
Build Started in Project 'libdemo2': 2015-02-10 11:08:58
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1 clean all
Working Directory: D:/casco800A/fep/code/test_sys/libdemo2/SIMPENTIUMdiab_RTP
make: removing targets and objects of D:/casco800A/fep/code/test_sys/libdemo2/SIMPENTIUMdiab_RTP
if [ -d "libdemo2" ]; then cd "libdemo2"; rm -rf Debug; fi
if [ ! -d "`dirname "libdemo2/Debug/Objects/libdemo2/src/demo.o"`" ]; then mkdir -p "`dirname "libdemo2/Debug/Objects/libdemo2/src/demo.o"`"; fi;echo "building libdemo2/Debug/Objects/libdemo2/src/demo.o"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo2/Debug/Objects/libdemo2/src/demo.o" -c "D:/casco800A/fep/code/test_sys/libdemo2/src/demo.cpp"
building libdemo2/Debug/Objects/libdemo2/src/demo.o
if [ ! -d "`dirname "libdemo2/Debug/Objects/libdemo2/src/stdafx.o"`" ]; then mkdir -p "`dirname "libdemo2/Debug/Objects/libdemo2/src/stdafx.o"`"; fi;echo "building libdemo2/Debug/Objects/libdemo2/src/stdafx.o"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -I../inc -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "libdemo2/Debug/Objects/libdemo2/src/stdafx.o" -c "D:/casco800A/fep/code/test_sys/libdemo2/src/stdafx.cpp"
building libdemo2/Debug/Objects/libdemo2/src/stdafx.o
if [ ! -d "`dirname "libdemo2/Debug/libdemo2.a"`" ]; then mkdir -p "`dirname "libdemo2/Debug/libdemo2.a"`"; fi;echo "building libdemo2/Debug/libdemo2.a"; dar crus "libdemo2/Debug/libdemo2.a" libdemo2/Debug/Objects/libdemo2/src/demo.o libdemo2/Debug/Objects/libdemo2/src/stdafx.o ; echo "copy libdemo2/Debug/libdemo2.a to d:/casco800A/fep/lib";cp -f libdemo2/Debug/libdemo2.a d:/casco800A/fep/lib;
building libdemo2/Debug/libdemo2.a
copy libdemo2/Debug/libdemo2.a to d:/casco800A/fep/lib
make: built targets of D:/casco800A/fep/code/test_sys/libdemo2/SIMPENTIUMdiab_RTP
Build Finished in Project 'libdemo2': 2015-02-10 11:08:58 (Elapsed Time: 00:01)
再次設置testDemo工程:
圖6.9 靜態庫路徑引用項和libdemo2文件
再次編譯testDemo工程:
Build Started in Project 'testdemo': 2015-02-10 11:13:16
Generation of makefiles started.
Generation of makefiles finished (Elapsed Time: 00:00).
Platform: Wind River VxWorks 6.6
Command: make --no-print-directory BUILD_SPEC=SIMPENTIUMdiab_RTP DEBUG_MODE=1 TRACE=1 clean all
Working Directory: D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
make: removing targets and objects of D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
if [ -d "testdemo" ]; then cd "testdemo"; rm -rf Debug; fi
if [ ! -d "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`" ]; then mkdir -p "`dirname "testdemo/Debug/Objects/testdemo/testdemo.o"`"; fi;echo "building testdemo/Debug/Objects/testdemo/testdemo.o"; dplus -g -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h -IC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/h/wrn/coreip -Id:/casco800A/fep/code/include -D_VX_CPU=_VX_SIMPENTIUM -D_VX_TOOL_FAMILY=diab -D_VX_TOOL=diab -o "testdemo/Debug/Objects/testdemo/testdemo.o" -c "D:/casco800A/fep/code/test_sys/testdemo/testdemo.cpp"
building testdemo/Debug/Objects/testdemo/testdemo.o
if [ ! -d "`dirname "testdemo/Debug/testdemo.vxe"`" ]; then mkdir -p "`dirname "testdemo/Debug/testdemo.vxe"`"; fi;echo "building testdemo/Debug/testdemo.vxe"; dplus -tX86LH:rtpsim -Xansi -Xforce-declarations -Xmake-dependency=0xd -f 0x90,1,1 -o "testdemo/Debug/testdemo.vxe" testdemo/Debug/Objects/testdemo/testdemo.o -L d:/casco800A/fep/lib -lstlstd -ldemo2 -LC:/WindRiver-GPPVE-3.6-PPC-Eval/vxworks-6.6/target/usr/lib/simpentium/SIMPENTIUM/common && if [ "0" = "1" ]; then mv -f "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped" && strippentium -g -o "testdemo/Debug/testdemo.vxe" "testdemo/Debug/testdemo.vxe.unstripped";fi && if [ "0" = "1" ]; then plink "testdemo/Debug/testdemo.vxe";fi; echo "copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin";cp -f testdemo/Debug/testdemo.vxe d:/casco800A/fep/bin;
building testdemo/Debug/testdemo.vxe
copy testdemo/Debug/testdemo.vxe to d:/casco800A/fep/bin
make: built targets of D:/casco800A/fep/code/test_sys/testdemo/SIMPENTIUMdiab_RTP
Build Finished in Project 'testdemo': 2015-02-10 11:13:17 (Elapsed Time: 00:01)
測試結果:
圖6.10 單步調試結果
七、總結
我們用大量的截圖說明創建了動態鏈接庫和靜態庫,其中動態鏈接庫看起來比較簡單。靜態庫創建有兩種方法,第一種是我們傳統創建方法,但需要注意編譯器的配置項。第二種是使用RTP創建,基本沒有太多配置。無論是第一種還是第二種方法,其實我們可以發現編譯開發PIC是關鍵。
用大量截圖說明創建共享庫的過程,這是一種直接而顯而易見的方法,我相信參考上述這些過程,你碰到的問題基本能得以解決。