Compare commits
78 Commits
release/3.
...
release/3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65605d175f | ||
|
|
f00e4910e8 | ||
|
|
d4df1c7cba | ||
|
|
6a202a495f | ||
|
|
4b3e09deec | ||
|
|
e4282ff85b | ||
|
|
866b67d036 | ||
|
|
5417456b05 | ||
|
|
5212ea7bdc | ||
|
|
e3eb2aa347 | ||
|
|
bc58ece69a | ||
|
|
802e9dbc28 | ||
|
|
3f6504eb81 | ||
|
|
03999ef343 | ||
|
|
4a9d8e58d2 | ||
|
|
ced4855c65 | ||
|
|
75c35a49b3 | ||
|
|
651482a0df | ||
|
|
f0fff6d16e | ||
|
|
8d1e9abcc9 | ||
|
|
5944ad64d9 | ||
|
|
cf1afee705 | ||
|
|
548de8bd2d | ||
|
|
f390d16625 | ||
|
|
fbda7475f0 | ||
|
|
287380d98d | ||
|
|
355a88d0cd | ||
|
|
245ab83192 | ||
|
|
0c3bf73b01 | ||
|
|
689f73ef76 | ||
|
|
4bf8367d3c | ||
|
|
d4890af978 | ||
|
|
c2ef0ba2dc | ||
|
|
fae026da99 | ||
|
|
18889da1dc | ||
|
|
3977bab348 | ||
|
|
db21783c26 | ||
|
|
ede6d2fe85 | ||
|
|
20d4f3def3 | ||
|
|
853ca8b713 | ||
|
|
7e25d81d12 | ||
|
|
2b98575f39 | ||
|
|
1e5f4a4881 | ||
|
|
62f47ccd9d | ||
|
|
f16cdc0c80 | ||
|
|
d4b6eae8ee | ||
|
|
c7b112e8f4 | ||
|
|
3e739e8a0c | ||
|
|
9f542a9108 | ||
|
|
600d6cfb5f | ||
|
|
d001ca1263 | ||
|
|
e80520c9ac | ||
|
|
e70381a0b9 | ||
|
|
7db79e8414 | ||
|
|
0e24b325f4 | ||
|
|
9b72febb48 | ||
|
|
aed93a2267 | ||
|
|
1758cee3f3 | ||
|
|
c70b71d843 | ||
|
|
df541b96c8 | ||
|
|
09e7086560 | ||
|
|
a7162574b3 | ||
|
|
444d6be8ad | ||
|
|
0136cf6849 | ||
|
|
8f5a14dc93 | ||
|
|
0bde0fbce9 | ||
|
|
e3d55cf136 | ||
|
|
e57f5f761c | ||
|
|
c68585096d | ||
|
|
0856c9827f | ||
|
|
a54e3c43cb | ||
|
|
7c6278a7ff | ||
|
|
cb1819693d | ||
|
|
c09266504a | ||
|
|
3f2d05e183 | ||
|
|
ed043cd81c | ||
|
|
8ca2beb4cb | ||
|
|
bf9c4d93c0 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -12,7 +12,6 @@ sgBuild
|
||||
image
|
||||
build
|
||||
macflightgear
|
||||
fgdata
|
||||
src
|
||||
tmp
|
||||
Makefile
|
||||
@@ -20,7 +19,6 @@ CMakeFiles
|
||||
archivebuild
|
||||
osgbuild
|
||||
CMakeCache.txt
|
||||
aircraft-data
|
||||
*.pyc
|
||||
base_package
|
||||
extended-data
|
||||
|
||||
|
||||
12
.gitmodules
vendored
12
.gitmodules
vendored
@@ -1,16 +1,20 @@
|
||||
[submodule "simgear"]
|
||||
path = simgear
|
||||
url = git://git.code.sf.net/p/flightgear/simgear
|
||||
branch = release/3.4.0
|
||||
branch = release/3.6.0
|
||||
[submodule "flightgear"]
|
||||
path = flightgear
|
||||
url = git://git.code.sf.net/p/flightgear/flightgear
|
||||
branch = release/3.4.0
|
||||
branch = release/3.6.0
|
||||
[submodule "fgrun"]
|
||||
path = fgrun
|
||||
url = git://git.code.sf.net/p/flightgear/fgrun
|
||||
branch = release/3.4.0
|
||||
branch = release/3.6.0
|
||||
[submodule "fgdata"]
|
||||
path = fgdata
|
||||
url = git://git.code.sf.net/p/flightgear/fgdata
|
||||
branch = release/3.4.0
|
||||
branch = release/3.6.0
|
||||
[submodule "windows-3rd-party"]
|
||||
path = windows-3rd-party
|
||||
url = git://git.code.sf.net/p/flightgear/windows-3rd-party
|
||||
branch = release/3.6.0
|
||||
|
||||
110
CMakeLists.txt
110
CMakeLists.txt
@@ -1,65 +1,41 @@
|
||||
cmake_minimum_required (VERSION 2.6.4)
|
||||
cmake_minimum_required (VERSION 2.8.0)
|
||||
|
||||
include (ExternalProject)
|
||||
|
||||
project(FlightGear-Meta)
|
||||
|
||||
if(NOT CMAKE_INSTALL_PREFIX)
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
|
||||
message(STATUS "Default install dir to ${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
set(BOOST_BOOTSTRAP "./bootstrap.sh" --prefix=${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
set(BOOST_BOOTSTRAP "bootstrap.bat")
|
||||
message(STATUS "Default install dir set to ${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
|
||||
set(SG_DEPS OSG)
|
||||
set(FG_DEPS SimGear)
|
||||
set(SG_CMAKE_ARGS "")
|
||||
set(FG_CMAKE_ARGS "")
|
||||
set(FGRUN_CMAKE_ARGS "")
|
||||
|
||||
if(APPLE)
|
||||
set(BOOST_ARGS link=static stage --with-system)
|
||||
ExternalProject_Add(Boost
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
SVN_REPOSITORY http://svn.boost.org/svn/boost/tags/release/Boost_1_52_0
|
||||
UPDATE_COMMAND ${BOOST_BOOTSTRAP}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ./bjam ${BOOST_ARGS}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND ./b2 install ${BOOST_ARGS})
|
||||
|
||||
list(APPEND SG_DEPS Boost)
|
||||
endif() # of Apple
|
||||
|
||||
set(OSG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(SG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(FG_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(PLIB_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(RTI_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(FGRUN_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
|
||||
# OpenSceneGraph configuration
|
||||
set(OSG_SOURCE http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
|
||||
#set(OSG_SOURCE http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
|
||||
set(OSG_SOURCE https://github.com/openscenegraph/osg.git)
|
||||
set(OSG_TAG OpenSceneGraph-3.2)
|
||||
|
||||
if (APPLE)
|
||||
set(SDKROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk)
|
||||
# force disable Qt and Jasper, and ensure an SDKROOT is set, or
|
||||
# osgViewer system detection goes wrongh
|
||||
set(OSG_CMAKE_ARGS -DCMAKE_OSX_SYSROOT=${SDKROOT}
|
||||
# force disable Qt and Jasper
|
||||
set(OSG_CMAKE_ARGS
|
||||
-DOSG_USE_QT=0
|
||||
-DJASPER_LIBRARY=
|
||||
-DSDL_LIBRARY:FILEPATH=
|
||||
-DCMAKE_OSX_ARCHITECTURES=x86_64
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7
|
||||
)
|
||||
# OSG with some patches applied for Mac
|
||||
# set(OSG_SOURCE GIT_REPOSITORY git://gitorious.org/+flightgear-developers/openscenegraph/mac-release-osg.git)
|
||||
# set(OSG_SOURCE URL http://www.openscenegraph.org/downloads/developer_releases/OpenSceneGraph-3.2.0.zip)
|
||||
|
||||
set(OSG_SOURCE https://github.com/zakalawe/osg.git)
|
||||
set(OSG_TAG fgfs-osg-32)
|
||||
elseif(MSVC)
|
||||
set(OSG_MSVC "msvc")
|
||||
if (${MSVC_VERSION} EQUAL 1700)
|
||||
@@ -104,64 +80,31 @@ else()
|
||||
# normal OSG
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# download 3rdparty dependencies zip, including boost
|
||||
ExternalProject_Add(WinDeps
|
||||
SVN_REPOSITORY http://fgfs.goneabitbursar.com/fgwin3rdparty/trunk/msvc100/${RDPARTY_DIR}
|
||||
# extract to current root
|
||||
SOURCE_DIR ${CMAKE_BINARY_DIR}/winDeps/${RDPARTY_DIR}
|
||||
BINARY_DIR ${CMAKE_BINARY_DIR}
|
||||
UPDATE_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ${CMAKE_SOURCE_DIR}/installWinDeps.bat
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
set(BOOST_ARGS link=static stage --with-system)
|
||||
set(Boost_Version 1.54.0)
|
||||
string(REPLACE "." "_" Boost_Version_Underscore ${Boost_Version})
|
||||
ExternalProject_Add(Boost
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
URL http://downloads.sourceforge.net/project/boost/boost/${Boost_Version}/boost_${Boost_Version_Underscore}.zip
|
||||
URL_MD5 78a35834c45220a6164310e280abe675
|
||||
UPDATE_COMMAND ""
|
||||
CONFIGURE_COMMAND ${BOOST_BOOTSTRAP}
|
||||
BUILD_COMMAND bjam --with-program_options ${BOOST_ARGS}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
list(APPEND SG_DEPS Boost)
|
||||
list(APPEND SG_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
|
||||
list(APPEND FG_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
|
||||
list(APPEND FG_CMAKE_ARGS -DPNG_LIBRARY=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/lib/libpng16.lib)
|
||||
list(APPEND FGRUN_CMAKE_ARGS -DBOOST_ROOT=${CMAKE_BINARY_DIR}/src/Boost)
|
||||
endif(MSVC) # of Windows
|
||||
|
||||
ExternalProject_Add(OSG
|
||||
DEPENDS ${OSG_DEPS}
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
URL ${OSG_SOURCE}
|
||||
URL_HASH MD5=4980f8692712a24d4c99f363f80c6814
|
||||
GIT_REPOSITORY ${OSG_SOURCE}
|
||||
GIT_TAG ${OSG_TAG}
|
||||
BINARY_DIR osgbuild
|
||||
CMAKE_ARGS ${OSG_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=${OSG_INSTALL_PREFIX}
|
||||
)
|
||||
|
||||
# Because OSG install the libraries in lib64/ instead of lib/
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
ExternalProject_Add_Step(OSG after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${OSG_INSTALL_PREFIX}/lib64 ${OSG_INSTALL_PREFIX}/lib
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${OSG_INSTALL_PREFIX}/lib64
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${OSG_INSTALL_PREFIX}/lib64 ${OSG_INSTALL_PREFIX}/lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
endif()
|
||||
|
||||
# FIXME install of OpenRTI is failing on Windows, files in PREFIX/share which
|
||||
# are ending up in C:/Program Files/OpenRTI
|
||||
if (NOT MSVC)
|
||||
if (FALSE)
|
||||
ExternalProject_Add(OpenRTI
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
DOWNLOAD_COMMAND GIT_REPOSITORY git://gitorious.org/openrti/openrti.git
|
||||
DOWNLOAD_COMMAND GIT_REPOSITORY git://git.code.sf.net/p/openrti/OpenRTI
|
||||
BINARY_DIR rtibuild
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${RTI_INSTALL_PREFIX}
|
||||
)
|
||||
@@ -205,23 +148,6 @@ if (NOT WIN32)
|
||||
list(APPEND FG_DEPS PLIB)
|
||||
endif()
|
||||
|
||||
# Only compile FGRun for Windows
|
||||
if (MSVC)
|
||||
list(APPEND FGRUN_CMAKE_ARGS -DMSVC_3RDPARTY_ROOT:PATH=${CMAKE_BINARY_DIR})
|
||||
list(APPEND FGRUN_CMAKE_ARGS -DFLTK_FLUID_EXECUTABLE:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/fluid.exe)
|
||||
list(APPEND FGRUN_CMAKE_ARGS -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH==${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/msgfmt.exe)
|
||||
list(APPEND FGRUN_CMAKE_ARGS -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=${CMAKE_BINARY_DIR}/${RDPARTY_DIR}/bin/msgmerge.exe)
|
||||
ExternalProject_Add(FGRun
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${FG_DEPS}
|
||||
DOWNLOAD_COMMAND "" # no need to download
|
||||
UPDATE_COMMAND "" # or update.
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/fgrun
|
||||
BINARY_DIR fgrunbuild
|
||||
CMAKE_ARGS ${FGRUN_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=${FGRUN_INSTALL_PREFIX} -DCMAKE_PREFIX_PATH=${OSG_INSTALL_PREFIX} -DADDITIONAL_LIBRARY_PATHS=${SG_INSTALL_PREFIX}
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(FlightGear
|
||||
PREFIX ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${FG_DEPS}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
AppId=FlightGear
|
||||
AppName=FlightGear
|
||||
AppPublisher=The FlightGear Team
|
||||
OutputBaseFilename=fgsetup-{#FGVersion}
|
||||
OutputBaseFilename=FlightGear-{#FGVersion}{#FGDetails}
|
||||
AppVerName=FlightGear v{#FGVersion}
|
||||
AppPublisherURL=http://www.flightgear.org
|
||||
AppSupportURL=http://www.flightgear.org
|
||||
@@ -45,6 +45,7 @@ AppUpdatesURL=http://www.flightgear.org
|
||||
DefaultDirName={pf}\FlightGear {#FGVersion}
|
||||
UsePreviousAppDir=no
|
||||
DefaultGroupName=FlightGear {#FGVersion}
|
||||
UsePreviousGroup=no
|
||||
LicenseFile=X:\flightgear\COPYING
|
||||
Uninstallable=yes
|
||||
SetupIconFile=X:\flightgear\package\flightgear.ico
|
||||
@@ -68,22 +69,13 @@ Name: "insoal"; Description: "Install OpenAL (the sound engine)"
|
||||
; NOTE: run subst X: F:\ (or whatever path the expanded tree resides at)
|
||||
;Source: "X:\*.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; 32 bits install
|
||||
Source: "X:\install\msvc100\FlightGear\bin\fgfs.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\fgadmin.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\terrasync.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\js_demo.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\fgjs.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\GPSsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\UGsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\MIDGsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\metar.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\yasim.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\fgcom.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FlightGear\bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FGRun\bin\fgrun.exe"; DestDir: "{app}\bin"; Flags: ignoreversion ; Check: not Is64BitInstallMode
|
||||
Source: "X:\install\msvc100\FGRun\share\locale\*"; DestDir: "{app}\bin\locale"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\zlib.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\OpenAL32.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\libpng16.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\CrashRpt1402.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
Source: "X:\3rdParty\bin\CrashSender1402.exe"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
@@ -91,23 +83,14 @@ Source: "{#VCInstallDir}\redist\x86\Microsoft.VC100.CRT\*.dll"; DestDir: "{app}
|
||||
Source: "X:\3rdParty\bin\vcredist_x86.exe"; DestDir: "{app}\bin"; Flags: skipifsourcedoesntexist; Check: not Is64BitInstallMode
|
||||
|
||||
; 64 bits install
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\fgfs.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\fgadmin.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\terrasync.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\js_demo.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\fgjs.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\GPSsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\UGsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\MIDGsmooth.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\metar.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\yasim.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\fgcom.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FlightGear\bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FGRun\bin\fgrun.exe"; DestDir: "{app}\bin"; Flags: ignoreversion; Check: Is64BitInstallMode
|
||||
Source: "X:\install\msvc100-64\FGRun\share\locale\*"; DestDir: "{app}\bin\locale"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\zlib.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\OpenAL32.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\vcredist_x64.exe"; DestDir: "{app}\bin"; Flags: skipifsourcedoesntexist; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\libpng16.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\libintl-8.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\CrashRpt1402.dll"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\crashrpt_lang.ini"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
Source: "X:\3rdParty.x64\bin\CrashSender1402.exe"; DestDir: "{app}\bin"; Check: Is64BitInstallMode
|
||||
@@ -118,13 +101,12 @@ Source: "{#VCInstallDir}\redist\x64\Microsoft.VC100.CRT\*.dll"; DestDir: "{app}\
|
||||
Source: "X:\install\msvc100\FlightGear\bin\fgpanel.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||
Source: "X:\3rdParty\bin\oalinst.exe"; DestDir: "{app}\bin"; Flags: ignoreversion skipifsourcedoesntexist
|
||||
|
||||
; NOTE: tar.gz file uses name 'fgdata', to avoid renaming it, look for both names.
|
||||
; assuming no setup has both names and hence we don't package twice :)
|
||||
Source: "X:\data\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
; Include the base package
|
||||
#if IncludeData == "TRUE"
|
||||
Source: "X:\fgdata\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
|
||||
; work-around for 3.4.1: look for additional aircraft data
|
||||
; work-around for 3.6: look for additional aircraft data
|
||||
Source: "X:\extended-data\*.*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
#endif
|
||||
|
||||
; 32 bits install
|
||||
Source: "{#OSGInstallDir}\bin\osg{#OSGSoNumber}-osg.dll"; DestDir: "{app}\bin"; Check: not Is64BitInstallMode
|
||||
@@ -209,16 +191,16 @@ Name: "{userdocs}\FlightGear\TerraSync"; Permissions: everyone-modify; Check: no
|
||||
Name: "{userdocs}\FlightGear\Custom Scenery"; Permissions: everyone-modify; Check: not DirExists(ExpandConstant('{userdocs}\FlightGear\Custom Scenery'))
|
||||
|
||||
[Icons]
|
||||
Name: "{userdesktop}\FlightGear {#FGVersion}"; Filename: "{app}\bin\fgrun.exe"; WorkingDir: "{app}"; Tasks: desktopicon;
|
||||
Name: "{group}\FlightGear Launcher"; Filename: "{app}\bin\fgrun.exe"; WorkingDir: "{app}";
|
||||
Name: "{userdesktop}\FlightGear {#FGVersion}"; Filename: "{app}\bin\fgfs.exe"; Parameters: "--launcher"; WorkingDir: "{app}\bin"; Tasks: desktopicon;
|
||||
Name: "{group}\FlightGear"; Filename: "{app}\bin\fgfs.exe"; Parameters: "--launcher"; WorkingDir: "{app}\bin";
|
||||
Name: "{group}\FlightGear Manual"; Filename: "{app}\data\Docs\getstart.pdf"
|
||||
Name: "{group}\FlightGear Documentation"; Filename: "{app}\data\Docs\index.html"
|
||||
Name: "{group}\Flightgear Wiki"; Filename: "http://wiki.flightgear.org"
|
||||
Name: "{group}\Tools\FGRun"; Filename: "{app}\bin\fgrun.exe"; WorkingDir: "{app}";
|
||||
Name: "{group}\Tools\Install & Uninstall Scenery"; Filename: "{app}\bin\fgadmin.exe"; WorkingDir: "{app}"
|
||||
Name: "{group}\Tools\TerraSync"; Filename: "{app}\bin\terrasync.exe"; Parameters: "-S -p 5505 -d ""{userdocs}\FlightGear\TerraSync"""; WorkingDir: "{app}"
|
||||
Name: "{group}\Tools\Uninstall FlightGear"; Filename: "{uninstallexe}"
|
||||
Name: "{group}\Tools\js_demo"; Filename: "{app}\bin\js_demo.exe"
|
||||
Name: "{group}\Tools\fgjs"; Filename: "cmd"; Parameters: "/k fgjs.exe ""--fg-root={app}\data"""; WorkingDir: "{app}\bin"
|
||||
Name: "{group}\Tools\fgjs"; Filename: "cmd"; Parameters: "/k fgjs.exe ""--fg-root={app}\fgdata"""; WorkingDir: "{app}\bin"
|
||||
Name: "{group}\Tools\GPSsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\GPSsmooth.exe"" -h"; WorkingDir: "{app}\bin"
|
||||
Name: "{group}\Tools\UGsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\UGsmooth.exe"" -h"; WorkingDir: "{app}\bin"
|
||||
Name: "{group}\Tools\MIDGsmooth"; Filename: "cmd"; Parameters: "/k ""{app}\bin\MIDGsmooth.exe"" -h"; WorkingDir: "{app}\bin"
|
||||
@@ -236,7 +218,7 @@ filename: "{app}\bin\vcredist_x86.exe"; WorkingDir: "{app}\bin"; Parameters: "/p
|
||||
filename: "{app}\bin\vcredist_x64.exe"; WorkingDir: "{app}\bin"; Parameters: "/passive /norestart"; Description: "Installing MS Visual C++ runtime components"; Check: Is64BitInstallMode and FileExists(ExpandConstant('{app}\bin\vcredist_x64.exe'))
|
||||
filename: "{app}\bin\oalinst.exe"; WorkingDir: "{app}\bin"; Description: "Installing OpenAL"; Check: IsTaskSelected('insoal') and FileExists(ExpandConstant('{app}\bin\oalinst.exe'))
|
||||
; Put installation directory into the fgrun.prefs
|
||||
filename: "{app}\bin\fgrun.exe"; WorkingDir: "{app}\bin"; Parameters: "--silent ""--fg-exe={app}\bin\fgfs.exe"" ""--fg-root={app}\data"" ""--fg-scenery={userdocs}\FlightGear\Custom Scenery;{app}\data\Scenery;{userdocs}\FlightGear\TerraSync"" ""--fg-aircraft={userdocs}\FlightGear\Aircraft"" ""--terrasync-dir={userdocs}\FlightGear\TerraSync"" --version={#FGVersion}"
|
||||
filename: "{app}\bin\fgrun.exe"; WorkingDir: "{app}\bin"; Parameters: "--silent ""--fg-exe={app}\bin\fgfs.exe"" ""--fg-root={app}\data"" ""--fg-scenery={userdocs}\FlightGear\Custom Scenery;{app}\fgdata\Scenery;{userdocs}\FlightGear\TerraSync"" ""--fg-aircraft={userdocs}\FlightGear\Aircraft"" ""--terrasync-dir={userdocs}\FlightGear\TerraSync"" --version={#FGVersion}"
|
||||
; Put installation and source directories into the fgadmin.prefs
|
||||
filename: "{app}\bin\fgadmin.exe"; WorkingDir: "{app}\bin"; Parameters: "--silent ""--install-source={src}\..\Scenery"" ""--scenery-dest={userdocs}\FlightGear\Custom Scenery"""
|
||||
|
||||
|
||||
@@ -14,8 +14,4 @@
|
||||
+ /Aircraft/SenecaII
|
||||
+ /Aircraft/A6M2
|
||||
- /Aircraft/*
|
||||
+ /Models
|
||||
+ /Scenery
|
||||
+ /AI
|
||||
- /*
|
||||
|
||||
- .svn
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
- .git
|
||||
- *.xcf
|
||||
- *.tex
|
||||
- .svn
|
||||
|
||||
- /fgdata/Textures/Unused
|
||||
- /fgdata/Textures/*.orig
|
||||
- /fgdata/Docs/source
|
||||
- /fgdata/Models/Airspace
|
||||
- /fgdata/Models/MNUAV
|
||||
|
||||
|
||||
|
||||
@@ -9,13 +9,12 @@ VERSION=`cat flightgear/version`
|
||||
|
||||
#####################################################################################
|
||||
# remove old and create fresh build directories
|
||||
rm -rf sgBuild
|
||||
rm -rf fgBuild
|
||||
cd $WORKSPACE
|
||||
mkdir -p sgBuild
|
||||
mkdir -p fgBuild
|
||||
mkdir -p output
|
||||
rm -rf output/*
|
||||
rm -rf $WORKSPACE/dist/include/simgear $WORKSPACE/dist/libSim* $WORKSPACE/dist/libsg*.a
|
||||
rm -rf dist/*
|
||||
|
||||
#####################################################################################
|
||||
echo "Starting on SimGear"
|
||||
@@ -72,10 +71,10 @@ rsync -a --delete \
|
||||
--filter 'merge base-package.rules' \
|
||||
fgdata base_package
|
||||
|
||||
echo "Syncing extended data"
|
||||
rsync -a --filter 'merge aircraft.rules' /home/jenkins/fgdata_340/ extended-data
|
||||
echo "Syncing aircraft data"
|
||||
rsync -a --delete --filter 'merge aircraft.rules' /home/jenkins/fgaddon-3.6.0/ extended-data
|
||||
|
||||
echo "Copying extended data"
|
||||
echo "Copying aircraft data"
|
||||
rsync -a extended-data/ base_package/fgdata
|
||||
|
||||
echo "Creating tar archive"
|
||||
0
build_release_mac.sh
Executable file
0
build_release_mac.sh
Executable file
142
build_release_windows.bat
Executable file
142
build_release_windows.bat
Executable file
@@ -0,0 +1,142 @@
|
||||
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
|
||||
REM 32bits
|
||||
md build-sg32
|
||||
md build-fg32
|
||||
md build-fgrun32
|
||||
cd build-sg32
|
||||
cmake ..\simgear -G "Visual Studio 10" ^
|
||||
-DMSVC_3RDPARTY_ROOT=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/SimGear ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fg32
|
||||
cmake ..\flightgear -G "Visual Studio 10" ^
|
||||
-DMSVC_3RDPARTY_ROOT=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FlightGear ^
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK32% ^
|
||||
-DPNG_LIBRARY=%WORKSPACE%/3rdParty/lib/libpng16.lib ^
|
||||
-DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fgrun32
|
||||
cmake ..\fgrun -G "Visual Studio 10" ^
|
||||
-DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FGRun ^
|
||||
-DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe ^
|
||||
-DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe ^
|
||||
-DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..
|
||||
|
||||
REM 64 bits
|
||||
md build-sg64
|
||||
md build-fg64
|
||||
md build-fgrun64
|
||||
cd build-sg64
|
||||
cmake ..\SimGear -G "Visual Studio 10 Win64" ^
|
||||
-DMSVC_3RDPARTY_ROOT=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/SimGear ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fg64
|
||||
cmake ..\flightgear -G "Visual Studio 10 Win64" ^
|
||||
-DMSVC_3RDPARTY_ROOT=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FlightGear ^
|
||||
-DCMAKE_PREFIX_PATH=%QT5SDK64% ^
|
||||
-DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost ^
|
||||
-DWITH_FGPANEL=OFF ^
|
||||
-DENABLE_PROFILE=OFF
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fgrun64
|
||||
cmake ..\fgrun -G "Visual Studio 10 Win64" ^
|
||||
-DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% ^
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FGRun ^
|
||||
-DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe ^
|
||||
-DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe ^
|
||||
-DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe ^
|
||||
-DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..
|
||||
|
||||
REM Qt5 deployment
|
||||
%QT5SDK32%\bin\windeployqt --release --list target %WORKSPACE%/install/msvc100/FlightGear/bin/fgfs.exe
|
||||
%QT5SDK64%\bin\windeployqt --release --list target %WORKSPACE%/install/msvc100-64/FlightGear/bin/fgfs.exe
|
||||
|
||||
REM build setup
|
||||
ECHO Packaging root is %WORKSPACE%
|
||||
|
||||
subst X: /D
|
||||
subst X: %WORKSPACE%.
|
||||
|
||||
REM ensure output dir is clean since we upload the entirety of it
|
||||
rmdir /S /Q output
|
||||
|
||||
REM archiving PDB files
|
||||
copy %WORKSPACE%\build-fg32\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x86-%BUILD_NUMBER%.pdb
|
||||
copy %WORKSPACE%\build-fg64\src\Main\RelWithDebInfo\fgfs.pdb %WORKSPACE%\Output\fgfs-x64-%BUILD_NUMBER%.pdb
|
||||
|
||||
REM indirect way to get command output into an environment variable
|
||||
set PATH=%WORKSPACE%\install\msvc100\OpenSceneGraph\bin;%PATH%
|
||||
osgversion --so-number > %TEMP%\osg-so-number.txt
|
||||
osgversion --version-number > %TEMP%\osg-version.txt
|
||||
osgversion --openthreads-soversion-number > %TEMP%\openthreads-so-number.txt
|
||||
|
||||
SET /P FLIGHTGEAR_VERSION=<flightgear\version
|
||||
SET /P OSG_VERSION=<%TEMP%\osg-version.txt
|
||||
SET /P OSG_SO_NUMBER=<%TEMP%\osg-so-number.txt
|
||||
SET /P OT_SO_NUMBER=<%TEMP%\openthreads-so-number.txt
|
||||
|
||||
IF %IS_NIGHTLY_BUILD% EQU 1 (
|
||||
REM FlightGear nightly: with fgdata, output filename would be "FlightGear-x.x.x-nightly-full.exe"
|
||||
CALL :writeBaseConfig
|
||||
CALL :writeNightlyFullConfig
|
||||
iscc FlightGear.iss
|
||||
|
||||
REM FlightGear nightly: without fgdata, output filename would be "FlightGear-x.x.x-nightly.exe"
|
||||
CALL :writeBaseConfig
|
||||
CALL :writeNightlyDietConfig
|
||||
iscc FlightGear.iss
|
||||
) ELSE (
|
||||
REM FlightGear release: with fgdata, output filename would be "FlightGear-x.x.x.exe"
|
||||
CALL :writeBaseConfig
|
||||
CALL :writeReleaseConfig
|
||||
iscc FlightGear.iss
|
||||
)
|
||||
GOTO End
|
||||
|
||||
:writeBaseConfig
|
||||
ECHO #define FGVersion "%FLIGHTGEAR_VERSION%" > InstallConfig.iss
|
||||
ECHO #define OSGVersion "%OSG_VERSION%" >> InstallConfig.iss
|
||||
ECHO #define OSGSoNumber "%OSG_SO_NUMBER%" >> InstallConfig.iss
|
||||
ECHO #define OTSoNumber "%OT_SO_NUMBER%" >> InstallConfig.iss
|
||||
GOTO End
|
||||
|
||||
:writeReleaseConfig
|
||||
CALL :writeBaseConfig
|
||||
ECHO #define FGDetails "" >> InstallConfig.iss
|
||||
ECHO #define IncludeData "TRUE" >> InstallConfig.iss
|
||||
GOTO End
|
||||
|
||||
:writeNightlyFullConfig
|
||||
CALL :writeBaseConfig
|
||||
ECHO #define FGDetails "-nightly-full" >> InstallConfig.iss
|
||||
ECHO #define IncludeData "TRUE" >> InstallConfig.iss
|
||||
GOTO End
|
||||
|
||||
:writeNightlyDietConfig
|
||||
CALL :writeBaseConfig
|
||||
ECHO #define FGDetails "-nightly" >> InstallConfig.iss
|
||||
ECHO #define IncludeData "FALSE" >> InstallConfig.iss
|
||||
GOTO End
|
||||
|
||||
:End
|
||||
@@ -1,12 +1,13 @@
|
||||
aircraftTypeTags = [
|
||||
"ga", "fighter", "helicopter", "glider", "spaceship", "bomber", "groundvehicle",
|
||||
"ga", "fighter", "helicopter", "glider", "spaceship", "bomber", "groundvehicle",
|
||||
"tanker", "cargo", "transport", "bizjet", "trainer", "airship", "balloon"
|
||||
]
|
||||
|
||||
manufacturerTags = [
|
||||
"boeing", "cessna", "diamond", "douglas", "bell", "piper",
|
||||
"boeing", "cessna", "diamond", "douglas", "bell", "piper",
|
||||
"airbus", "vickers", "lockheed", "fokker",
|
||||
"embrarer", "bombardier", "pilatus", "robin"
|
||||
"embrarer", "bombardier", "pilatus", "robin",
|
||||
"eurocopter"
|
||||
]
|
||||
|
||||
eraTags = [
|
||||
@@ -21,6 +22,8 @@ eraTags = [
|
||||
"1960s",
|
||||
"1970s",
|
||||
"1980s",
|
||||
"1990s",
|
||||
"2000s",
|
||||
"gulfwar1",
|
||||
"gulfwar2"
|
||||
]
|
||||
@@ -69,7 +72,8 @@ propulsionTags = [
|
||||
|
||||
simFeatureTags = [
|
||||
"tow",
|
||||
"dual-controls"
|
||||
"dual-controls",
|
||||
"rembrandt"
|
||||
]
|
||||
|
||||
tags = aircraftTypeTags + manufacturerTags + eraTags + simFeatureTags + propulsionTags + featureTags
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2
fgdata
2
fgdata
Submodule fgdata updated: 90dcec50e2...d01b9bb1c7
2
fgrun
2
fgrun
Submodule fgrun updated: 9357de19f0...c67c2ee07a
Submodule flightgear updated: 94c7479408...38e5a2a0eb
40
git_catalog_repository.py
Normal file
40
git_catalog_repository.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# git diff --quiet e5f841bc84d31fee339191a59b8746cb4eb8074c -- ./Aircraft/
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
class GITCatalogRepository:
|
||||
def __init__(self, path, usesSubmodules = False, singleAircraft = False):
|
||||
self._path = path
|
||||
|
||||
if not os.path.exists(os.path.join(path, ".git")):
|
||||
raise RuntimeError("not a Git directory:" + path)
|
||||
|
||||
self._usesSubmodules = usesSubmodules
|
||||
self._singleAircraft = singleAircraft
|
||||
|
||||
self._currentRevision = subprocess.catch_output(["git", "rev-parse", "HEAD"],
|
||||
cwd = self._path)
|
||||
|
||||
def hasPathChanged(self, path, oldRev):
|
||||
diffArgs = ["git", "diff", "--quiet", oldRev, "--"]
|
||||
if not (self._usesSubmodules and self._singleAircraft):
|
||||
diffArgs.append(path)
|
||||
|
||||
return subprocess.call(diffArgs, cwd = self._path)
|
||||
|
||||
def update(self):
|
||||
subprocess.call(["git", "pull"])
|
||||
self._currentRevision = subprocess.catch_output(["git", "rev-parse", "HEAD"],
|
||||
cwd = self._path)
|
||||
|
||||
if self._usesSubmodules:
|
||||
subprocess.call(["git", "submodule", "update"], cwd = self._path)
|
||||
|
||||
def scmRevisionForPath(self, path):
|
||||
if self._usesSubmodules:
|
||||
return subprocess.catch_output(["git", "rev-parse", "HEAD"], cwd = self._path)
|
||||
|
||||
return self._currentRevision
|
||||
|
||||
|
||||
34
git_discrete_repository.py
Normal file
34
git_discrete_repository.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# git diff --quiet e5f841bc84d31fee339191a59b8746cb4eb8074c -- ./Aircraft/
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sgprops
|
||||
|
||||
import git_catalog_repository
|
||||
|
||||
class GitDiscreteSCM:
|
||||
def __init__(self, node):
|
||||
|
||||
configNode = node.parent
|
||||
|
||||
self._repos = {}
|
||||
|
||||
# iterate over aicraft paths finding repositories
|
||||
for g in config.getChildren("aircraft-dir"):
|
||||
repo = GITCatalogRepository(g, useSubmodules = False,
|
||||
singleAircraft = True)
|
||||
|
||||
|
||||
def hasPathChanged(self, path, oldRev):
|
||||
|
||||
return self._repos[path].hasPathChanged(path, oldRev)
|
||||
|
||||
def update(self):
|
||||
for r in self._repos:
|
||||
r.update()
|
||||
|
||||
def scmRevisionForPath(self, path):
|
||||
return self._repos[path].scmRevisionForPath(path)
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ popd
|
||||
################################################################################
|
||||
echo "Starting on FlightGear"
|
||||
pushd fgBuild
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -DENABLE_QT=1 -G Xcode ../flightgear
|
||||
cmake -DFG_NIGHTLY=1 -DCMAKE_INSTALL_PREFIX:PATH=$WORKSPACE/dist -G Xcode ../flightgear
|
||||
|
||||
xcodebuild -configuration RelWithDebInfo -target install build
|
||||
|
||||
@@ -46,7 +46,9 @@ popd
|
||||
|
||||
chmod +x $WORKSPACE/dist/bin/osgversion
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
# run the unlock script now - we need to do this right before code-signing,
|
||||
# or the keychain may automatically re-lock after some period of time
|
||||
unlock-keychain.sh
|
||||
|
||||
@@ -7,6 +7,19 @@ include FileUtils
|
||||
$osgLibs = ['osgFX', 'osgParticle', 'osg', 'osgGA', 'osgText', 'osgUtil', 'osgSim', 'osgViewer', 'osgDB']
|
||||
$osgPlugins = ['ac', 'osg', 'freetype', 'imageio', 'rgb', 'txf', 'mdl', '3ds']
|
||||
|
||||
# from http://drawingablank.me/blog/ruby-boolean-typecasting.html
|
||||
class String
|
||||
def to_bool
|
||||
return true if self == true || self =~ (/^(true|t|yes|y|1)$/i)
|
||||
return false if self == false || self.blank? || self =~ (/^(false|f|no|n|0)$/i)
|
||||
raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
|
||||
end
|
||||
end
|
||||
|
||||
class NilClass
|
||||
def to_bool; false; end
|
||||
end
|
||||
|
||||
def runOsgVersion(option)
|
||||
env = "export DYLD_LIBRARY_PATH=#{Dir.pwd}/dist/lib"
|
||||
bin = Dir.pwd + "/dist/bin/osgversion"
|
||||
@@ -19,22 +32,10 @@ $openThreadsSoVersion=runOsgVersion('openthreads-soversion-number')
|
||||
|
||||
$codeSignIdentity = ENV['FG_CODESIGN_IDENTITY']
|
||||
puts "Code signing identity is #{$codeSignIdentity}"
|
||||
|
||||
puts "osgVersion=#{osgVersion}, so-number=#{$osgSoVersion}"
|
||||
|
||||
def fix_install_names(object)
|
||||
#puts "fixing install names for #{object}"
|
||||
|
||||
$osgLibs.each do |l|
|
||||
oldName = "lib#{l}.#{$osgSoVersion}.dylib"
|
||||
newName = "@executable_path/../Frameworks/#{oldName}"
|
||||
`install_name_tool -change #{oldName} #{newName} #{object}`
|
||||
end
|
||||
|
||||
oldName = "libOpenThreads.#{$openThreadsSoVersion}.dylib"
|
||||
newName= "@executable_path/../Frameworks/#{oldName}"
|
||||
`install_name_tool -change #{oldName} #{newName} #{object}`
|
||||
end
|
||||
$isRelease = ENV['FG_IS_RELEASE'].to_bool
|
||||
puts "Is-release? : ##{$isRelease}"
|
||||
|
||||
$prefixDir=Dir.pwd + "/dist"
|
||||
dmgDir=Dir.pwd + "/image"
|
||||
@@ -68,7 +69,13 @@ fgCurrentYear = t.year
|
||||
fgVersion = File.read("#{srcDir}/version").strip
|
||||
volName="\"FlightGear #{fgVersion}\""
|
||||
|
||||
dmgPath = Dir.pwd + "/output/FlightGear-#{fgVersion}.dmg"
|
||||
if $isRelease
|
||||
dmgPath = "" # no 'lite' build for release candidates
|
||||
dmgFullPath = Dir.pwd + "/output/FlightGear-#{fgVersion}.dmg"
|
||||
else
|
||||
dmgPath = Dir.pwd + "/output/FlightGear-#{fgVersion}-nightly.dmg"
|
||||
dmgFullPath = Dir.pwd + "/output/FlightGear-#{fgVersion}-nightly-full.dmg"
|
||||
end
|
||||
|
||||
puts "Creating directory structure"
|
||||
`mkdir -p #{macosDir}`
|
||||
@@ -76,8 +83,6 @@ puts "Creating directory structure"
|
||||
`mkdir -p #{resourcesDir}`
|
||||
`mkdir -p #{osgPluginsDir}`
|
||||
|
||||
# fix install names on the primary executable
|
||||
fix_install_names("#{macosDir}/fgfs")
|
||||
|
||||
puts "Copying auxilliary binaries"
|
||||
bins = ['fgjs', 'fgcom']
|
||||
@@ -88,14 +93,12 @@ bins.each do |b|
|
||||
|
||||
outPath = "#{macosDir}/#{b}"
|
||||
`cp #{$prefixDir}/bin/#{b} #{outPath}`
|
||||
fix_install_names(outPath)
|
||||
end
|
||||
|
||||
puts "copying libraries"
|
||||
$osgLibs.each do |l|
|
||||
libFile = "lib#{l}.#{$osgSoVersion}.dylib"
|
||||
`cp #{$prefixDir}/lib/#{libFile} #{$frameworksDir}`
|
||||
fix_install_names("#{$frameworksDir}/#{libFile}")
|
||||
end
|
||||
|
||||
# and not forgetting OpenThreads
|
||||
@@ -105,7 +108,6 @@ libFile = "libOpenThreads.#{$openThreadsSoVersion}.dylib"
|
||||
$osgPlugins.each do |p|
|
||||
pluginFile = "osgdb_#{p}.dylib"
|
||||
`cp #{$prefixDir}/lib/osgPlugins/#{pluginFile} #{osgPluginsDir}`
|
||||
fix_install_names("#{osgPluginsDir}/#{pluginFile}")
|
||||
end
|
||||
|
||||
if File.exist?("#{$prefixDir}/bin/fgcom-data")
|
||||
@@ -125,22 +127,34 @@ File.open("#{contents}/Info.plist", 'w') { |f|
|
||||
`cp #{srcDir}/COPYING #{dmgDir}`
|
||||
|
||||
# move documentation to a public place
|
||||
`mv fgdata/Docs/FGShortRef.pdf "#{dmgDir}/Quick Reference.pdf"`
|
||||
`mv fgdata/Docs/getstart.pdf "#{dmgDir}/Getting Started.pdf"`
|
||||
|
||||
puts "Copying base package files into the image"
|
||||
`rsync -a --filter 'merge base-package.rules' fgdata/ #{resourcesDir}/data`
|
||||
|
||||
# work-around for 3.4.1: copy aircraft/scenery files too
|
||||
`rsync -a extended-data/ #{resourcesDir}/data`
|
||||
|
||||
# code sign the entire bundle once complete - v2 code-signing
|
||||
puts "Signing #{bundle}"
|
||||
`codesign --deep -s "#{$codeSignIdentity}" #{bundle}`
|
||||
|
||||
puts "Creating DMG"
|
||||
`cp fgdata/Docs/FGShortRef.pdf "#{dmgDir}/Quick Reference.pdf"`
|
||||
`cp fgdata/Docs/getstart.pdf "#{dmgDir}/Getting Started.pdf"`
|
||||
|
||||
createArgs = "-format UDBZ -imagekey bzip2-level=9 -quiet -volname #{volName}"
|
||||
|
||||
`rm #{dmgPath}`
|
||||
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgPath}`
|
||||
# work-around for 3.6: copy aircraft files too
|
||||
`rsync -a extended-data/ #{resourcesDir}/data`
|
||||
|
||||
if !$isRelease
|
||||
# create the 'lite' DMG without the base files
|
||||
|
||||
# code sign the entire bundle once complete - v2 code-signing
|
||||
puts "Signing #{bundle}"
|
||||
`codesign --deep -s "#{$codeSignIdentity}" #{bundle}`
|
||||
puts "Creating DMG"
|
||||
|
||||
`rm #{dmgPath}`
|
||||
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgPath}`
|
||||
end
|
||||
|
||||
puts "Creating full image with data"
|
||||
|
||||
puts "Copying base package files into the image"
|
||||
`rsync -a fgdata/ #{resourcesDir}/data`
|
||||
|
||||
# re-sign the entire bundle
|
||||
puts "Re-signing full #{bundle}"
|
||||
`codesign --force --deep -s "#{$codeSignIdentity}" #{bundle}`
|
||||
|
||||
`rm #{dmgFullPath}`
|
||||
`hdiutil create -srcfolder #{dmgDir} #{createArgs} #{dmgFullPath}`
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
|
||||
SET /P SIMGEAR_VERSION=<%WORKSPACE%\simgear\version
|
||||
ECHO #define SIMGEAR_VERSION "%SIMGEAR_VERSION%" > %WORKSPACE%\simgear\simgear\version.h
|
||||
|
||||
rem set PATH=%PATH%;D:\Program Files (x86)\CMake 2.8\bin
|
||||
rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
|
||||
|
||||
md build-sg
|
||||
md build-fg
|
||||
md build-fgrun
|
||||
cd build-sg
|
||||
cmake ..\simgear -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/SimGear -DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fg
|
||||
cmake ..\flightgear -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FlightGear -DPNG_LIBRARY=%WORKSPACE%/3rdParty/lib/libpng16.lib -DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe -DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fgrun
|
||||
cmake ..\fgrun -G "Visual Studio 10" -DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100/FGRun -DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe -DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
@@ -1,24 +0,0 @@
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
|
||||
|
||||
SET /P SIMGEAR_VERSION=<%WORKSPACE%\simgear\version
|
||||
ECHO #define SIMGEAR_VERSION "%SIMGEAR_VERSION%" > %WORKSPACE%\simgear\simgear\version.h
|
||||
|
||||
rem ECHO #define SIMGEAR_VERSION "2.9.0" > %WORKSPACE%\simgear\simgear\version.h
|
||||
rem set PATH=%PATH%;D:\Program Files (x86)\CMake 2.8\bin
|
||||
rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64
|
||||
|
||||
md build-sg64
|
||||
md build-fg64
|
||||
md build-fgrun64
|
||||
cd build-sg64
|
||||
cmake ..\SimGear -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/SimGear -DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fg64
|
||||
cmake ..\flightgear -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FlightGear -DFLTK_FLUID_EXECUTABLE=%WORKSPACE%/3rdParty/bin/fluid.exe -DBOOST_ROOT=%WORKSPACE%/Boost -DWITH_FGPANEL=OFF -DENABLE_PROFILE=OFF
|
||||
cmake --build . --config Release --target INSTALL
|
||||
|
||||
cd ..\build-fgrun64
|
||||
cmake ..\fgrun -G "Visual Studio 10 Win64" -DMSVC_3RDPARTY_ROOT:PATH=%WORKSPACE% -DCMAKE_INSTALL_PREFIX:PATH=%WORKSPACE%/install/msvc100-64/FGRun -DFLTK_FLUID_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/fluid.exe -DGETTEXT_MSGFMT_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgfmt.exe -DGETTEXT_MSGMERGE_EXECUTABLE:FILEPATH=%WORKSPACE%/3rdParty/bin/msgmerge.exe -DBOOST_ROOT=%WORKSPACE%/Boost
|
||||
cmake --build . --config Release --target INSTALL
|
||||
@@ -1,39 +0,0 @@
|
||||
ECHO OFF
|
||||
|
||||
IF NOT DEFINED WORKSPACE SET WORKSPACE=%~dp0
|
||||
ECHO Packaging root is %WORKSPACE%
|
||||
|
||||
subst X: /D
|
||||
subst X: %WORKSPACE%.
|
||||
|
||||
REM construct information file to be read by Inno-setup
|
||||
|
||||
|
||||
set PATH=%WORKSPACE%\install\msvc100\OpenSceneGraph\bin;%PATH%
|
||||
|
||||
REM add 7-zip to the PATH
|
||||
set PATH=%PATH%;C:\Program Files\7-zip
|
||||
|
||||
REM indirect way to get command output into an environment variable
|
||||
osgversion --so-number > %TEMP%\osg-so-number.txt
|
||||
osgversion --version-number > %TEMP%\osg-version.txt
|
||||
osgversion --openthreads-soversion-number > %TEMP%\openthreads-so-number.txt
|
||||
|
||||
SET /P FLIGHTGEAR_VERSION=<flightgear\version
|
||||
SET /P OSG_VERSION=<%TEMP%\osg-version.txt
|
||||
SET /P OSG_SO_NUMBER=<%TEMP%\osg-so-number.txt
|
||||
SET /P OT_SO_NUMBER=<%TEMP%\openthreads-so-number.txt
|
||||
|
||||
ECHO #define FGVersion "%FLIGHTGEAR_VERSION%" > InstallConfig.iss
|
||||
ECHO #define OSGVersion "%OSG_VERSION%" >> InstallConfig.iss
|
||||
ECHO #define OSGSoNumber "%OSG_SO_NUMBER%" >> InstallConfig.iss
|
||||
ECHO #define OTSoNumber "%OT_SO_NUMBER%" >> InstallConfig.iss
|
||||
|
||||
REM set DATA_FILE=FlightGear-%FLIGHTGEAR_VERSION%-data
|
||||
REM extract the data files
|
||||
REM 7z e -aoa %DATA_FILE%.tar.bz2 && 7z x -aoa %DATA_FILE%.tar
|
||||
|
||||
REM run Inno-setup!
|
||||
REM use iscc instead of compil32 for better error reporting
|
||||
|
||||
iscc FlightGear.iss
|
||||
@@ -1,6 +1,7 @@
|
||||
REM ExternalProject can't cleanly extract a zip into an existing directory
|
||||
REM Instead we extract to a subdir, and then move the directories we want
|
||||
REM using this bat file.
|
||||
REM This script is used by the SuperBuild CMakeLists.txt
|
||||
|
||||
echo %CD%
|
||||
IF EXIST winDeps/3rdParty (
|
||||
|
||||
394
maintain_catalog.py
Executable file
394
maintain_catalog.py
Executable file
@@ -0,0 +1,394 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os, sys, re, glob
|
||||
import hashlib # for MD5
|
||||
import subprocess
|
||||
import shutil # for copy2
|
||||
import catalogTags
|
||||
import sgprops
|
||||
#from multiprocessing import Pool
|
||||
import argparse
|
||||
import urllib2
|
||||
|
||||
import svn_catalog_repository
|
||||
import git_catalog_repository
|
||||
import git_discrete_repository
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--clean", help="Regenerate every package", type=bool)
|
||||
parser.add_argument("dir", help="Catalog directory")
|
||||
args = parser.parse_args()
|
||||
|
||||
standardTagSet = frozenset(catalogTags.tags)
|
||||
def isNonstandardTag(t):
|
||||
return t not in standardTagSet
|
||||
|
||||
thumbnailNames = ["thumbnail.png", "thumbnail.jpg"]
|
||||
includePaths = []
|
||||
|
||||
class VariantData:
|
||||
def __init__(self, path, node):
|
||||
#self._primary = primary
|
||||
self._path = path
|
||||
self._name = node.getValue("sim/description")
|
||||
|
||||
# ratings
|
||||
|
||||
# seperate thumbnails
|
||||
|
||||
@property
|
||||
def catalogNode(self):
|
||||
n = sgprops.Node("variant")
|
||||
n.addChild("id").value = self._path
|
||||
n.addChild("name").value = self._name
|
||||
|
||||
class PackageData:
|
||||
def __init__(self, path):
|
||||
self._path = path
|
||||
self._previousSCMRevision = None
|
||||
self._previousRevision = 0
|
||||
self._thumbnails = []
|
||||
self._variants = {}
|
||||
self._revision = 0
|
||||
self._md5 = None
|
||||
self._fileSize = 0
|
||||
|
||||
self._node = sgprops.Node("package")
|
||||
self._node.addChild("id").value = self.id
|
||||
|
||||
def setPreviousData(self, node):
|
||||
self._previousRevision = node.getValue("revision")
|
||||
self._previousMD5 = node.getValue("md5")
|
||||
self._previousSCMRevision = node.getValue("scm-revision")
|
||||
self._fileSize = int(node.getValue("file-size-bytes"))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return os.path.basename(self._path)
|
||||
|
||||
@property
|
||||
def thumbnails(self):
|
||||
return self._thumbnails
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
@property
|
||||
def variants(self):
|
||||
return self._variants
|
||||
|
||||
@property
|
||||
def scmRevision(self):
|
||||
currentRev = scmRepo.scmRevisionForPath(self._path)
|
||||
if (currentRev is None):
|
||||
raise RuntimeError("Unable to query SCM revision of files")
|
||||
|
||||
return currentRev
|
||||
|
||||
def isSourceModified(self, scmRepo):
|
||||
if (self._previousSCMRevision == None):
|
||||
return True
|
||||
|
||||
if (self._previousSCMRevision == self.scmRevision):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def scanSetXmlFiles(self, includes):
|
||||
foundPrimary = False
|
||||
foundMultiple = False
|
||||
|
||||
for f in os.listdir(self._path):
|
||||
if not f.endswith("-set.xml"):
|
||||
continue
|
||||
|
||||
p = os.path.join(self._path, f)
|
||||
node = sgprops.readProps(p, includePaths = includes)
|
||||
if not node.hasChild("sim"):
|
||||
continue
|
||||
|
||||
simNode = node.getChild("sim")
|
||||
if (simNode.getValue("exclude", False)):
|
||||
continue
|
||||
|
||||
primary = simNode.getValue("variant-of", None)
|
||||
if primary:
|
||||
if not primary in self.variants:
|
||||
self._variants[primary] = []
|
||||
self._variants[primary].append(VariantData(self, node))
|
||||
continue
|
||||
|
||||
if foundPrimary:
|
||||
if not foundMultiple:
|
||||
print "Multiple primary -set.xml files at:" + self._path
|
||||
foundMultiple = True
|
||||
continue
|
||||
else:
|
||||
foundPrimary = True;
|
||||
|
||||
self.parsePrimarySetNode(simNode)
|
||||
|
||||
for n in thumbnailNames:
|
||||
if os.path.exists(os.path.join(self._path, n)):
|
||||
self._thumbnails.append(n)
|
||||
|
||||
if not foundPrimary:
|
||||
raise RuntimeError("No primary -set.xml found at:" + self._path)
|
||||
|
||||
|
||||
|
||||
def parsePrimarySetNode(self, sim):
|
||||
|
||||
# basic / mandatory values
|
||||
self._node.addChild('name').value = sim.getValue('description')
|
||||
|
||||
longDesc = sim.getValue('long-description')
|
||||
if longDesc is not None:
|
||||
self._node.addChild('description').value = longDesc
|
||||
|
||||
# copy all the standard values
|
||||
for p in ['status', 'author', 'license']:
|
||||
v = sim.getValue(p)
|
||||
if v is not None:
|
||||
self._node.addChild(p).value = v
|
||||
|
||||
# ratings
|
||||
if sim.hasChild('rating'):
|
||||
pkgRatings = self._node.addChild('rating')
|
||||
for r in ['FDM', 'systems', 'cockpit', 'model']:
|
||||
pkgRatings.addChild(r).value = sim.getValue('rating/' + r, 0)
|
||||
|
||||
# copy tags
|
||||
if sim.hasChild('tags'):
|
||||
for c in sim.getChild('tags').getChildren('tag'):
|
||||
if isNonstandardTag(c.value):
|
||||
print "Skipping non-standard tag:", c.value, self.path
|
||||
else:
|
||||
self._node.addChild('tag').value = c.value
|
||||
|
||||
for t in sim.getChildren("thumbnail"):
|
||||
self._thumbnails.append(t.value)
|
||||
|
||||
def validate(self):
|
||||
for t in self._thumbnails:
|
||||
if not os.path.exists(os.path.join(self._path, t)):
|
||||
raise RuntimeError("missing thumbnail:" + t);
|
||||
|
||||
def generateZip(self, outDir):
|
||||
self._revision = self._previousRevision + 1
|
||||
|
||||
zipName = self.id + ".zip"
|
||||
zipFilePath = os.path.join(outDir, zipName)
|
||||
|
||||
os.chdir(os.path.dirname(self.path))
|
||||
|
||||
print "Creating zip", zipFilePath
|
||||
# TODO: exclude certain files
|
||||
# anything we can do to make this faster?
|
||||
subprocess.call(['zip', '--quiet', '-r', zipFilePath, self.id])
|
||||
|
||||
zipFile = open(zipFilePath, 'r')
|
||||
self._md5 = hashlib.md5(zipFile.read()).hexdigest()
|
||||
self._fileSize = os.path.getsize(zipFilePath)
|
||||
|
||||
def useExistingCatalogData(self):
|
||||
self._md5 = self._previousMD5
|
||||
|
||||
def packageNode(self, mirrorUrls, thumbnailUrl):
|
||||
self._node.getChild("md5", create = True).value = self._md5
|
||||
self._node.getChild("file-size-bytes", create = True).value = self._fileSize
|
||||
self._node.getChild("revision", create = True).value = int(self._revision)
|
||||
self._node.getChild("scm-revision", create = True).value = self.scmRevision
|
||||
|
||||
for m in mirrorUrls:
|
||||
self._node.addChild("url").value = m + "/" + self.id + ".zip"
|
||||
|
||||
for t in self._thumbnails:
|
||||
self._node.addChild("thumbnail").value = thumbnailUrl + "/" + self.id + "_" + t
|
||||
|
||||
for pr in self._variants:
|
||||
for vr in self._variants[pr]:
|
||||
self._node.addChild(vr.catalogNode)
|
||||
|
||||
return self._node
|
||||
|
||||
def extractThumbnails(self, thumbnailDir):
|
||||
for t in self._thumbnails:
|
||||
fullName = self.id + "_" + t
|
||||
shutil.copy2(os.path.join(self._path, t),
|
||||
os.path.join(thumbnailDir, fullName)
|
||||
)
|
||||
# TODO : verify image format, size and so on
|
||||
|
||||
def scanPackages(globPath):
|
||||
result = []
|
||||
print "Scanning", globPath
|
||||
print os.getcwd()
|
||||
for d in glob.glob(globPath):
|
||||
# check dir contains at least one -set.xml file
|
||||
if len(glob.glob(os.path.join(d, "*-set.xml"))) == 0:
|
||||
print "no -set.xml in", d
|
||||
continue
|
||||
|
||||
result.append(PackageData(d))
|
||||
|
||||
return result
|
||||
|
||||
def initScmRepository(node):
|
||||
scmType = node.getValue("type")
|
||||
if (scmType == "svn"):
|
||||
svnPath = node.getValue("path")
|
||||
return svn_catalog_repository.SVNCatalogRepository(svnPath)
|
||||
elif (scmType == "git"):
|
||||
gitPath = node.getValue("path")
|
||||
usesSubmodules = node.getValue("uses-submodules", False)
|
||||
return git_catalog_repository.GitCatalogRepository(gitPath, usesSubmodules)
|
||||
elif (scmType == "git-discrete"):
|
||||
return git_discrete_repository.GitDiscreteSCM(node)
|
||||
elif (scmType == None):
|
||||
raise RuntimeError("No scm/type defined in catalog configuration")
|
||||
else:
|
||||
raise RuntimeError("Unspported SCM type:" + scmType)
|
||||
|
||||
def processUpload(node, outputPath):
|
||||
if not node.getValue("enabled", True):
|
||||
print "Upload disabled"
|
||||
return
|
||||
|
||||
uploadType = node.getValue("type")
|
||||
if (uploadType == "rsync"):
|
||||
subprocess.call(["rsync", node.getValue("args", "-az"), ".",
|
||||
node.getValue("remote")],
|
||||
cwd = outputPath)
|
||||
elif (uploadType == "rsync-ssh"):
|
||||
subprocess.call(["rsync", node.getValue("args", "-azve"),
|
||||
"ssh", ".",
|
||||
node.getValue("remote")],
|
||||
cwd = outputPath)
|
||||
elif (uploadType == "scp"):
|
||||
subprocess.call(["scp", node.getValue("args", "-r"), ".",
|
||||
node.getValue("remote")],
|
||||
cwd = outputPath)
|
||||
else:
|
||||
raise RuntimeError("Unsupported upload type:" + uploadType)
|
||||
|
||||
# dictionary
|
||||
packages = {}
|
||||
|
||||
rootDir = args.dir
|
||||
if not os.path.isabs(rootDir):
|
||||
rootDir = os.path.abspath(rootDir)
|
||||
os.chdir(rootDir)
|
||||
|
||||
configPath = 'catalog.config.xml'
|
||||
if not os.path.exists(configPath):
|
||||
raise RuntimeError("no config file found at:" + configPath)
|
||||
|
||||
config = sgprops.readProps(configPath)
|
||||
|
||||
# out path
|
||||
outPath = config.getValue('output-dir')
|
||||
if outPath is None:
|
||||
# default out path
|
||||
outPath = os.path.join(rootDir, "output")
|
||||
elif not os.path.isabs(outPath):
|
||||
outPath = os.path.join(rootDir, "output")
|
||||
|
||||
if args.clean:
|
||||
print "Cleaning output"
|
||||
shutil.rmtree(outPath)
|
||||
|
||||
if not os.path.exists(outPath):
|
||||
os.mkdir(outPath)
|
||||
|
||||
thumbnailPath = os.path.join(outPath, config.getValue('thumbnail-dir', "thumbnails"))
|
||||
if not os.path.exists(thumbnailPath):
|
||||
os.mkdir(thumbnailPath)
|
||||
|
||||
thumbnailUrl = config.getValue('thumbnail-url')
|
||||
|
||||
for i in config.getChildren("include-dir"):
|
||||
if not os.path.exists(i.value):
|
||||
print "Skipping missing include path:", i.value
|
||||
continue
|
||||
includePaths.append(i.value)
|
||||
|
||||
mirrorUrls = []
|
||||
|
||||
# contains existing catalog
|
||||
existingCatalogPath = os.path.join(outPath, 'catalog.xml')
|
||||
|
||||
scmRepo = initScmRepository(config.getChild('scm'))
|
||||
|
||||
# scan the directories in the aircraft paths
|
||||
for g in config.getChildren("aircraft-dir"):
|
||||
for p in scanPackages(g.value):
|
||||
packages[p.id] = p
|
||||
|
||||
if not os.path.exists(existingCatalogPath):
|
||||
try:
|
||||
# can happen on new or from clean, try to pull current
|
||||
# catalog from the upload location
|
||||
response = urllib2.urlopen(config.getValue("template/url"), timeout = 5)
|
||||
content = response.read()
|
||||
f = open(existingCatalogPath, 'w' )
|
||||
f.write( content )
|
||||
f.close()
|
||||
except urllib2.URLError as e:
|
||||
print "Downloading current catalog failed", e
|
||||
|
||||
|
||||
if os.path.exists(existingCatalogPath):
|
||||
try:
|
||||
previousCatalog = sgprops.readProps(existingCatalogPath)
|
||||
except:
|
||||
print "Previous catalog is malformed"
|
||||
previousCatalog = sgprops.Node()
|
||||
|
||||
for p in previousCatalog.getChildren("package"):
|
||||
pkgId = p.getValue("id")
|
||||
if not pkgId in packages.keys():
|
||||
print "Orphaned old package:", pkgId
|
||||
continue
|
||||
|
||||
packages[pkgId].setPreviousData(p)
|
||||
else:
|
||||
print "No previous catalog"
|
||||
|
||||
catalogNode = sgprops.Node("catalog")
|
||||
sgprops.copy(config.getChild("template"), catalogNode)
|
||||
|
||||
mirrorUrls = (m.value for m in config.getChildren("mirror"))
|
||||
|
||||
packagesToGenerate = []
|
||||
for p in packages.values():
|
||||
p.scanSetXmlFiles(includePaths)
|
||||
|
||||
if (p.isSourceModified(scmRepo)):
|
||||
packagesToGenerate.append(p)
|
||||
else:
|
||||
p.useExistingCatalogData()
|
||||
|
||||
|
||||
# def f(x):
|
||||
# x.generateZip(outPath)
|
||||
# x.extractThumbnails(thumbnailPath)
|
||||
# return True
|
||||
#
|
||||
# p = Pool(8)
|
||||
# print(p.map(f,packagesToGenerate))
|
||||
|
||||
for p in packagesToGenerate:
|
||||
p.generateZip(outPath)
|
||||
p.extractThumbnails(thumbnailPath)
|
||||
|
||||
print "Creating catalog"
|
||||
for p in packages.values():
|
||||
catalogNode.addChild(p.packageNode(mirrorUrls, thumbnailUrl))
|
||||
|
||||
catalogNode.write(os.path.join(outPath, "catalog.xml"))
|
||||
|
||||
print "Uploading"
|
||||
if config.hasChild("upload"):
|
||||
processUpload(config.getChild("upload"), outPath)
|
||||
113
post_upload.py
Normal file
113
post_upload.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os, sys, re, fnmatch
|
||||
from subprocess import call
|
||||
|
||||
suffix = '.dmg'
|
||||
if sys.argv[1] == 'windows':
|
||||
suffix = '.exe'
|
||||
if sys.argv[1] == 'linux':
|
||||
suffix = '.tar.bz2'
|
||||
|
||||
isReleaseCandidate = False
|
||||
if len(sys.argv) > 2 and sys.argv[2] == 'release':
|
||||
isReleaseCandidate = True
|
||||
|
||||
allSuffix = '*' + suffix
|
||||
|
||||
print "Wildcard pattern is:" + allSuffix
|
||||
pattern = r'\w+-(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)([\w-]*)' + suffix
|
||||
sourceForgeUserHost = "jmturner@frs.sourceforge.net"
|
||||
sftpCommandFile = "sftp-commands"
|
||||
|
||||
if isReleaseCandidate:
|
||||
publicRoot = "/var/www/html/builds/rc"
|
||||
incomingDir = "/home/jenkins/incoming"
|
||||
sourceForgePath = "/home/frs/project/f/fl/flightgear/release-candidate/"
|
||||
else:
|
||||
publicRoot = "/var/www/html/builds/nightly"
|
||||
incomingDir = "/home/jenkins/nightly-incoming"
|
||||
sourceForgePath = "/home/frs/project/f/fl/flightgear/unstable/"
|
||||
|
||||
os.chdir(publicRoot)
|
||||
|
||||
def findFileVersion(dir):
|
||||
for file in os.listdir(dir):
|
||||
if fnmatch.fnmatch(file, allSuffix):
|
||||
m = re.match(pattern, file)
|
||||
if (m is not None):
|
||||
return (m.group('major'), m.group('minor'), m.group('patch'))
|
||||
|
||||
return None
|
||||
|
||||
incomingVer = findFileVersion(incomingDir)
|
||||
if incomingVer is None:
|
||||
print "No incoming files found matching " + allSuffix
|
||||
exit()
|
||||
|
||||
existingVer = findFileVersion('.')
|
||||
|
||||
# if files in dest location mis-match the version, archive them
|
||||
# and re-create the symlinks
|
||||
|
||||
versionChange = (existingVer != incomingVer)
|
||||
|
||||
oldFiles = []
|
||||
incomingFiles = []
|
||||
newFiles = []
|
||||
|
||||
if versionChange:
|
||||
print "Version number changing"
|
||||
|
||||
for file in os.listdir('.'):
|
||||
if fnmatch.fnmatch(file, allSuffix):
|
||||
if not os.path.islink(file):
|
||||
oldFiles.append(file)
|
||||
os.remove(file)
|
||||
|
||||
for file in os.listdir(incomingDir):
|
||||
if fnmatch.fnmatch(file, allSuffix):
|
||||
incomingFiles.append(file)
|
||||
|
||||
# copy and symlink
|
||||
for file in incomingFiles:
|
||||
# move it to the public location
|
||||
srcFile = os.path.join(incomingDir, file)
|
||||
|
||||
outFile = file
|
||||
# insert -rc before suffix
|
||||
if isReleaseCandidate:
|
||||
m = re.match(r'(\w+-\d+\.\d+\.\d+[\w-]*)' + suffix, file)
|
||||
outFile = m.group(1) + '-rc' + suffix
|
||||
print "RC out name is " + outFile
|
||||
|
||||
os.rename(srcFile, outFile)
|
||||
newFiles.append(outFile)
|
||||
|
||||
if not isReleaseCandidate:
|
||||
# symlink for stable web URL
|
||||
m = re.match(r'(\w+)-\d+\.\d+\.\d+-([\w-]+)' + suffix, file)
|
||||
latestName = m.group(1) + '-latest-' + m.group(2) + suffix
|
||||
|
||||
if os.path.exists(latestName):
|
||||
os.remove(latestName)
|
||||
os.symlink(file, latestName)
|
||||
|
||||
|
||||
# remove files from SF
|
||||
if len(oldFiles) > 0:
|
||||
f = open(sftpCommandFile, 'w')
|
||||
f.write("cd " + sourceForgePath + '\n')
|
||||
for file in oldFiles:
|
||||
print "Removing file " + file + " from SourceForge"
|
||||
f.write("rm " + file + '\n')
|
||||
f.write("bye\n")
|
||||
f.close()
|
||||
|
||||
call(["sftp", "-b", sftpCommandFile, sourceForgeUserHost])
|
||||
os.remove(sftpCommandFile)
|
||||
|
||||
# upload to SourceForge
|
||||
for file in newFiles:
|
||||
print "Uploading " + file + " to SourceForge"
|
||||
call(["scp", file, sourceForgeUserHost + ":" + sourceForgePath + file])
|
||||
197
sgprops.py
197
sgprops.py
@@ -13,7 +13,7 @@ class Node(object):
|
||||
self._value = None
|
||||
self._index = 0
|
||||
self._children = []
|
||||
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
@@ -21,21 +21,21 @@ class Node(object):
|
||||
@value.setter
|
||||
def value(self, v):
|
||||
self._value = v
|
||||
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
|
||||
@property
|
||||
def index(self):
|
||||
return self._index
|
||||
|
||||
@property
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
|
||||
def getChild(self, n, i=None, create = False):
|
||||
|
||||
|
||||
if i is None:
|
||||
i = 0
|
||||
# parse name as foo[999] if necessary
|
||||
@@ -43,72 +43,79 @@ class Node(object):
|
||||
if m is not None:
|
||||
n = m.group(1)
|
||||
i = int(m.group(2))
|
||||
|
||||
|
||||
for c in self._children:
|
||||
if (c.name == n) and (c.index == i):
|
||||
return c
|
||||
|
||||
|
||||
if create:
|
||||
c = Node(n, i, self)
|
||||
self._children.append(c)
|
||||
return c
|
||||
else:
|
||||
raise IndexError("no such child:" + str(n) + " index=" + str(i))
|
||||
|
||||
|
||||
def addChild(self, n):
|
||||
i = 0
|
||||
|
||||
# find first free index
|
||||
usedIndices = frozenset(c.index for c in self.getChildren(n))
|
||||
while i < 1000:
|
||||
if i not in usedIndices:
|
||||
break
|
||||
i += 1
|
||||
|
||||
# adding an existing instance
|
||||
if isinstance(n, Node):
|
||||
n._parent = self
|
||||
n._index = self.firstUnusedIndex(n.name)
|
||||
self._children.append(n)
|
||||
return n
|
||||
|
||||
i = self.firstUnusedIndex(n)
|
||||
# create it via getChild
|
||||
return self.getChild(n, i, create=True)
|
||||
|
||||
|
||||
def firstUnusedIndex(self, n):
|
||||
usedIndices = frozenset(c.index for c in self.getChildren(n))
|
||||
i = 0
|
||||
while i < 1000:
|
||||
if i not in usedIndices:
|
||||
return i
|
||||
i += 1
|
||||
raise RuntimeException("too many children with name:" + n)
|
||||
|
||||
def hasChild(self, nm):
|
||||
for c in self._children:
|
||||
if (c.name == nm):
|
||||
return True
|
||||
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def getChildren(self, n = None):
|
||||
if n is None:
|
||||
return self._children
|
||||
|
||||
|
||||
return [c for c in self._children if c.name == n]
|
||||
|
||||
|
||||
def getNode(self, path, cr = False):
|
||||
axes = path.split('/')
|
||||
nd = self
|
||||
for ax in axes:
|
||||
nd = nd.getChild(ax, create = cr)
|
||||
|
||||
|
||||
return nd
|
||||
|
||||
|
||||
def getValue(self, path, default = None):
|
||||
try:
|
||||
nd = self.getNode(path)
|
||||
return nd.value
|
||||
except:
|
||||
return default
|
||||
|
||||
|
||||
def write(self, path):
|
||||
root = self._createXMLElement('PropertyList')
|
||||
|
||||
t = ET.ElementTree(root)
|
||||
t.write(path, 'utf-8')
|
||||
|
||||
t.write(path, 'utf-8', xml_declaration = True)
|
||||
|
||||
def _createXMLElement(self, nm = None):
|
||||
if nm is None:
|
||||
nm = self.name
|
||||
|
||||
|
||||
n = ET.Element(nm)
|
||||
|
||||
# value and type specification
|
||||
|
||||
# value and type specification
|
||||
try:
|
||||
if self._value is not None:
|
||||
if isinstance(self._value, basestring):
|
||||
@@ -126,99 +133,145 @@ class Node(object):
|
||||
n.set('type', "bool")
|
||||
except UnicodeEncodeError:
|
||||
print "Encoding error with", self._value, type(self._value)
|
||||
|
||||
|
||||
# index in parent
|
||||
if (self.index != 0):
|
||||
n.set('n', self.index)
|
||||
|
||||
n.set('n', str(self.index))
|
||||
|
||||
# children
|
||||
for c in self._children:
|
||||
n.append(c._createXMLElement())
|
||||
|
||||
|
||||
return n;
|
||||
|
||||
|
||||
|
||||
class PropsHandler(handler.ContentHandler):
|
||||
def __init__(self, root = None, path = None, dataDirPath = None):
|
||||
def __init__(self, root = None, path = None, includePaths = []):
|
||||
self._root = root
|
||||
self._path = path
|
||||
self._basePath = os.path.dirname(path)
|
||||
self._dataDirPath = dataDirPath
|
||||
self._includes = includePaths
|
||||
self._locator = None
|
||||
|
||||
|
||||
if root is None:
|
||||
# make a nameless root node
|
||||
self._root = Node("", 0)
|
||||
self._current = self._root
|
||||
|
||||
|
||||
def setDocumentLocator(self, loc):
|
||||
self._locator = loc
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
self._content = ''
|
||||
self._locator = loc
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
self._content = None
|
||||
if (name == 'PropertyList'):
|
||||
return
|
||||
|
||||
|
||||
if 'n' in attrs.keys():
|
||||
index = int(attrs['n'])
|
||||
try:
|
||||
index = int(attrs['n'])
|
||||
except:
|
||||
print "Invalid index at line:", self._locator.getLineNumber(), "of", self._path
|
||||
self._current = self._current.addChild(name)
|
||||
return
|
||||
|
||||
self._current = self._current.getChild(name, index, create=True)
|
||||
else:
|
||||
self._current = self._current.addChild(name)
|
||||
|
||||
|
||||
|
||||
|
||||
if 'include' in attrs.keys():
|
||||
self.handleInclude(attrs['include'])
|
||||
|
||||
|
||||
self._currentTy = None;
|
||||
if 'type' in attrs.keys():
|
||||
self._currentTy = attrs['type']
|
||||
|
||||
|
||||
def handleInclude(self, includePath):
|
||||
if includePath.startswith('/'):
|
||||
includePath = includePath[1:]
|
||||
|
||||
|
||||
p = os.path.join(self._basePath, includePath)
|
||||
if not os.path.exists(p):
|
||||
p = os.path.join(self._dataDirPath, includePath)
|
||||
if not os.path.exists(p):
|
||||
found = False
|
||||
for i in self._includes:
|
||||
p = os.path.join(i, includePath)
|
||||
if os.path.exists(p):
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
raise RuntimeError("include file not found", includePath, "at line", self._locator.getLineNumber())
|
||||
|
||||
readProps(p, self._current, self._dataDirPath)
|
||||
|
||||
|
||||
readProps(p, self._current, self._includes)
|
||||
|
||||
def endElement(self, name):
|
||||
if (name == 'PropertyList'):
|
||||
return
|
||||
|
||||
|
||||
try:
|
||||
# convert and store value
|
||||
self._current.value = self._content
|
||||
if self._currentTy == "int":
|
||||
self._current.value = int(self._content)
|
||||
if self._currentTy is "bool":
|
||||
self._current.value = bool(self._content)
|
||||
if self._currentTy is "double":
|
||||
self._current.value = float(self._content)
|
||||
self._current.value = int(self._content) if self._content is not None else 0
|
||||
if self._currentTy == "bool":
|
||||
self._current.value = self.parsePropsBool(self._content)
|
||||
if self._currentTy == "double":
|
||||
if self._content is None:
|
||||
self._current.value = 0.0
|
||||
else:
|
||||
if self._content.endswith('f'):
|
||||
self._content = self._content[:-1]
|
||||
self._current.value = float(self._content)
|
||||
except:
|
||||
print "Parse error for value:", self._content, "at line:", self._locator.getLineNumber(), "of:", self._path
|
||||
|
||||
|
||||
self._current = self._current.parent
|
||||
|
||||
self._content = None
|
||||
self._currentTy = None
|
||||
|
||||
|
||||
def parsePropsBool(self, content):
|
||||
if content == "True" or content == "true":
|
||||
return True
|
||||
|
||||
if content == "False" or content == "false":
|
||||
return False
|
||||
|
||||
try:
|
||||
icontent = int(content)
|
||||
if icontent is not None:
|
||||
if icontent == 0:
|
||||
return False
|
||||
else:
|
||||
return True;
|
||||
except:
|
||||
return False
|
||||
|
||||
def characters(self, content):
|
||||
if self._content is None:
|
||||
self._content = ''
|
||||
self._content += content
|
||||
|
||||
|
||||
def endDocument(self):
|
||||
pass
|
||||
|
||||
|
||||
@property
|
||||
def root(self):
|
||||
return self._root
|
||||
|
||||
|
||||
def readProps(path, root = None, dataDirPath = None):
|
||||
def readProps(path, root = None, includePaths = []):
|
||||
parser = make_parser()
|
||||
locator = expatreader.ExpatLocator( parser )
|
||||
h = PropsHandler(root, path, dataDirPath)
|
||||
h = PropsHandler(root, path, includePaths)
|
||||
h.setDocumentLocator(locator)
|
||||
parser.setContentHandler(h)
|
||||
parser.parse(path)
|
||||
return h.root
|
||||
return h.root
|
||||
|
||||
def copy(src, dest):
|
||||
dest.value = src.value
|
||||
|
||||
# recurse over children
|
||||
for c in src.getChildren() :
|
||||
dc = dest.getChild(c.name, i = c.index, create = True)
|
||||
copy(c, dc)
|
||||
|
||||
2
simgear
2
simgear
Submodule simgear updated: 63b439e9ac...a52d3540a0
25
svn_catalog_repository.py
Normal file
25
svn_catalog_repository.py
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
import subprocess
|
||||
import xml.etree.cElementTree as ET
|
||||
|
||||
class SVNCatalogRepository:
|
||||
def __init__(self, path):
|
||||
self._path = path
|
||||
xml = subprocess.check_output(["svn", "info", "--xml", path])
|
||||
root = ET.fromstring(xml)
|
||||
|
||||
if (root.find(".//repository/root") == None):
|
||||
raise RuntimeError("Not an SVN repository:" + path)
|
||||
|
||||
def hasPathChanged(self, path, oldRevision):
|
||||
return self.scmRevisionForPath(path) != oldRevision
|
||||
|
||||
def scmRevisionForPath(self, path):
|
||||
xml = subprocess.check_output(["svn", "info", "--xml", path])
|
||||
root = ET.fromstring(xml)
|
||||
commit = root.find(".//entry/commit")
|
||||
return commit.get('revision', 0)
|
||||
|
||||
def update(self):
|
||||
subprocess.call(["svn", "update"])
|
||||
|
||||
52
template_catalog.xml
Normal file
52
template_catalog.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Template catalog - copy and modify for your site as required
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<!--
|
||||
catalogProps.addChild('version').value = '3.1.0'
|
||||
catalogProps.addChild('id').value = 'org.flightgear.default'
|
||||
catalogProps.addChild('license').value = 'GPL'
|
||||
catalogProps.addChild('url').value = "http://fgfs.goneabitbursar.com/pkg/3.1.0/default-catalog.xml"
|
||||
|
||||
catalogProps.addChild('description').value = "Aircraft developed and maintained by the FlightGear project"
|
||||
|
||||
de = catalogProps.addChild('de')
|
||||
# de.addChild('description').value = "<German translation of catalog description>"
|
||||
|
||||
fr = catalogProps.addChild('fr')
|
||||
-->
|
||||
|
||||
<version>3.4.*</version>
|
||||
<version>3.5.*</version>
|
||||
<version>3.6.*</version>
|
||||
|
||||
<id>org.myorganisation.hangar</id>
|
||||
<license>GPL</license>
|
||||
<url>http://some.stable.url.com/foo/bar/catalog.xml</url>
|
||||
|
||||
<description>A collection of interesting aircraft with some features
|
||||
</description>
|
||||
|
||||
<de>
|
||||
<description>Au Deutsch</description>
|
||||
</de>
|
||||
|
||||
<fr>
|
||||
<description>Francais</description>
|
||||
</fr>
|
||||
|
||||
<mirror>http://some.url/</mirror>
|
||||
<!-- <mirror>another mirror</mirror> -->
|
||||
|
||||
|
||||
<thumbnails>http://some.url/images</thumbnails>
|
||||
|
||||
<git-repository>git://some.git.repo/</git-repository>
|
||||
|
||||
<repository-prefix>Aircraft</repository-prefix>
|
||||
|
||||
</PropertyList>
|
||||
|
||||
|
||||
1
windows-3rd-party
Submodule
1
windows-3rd-party
Submodule
Submodule windows-3rd-party added at 522b07550b
Reference in New Issue
Block a user