This file was deleted.

This file was deleted.

@@ -1,29 +1,16 @@
/*
* Bootloader for a packed executable.
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Bootloader for a packed executable.
*/


@@ -46,11 +33,6 @@
#define _CRT_SECURE_NO_WARNINGS 1


/* To call TransformProcessType in the child process. */
#if defined(__APPLE__) && defined(WINDOWED)
#include <Carbon/Carbon.h>
#endif

#ifdef WIN32
#include <windows.h>
#include <wchar.h>
@@ -64,15 +46,12 @@

/* PyInstaller headers. */
#include "stb.h"
#include "pyi_global.h"
#include "pyi_global.h" // PATH_MAX for win32
#include "pyi_path.h"
#include "pyi_archive.h"
#include "pyi_utils.h"
#include "pyi_pythonlib.h"
#include "utils.h"
#include "launch.h"


#define MAX_STATUS_LIST 20
#include "pyi_launch.h"


#if defined(WIN32) && defined(WINDOWED)
@@ -82,15 +61,12 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
int main(int argc, char* argv[])
#endif
{
/* status_list[0] is reserved for the main process, the others for dependencies. */
ARCHIVE_STATUS *status_list[MAX_STATUS_LIST];
char thisfile[PATH_MAX];
#ifdef WIN32
wchar_t thisfilew[PATH_MAX + 1];
#endif
/* archive_status contain status information of the main process. */
ARCHIVE_STATUS *archive_status;
char executable[PATH_MAX];
char homepath[PATH_MAX];
char archivefile[PATH_MAX + 5];
char MEIPASS2[PATH_MAX + 1];
char archivefile[PATH_MAX];
char MEIPASS2[PATH_MAX];
int rc = 0;
char *extractionpath = NULL;
#if defined(WIN32) && defined(WINDOWED)
@@ -99,119 +75,85 @@ int main(int argc, char* argv[])
#endif
int i = 0;

memset(&status_list, 0, MAX_STATUS_LIST * sizeof(ARCHIVE_STATUS *));
if ((status_list[SELF] = (ARCHIVE_STATUS *) calloc(1, sizeof(ARCHIVE_STATUS))) == NULL){
memset(&archive_status, 0, sizeof(ARCHIVE_STATUS *));
archive_status = (ARCHIVE_STATUS *) malloc(sizeof(ARCHIVE_STATUS));
if (archive_status == NULL) {
FATALERROR("Cannot allocate memory for ARCHIVE_STATUS\n");
return -1;
}

get_thisfile(thisfile, argv[0]);
#ifdef WIN32
get_thisfilew(thisfilew);
#endif
get_archivefile(archivefile, thisfile);
get_homepath(homepath, thisfile);
pyi_path_executable(executable, argv[0]);
pyi_path_archivefile(archivefile, executable);
pyi_path_homepath(homepath, executable);

extractionpath = pyi_getenv("_MEIPASS2");

/* If the Python program we are about to run invokes another PyInstaller
* one-file program as subprocess, this subprocess must not be fooled into
* thinking that it is already unpacked. Therefore, PyInstaller deletes
* the _MEIPASS2 variable from the environment in _pyi_bootstrap.py.
*
* However, on some platforms (e.g. AIX) the Python function 'os.unsetenv()'
* does not always exist. In these cases we cannot delete the _MEIPASS2
* environment variable from Python but only set it to the empty string.
* The code below takes into account that _MEIPASS2 may exist while its
* value is only the empty string.
*/
if (extractionpath && *extractionpath == 0) {
extractionpath = NULL;
}

VS("_MEIPASS2 is %s\n", (extractionpath ? extractionpath : "NULL"));
VS("LOADER: _MEIPASS2 is %s\n", (extractionpath ? extractionpath : "NULL"));

if (init(status_list[SELF], homepath, &thisfile[strlen(homepath)])) {
if (init(status_list[SELF], homepath, &archivefile[strlen(homepath)])) {
if (pyi_arch_setup(archive_status, homepath, &executable[strlen(homepath)])) {
if (pyi_arch_setup(archive_status, homepath, &archivefile[strlen(homepath)])) {
FATALERROR("Cannot open self %s or archive %s\n",
thisfile, archivefile);
executable, archivefile);
return -1;
}
}

#ifdef WIN32
if (!extractionpath && !needToExtractBinaries(status_list)) {
VS("No need to extract files to run; setting extractionpath to homepath\n");
/* On Windows use single-process for --onedir mode. */
if (!extractionpath && !pyi_launch_need_to_extract_binaries(archive_status)) {
VS("LOADER: No need to extract files to run; setting extractionpath to homepath\n");
extractionpath = homepath;
strcpy(MEIPASS2, homepath);
pyi_setenv("_MEIPASS2", MEIPASS2); //Bootstrap sets sys._MEIPASS, plugins rely on it
}
#endif
if (extractionpath) {
VS("Already in the child - running!\n");
VS("LOADER: Already in the child - running user's code.\n");
/* If binaries were extracted to temppath,
* we pass it through status variable
*/
if (strcmp(homepath, extractionpath) != 0) {
strcpy(status_list[SELF]->temppath, extractionpath);
#ifdef WIN32
strcpy(status_list[SELF]->temppathraw, extractionpath);
#endif
strcpy(archive_status->temppath, extractionpath);
/*
* Temp path exits - set appropriate flag and change
* status->mainpath to point to temppath.
*/
status_list[SELF]->has_temp_directory = true;
#ifdef WIN32
strcpy(status_list[SELF]->mainpath, status_list[SELF]->temppathraw);
#else
strcpy(status_list[SELF]->mainpath, status_list[SELF]->temppath);
#endif
archive_status->has_temp_directory = true;
strcpy(archive_status->mainpath, archive_status->temppath);
}

#if defined(__APPLE__) && defined(WINDOWED)
ProcessSerialNumber psn = { 0, kCurrentProcess };
OSStatus returnCode = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
#endif
#ifdef WIN32
CreateActContext(extractionpath, thisfile);
#endif
rc = doIt(status_list[SELF], argc, argv);
#ifdef WIN32
ReleaseActContext();
#endif
pyi_pylib_finalize();
/* Main code to initialize Python and run user's code. */
pyi_launch_initialize(executable, extractionpath);
rc = pyi_launch_execute(archive_status, argc, argv);
pyi_launch_finalize(archive_status);

} else {
if (extractBinaries(status_list)) {
VS("Error extracting binaries\n");

/* status->temppath is created if necessary. */
if (pyi_launch_extract_binaries(archive_status)) {
VS("LOADER: temppath is %s\n", archive_status->temppath);
VS("LOADER: Error extracting binaries\n");
return -1;
}

VS("Executing self as child with ");
/* run the "child" process, then clean up */
#ifdef WIN32
pyi_setenv("_MEIPASS2", status_list[SELF]->temppath[0] != 0 ? status_list[SELF]->temppathraw : status_list[SELF]->homepathraw);
#else
pyi_setenv("_MEIPASS2", status_list[SELF]->temppath[0] != 0 ? status_list[SELF]->temppath : homepath);
#endif
VS("LOADER: Executing self as child\n");
/* Run the 'child' process, then clean up. */
pyi_setenv("_MEIPASS2", archive_status->temppath[0] != 0 ? archive_status->temppath : homepath);

if (set_environment(status_list[SELF]) == -1)
if (pyi_utils_set_environment(archive_status) == -1)
return -1;

#ifndef WIN32
rc = spawn(thisfile, argv);
#else
rc = spawn(thisfilew);
#endif
/* Run user's code in a subprocess and pass command line argumets to it. */
rc = pyi_utils_create_child(executable, argv);

VS("Back to parent...\n");
if (status_list[SELF]->has_temp_directory == true)
pyi_remove_temp_path(status_list[SELF]->temppath);
VS("LOADER: Back to parent\n");

for (i = SELF; status_list[i] != NULL; i++) {
VS("Freeing status for %s\n", status_list[i]->archivename);
free(status_list[i]);
}
VS("LOADER: Doing cleanup\n");
if (archive_status->has_temp_directory == true)
pyi_remove_temp_path(archive_status->temppath);
pyi_arch_status_free_memory(archive_status);
if (extractionpath != NULL)
free(extractionpath);
}
return rc;
}
@@ -1,3 +1,14 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* On some platforms (e.g. Solaris, AIX) mkdtemp is not available.
*/
@@ -1,31 +1,16 @@
/*
* Fuctions related to PyInstaller archive embedded in executable.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Fuctions related to PyInstaller archive embedded in executable.
*/


@@ -155,6 +140,7 @@ int pyi_arch_extract2fs(ARCHIVE_STATUS *status, TOC *ptoc)
FILE *out;
unsigned char *data = pyi_arch_extract(status, ptoc);

/* Create tmp dir _MEIPASSxxx. */
if (pyi_create_temp_path(status) == -1){
return -1;
}
@@ -170,10 +156,11 @@ int pyi_arch_extract2fs(ARCHIVE_STATUS *status, TOC *ptoc)
#ifndef WIN32
fchmod(fileno(out), S_IRUSR | S_IWUSR | S_IXUSR);
#endif
fclose(out);
fclose(out);
}
free(data);
return 0;

return 0;
}


@@ -225,7 +212,7 @@ static int findDigitalSignature(ARCHIVE_STATUS * const status)
}
else {
/* Invalid magic value */
VS("Could not find a valid magic value (was %x %x).\n", (unsigned int) buf[0], (unsigned int) buf[1]);
VS("LOADER: Could not find a valid magic value (was %x %x).\n", (unsigned int) buf[0], (unsigned int) buf[1]);
return -1;
}

@@ -234,7 +221,7 @@ static int findDigitalSignature(ARCHIVE_STATUS * const status)
fread(&offset, 4, 1, status->fp);
if (offset == 0)
return -1;
VS("%s contains a digital signature\n", status->archivename);
VS("LOADER: %s contains a digital signature\n", status->archivename);
return offset;
#else
return -1;
@@ -252,11 +239,11 @@ int pyi_arch_open(ARCHIVE_STATUS *status)
int i;
#endif
int filelen;
VS("archivename is %s\n", status->archivename);
VS("LOADER: archivename is %s\n", status->archivename);
/* Physically open the file */
status->fp = stb_fopen(status->archivename, "rb");
if (status->fp == NULL) {
VS("Cannot open archive: %s\n", status->archivename);
VS("LOADER: Cannot open archive: %s\n", status->archivename);
return -1;
}

@@ -266,7 +253,7 @@ int pyi_arch_open(ARCHIVE_STATUS *status)

if (pyi_arch_check_cookie(status, filelen) < 0)
{
VS("%s does not contain an embedded package\n", status->archivename);
VS("LOADER: %s does not contain an embedded package\n", status->archivename);
#ifndef WIN32
return -1;
#else
@@ -284,13 +271,16 @@ int pyi_arch_open(ARCHIVE_STATUS *status)
}
if (i == 8)
{
VS("%s does not contain an embedded package, even skipping the signature\n", status->archivename);
VS("LOADER: %s does not contain an embedded package, even skipping the signature\n", status->archivename);
return -1;
}
VS("package found skipping digital signature in %s\n", status->archivename);
VS("LOADER: package found skipping digital signature in %s\n", status->archivename);
#endif
}

/* Set the flag that Python library was not loaded yet. */
status->is_pylib_loaded = false;

/* From the cookie, calculate the archive start */
status->pkgstart = filelen - ntohl(status->cookie.len);

@@ -325,34 +315,34 @@ int pyi_arch_open(ARCHIVE_STATUS *status)
*/
int pyi_arch_set_paths(ARCHIVE_STATUS *status, char const * archivePath, char const * archiveName)
{
#ifdef WIN32
char *p;
#endif
/* Get the archive Path */
strcpy(status->archivename, archivePath);
strcat(status->archivename, archiveName);

/* Set homepath to where the archive is */
strcpy(status->homepath, archivePath);
#ifdef WIN32
/* Replace backslashes with forward slashes. */
// TODO eliminate the need for this conversion and homepathraw and temppathraw
strcpy(status->homepathraw, archivePath);
for ( p = status->homepath; *p; p++ )
if (*p == '\\')
*p = '/';
#endif

/*
* Initial value of mainpath is homepath. It might be overriden
* by temppath if it is available.
*/
status->has_temp_directory = false;
#ifdef WIN32
strcpy(status->mainpath, status->homepathraw);
#else
strcpy(status->mainpath, status->homepath);
#endif

return 0;
}


/* Setup the archive with python modules. (this always needs to be done) */
int pyi_arch_setup(ARCHIVE_STATUS *status, char const * archivePath, char const * archiveName)
{
/* Set up paths */
if (pyi_arch_set_paths(status, archivePath, archiveName))
return -1;

/* Open the archive */
if (pyi_arch_open(status))
return -1;

return 0;
}
@@ -382,3 +372,20 @@ int pyi_arch_get_pyversion(ARCHIVE_STATUS *status)
{
return ntohl(status->cookie.pyvers);
}


/*
* Free memory allocated for archive status.
*/
void pyi_arch_status_free_memory(ARCHIVE_STATUS *archive_status)
{
if (archive_status != NULL) {
VS("LOADER: Freeing archive status for %s\n", archive_status->archivename);
/* Free the TOC memory from the archive status first. */
if (archive_status->tocbuff != NULL) {
free(archive_status->tocbuff);
}
free(archive_status);
}
}

@@ -1,33 +1,21 @@
/*
* Declarations related to an PyInstaller archive.
*
* Copyright (C) 2005, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/
#ifndef HEADER_PYI_ARCHIVE_H
#define HEADER_PYI_ARCHIVE_H


/*
* Declarations related to an PyInstaller archive.
*/


#ifndef PYI_ARCHIVE_H
#define PYI_ARCHIVE_H


/* Types of CArchive items. */
@@ -70,26 +58,28 @@ typedef struct _archive_status {
TOC *tocbuff;
TOC *tocend;
COOKIE cookie;
char archivename[PATH_MAX + 1];
char homepath[PATH_MAX + 1];
char temppath[PATH_MAX + 1];
#ifdef WIN32
char homepathraw[PATH_MAX + 1];
char temppathraw[PATH_MAX + 1];
#endif
char archivename[PATH_MAX];
char homepath[PATH_MAX];
char temppath[PATH_MAX];
/*
* Main path could be homepath or temppath. It will be temppath
* if temppath is available. Sometimes we do not need to know if temppath
* or homepath should be used. We only need to know the path. This variable
* is used for example to set PYTHONPATH or PYTHONHOME.
*/
char mainpath[PATH_MAX + 1];
char mainpath[PATH_MAX];
/*
* Flag if temporary directory is available. This usually means running
* executable in onefile mode. Bootloader has to behave differently
* in this mode.
*/
bool_t has_temp_directory;
bool has_temp_directory;
/*
* Flag if Python library was loaded. This indicates if it is safe
* to call function PI_Py_Finalize(). If Python dll is missing
* calling this function would cause segmentation fault.
*/
bool is_pylib_loaded;
} ARCHIVE_STATUS;


@@ -110,7 +100,33 @@ int pyi_arch_get_pyversion(ARCHIVE_STATUS *status);
int pyi_arch_set_paths(ARCHIVE_STATUS *status, char const * archivePath, char const * archiveName);
int pyi_arch_open(ARCHIVE_STATUS *status);


/*
* Memory allocation wrappers.
*/
// TODO implement alloc function.
//void pyi_arch_status_alloc_memory(ARCHIVE_STATUS *status)
void pyi_arch_status_free_memory(ARCHIVE_STATUS *status);

/*
* Setup the paths and open the archive
*
* @param archivePath The path (with trailing backslash) to the archive.
*
* @param archiveName The file name of the archive, without a path.
*
* @param workpath The path (with trailing backslash) to where
* the binaries were extracted. If they have not
* benn extracted yet, this is NULL. If they have,
* this will either be archivePath, or a temp dir
* where the user has write permissions.
*
* @return 0 on success, non-zero otherwise.
*/
int pyi_arch_setup(ARCHIVE_STATUS *status, char const * archivePath, char const * archiveName);

TOC *getFirstTocEntry(ARCHIVE_STATUS *status);
TOC *getNextTocEntry(ARCHIVE_STATUS *status, TOC *entry);

#endif /* HEADER_PYI_ARCHIVE_H */

#endif /* PYI_ARCHIVE_H */
@@ -1,31 +1,16 @@
/*
* Glogal shared fuctions used in many bootloader files.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Glogal shared fuctions used in many bootloader files.
*/


@@ -109,6 +94,3 @@
}
#endif
#endif



@@ -1,43 +1,42 @@
/*
* Glogal shared declarations used in many bootloader files.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Glogal shared declarations used in many bootloader files.
*/


#ifndef PYI_GLOBAL_H
#define PYI_GLOBAL_H


/*
* Detect memory leaks.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* Use Boehm garbage collector to detect memory leaks.
* malloc(), free(), strdup() and similar functions
* are replaced by calls from the gc library.
*/
#ifndef HEADER_PYI_GLOBAL_H
#define HEADER_PYI_GLOBAL_H
#ifdef PYI_LEAK_DETECTOR
#include <gc/leak_detector.h>
#endif


/*
* Definition of type boolean. On OSX boolean type is available.
*/
typedef int bool_t;
typedef int bool;

#define false 0
#define true 1
#define true 1
#define false 0


/* Type for dynamic library. */
@@ -104,16 +103,25 @@ typedef int bool_t;
#endif


/* Path separator. */
/* Path and string macros. */

#ifdef WIN32
#define PATHSEP ";"
#define SEP '\\'
#define PYI_PATHSEP ';'
#define PYI_SEP '\\'
/*
* For some functions like strcat() we need to pass
* string and not only char.
*/
#define PYI_SEPSTR "\\"
#else
#define PATHSEP ":"
#define SEP '/'
#define PYI_PATHSEP ':'
#define PYI_SEP '/'
#define PYI_SEPSTR "/"
#endif

/* Strings are usually terminated by this character. */
#define PYI_NULLCHAR '\0'


/* Rewrite ANSI/POSIX functions to Win32 equivalents. */
#ifdef WIN32
@@ -128,9 +136,4 @@ typedef int bool_t;
#endif




/* Refers to 1st item in the archive status_list. */
#define SELF 0

#endif /* HEADER_PYI_GLOBAL_H */
#endif /* PYI_GLOBAL_H */

Large diffs are not rendered by default.

@@ -0,0 +1,86 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Launch a python module from an archive and other related stuff.
*/
#ifndef PYI_LAUNCH_H
#define PYI_LAUNCH_H


/*****************************************************************
* The following 4 entries are for applications which may need to
* use to 2 steps to execute
*****************************************************************/

/*
* Extract binaries in the archive
*
* @param workpath (OUT) Where the binaries were extracted to. If
* none extracted, is NULL.
*
* @return 0 on success, non-zero otherwise.
*/
int pyi_launch_extract_binaries(ARCHIVE_STATUS *archive_status);


/*
* Check if binaries need to be extracted. If not, this is probably a onedir
* solution, and a child process will not be required on windows.
*/
int pyi_launch_need_to_extract_binaries(ARCHIVE_STATUS *archive_status);

/*
* Wrapped platform specific initialization before loading Python and executing
* all scripts in the archive.
*/
void pyi_launch_initialize(const char *executable, const char *extractionpath);


/*
* Wrapped platform specific finalization before loading Python and executing
* all scripts in the archive.
*/
void pyi_launch_finalize(ARCHIVE_STATUS *archive_status);


/*
* Load Python and execute all scripts in the archive
*
* @param argc Count of "commandline" args
*
* @param argv The "commandline".
*
* @return -1 for internal failures, or the rc of the last script.
*/
int pyi_launch_execute(ARCHIVE_STATUS *status, int argc, char *argv[]);


/*
* Call a simple "int func(void)" entry point. Assumes such a function
* exists in the main namespace.
* Return non zero on failure, with -2 if the specific error is
* that the function does not exist in the namespace.
*
* @param name Name of the function to execute.
* @param presult Integer return value.
*/
int callSimpleEntryPoint(char *name, int *presult);


/**
* Clean up extracted binaries
*/
void cleanUp(ARCHIVE_STATUS *status);


#endif /* PYI_LAUNCH_H */

@@ -0,0 +1,222 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Path manipulation utilities.
*/


#ifdef WIN32
#include <windows.h> // GetModuleFileNameW
#include <wchar.h>
#elif __APPLE__
#include <mach-o/dyld.h> // _NSGetExecutablePath()
#else
#include <limits.h> // PATH_MAX
// TODO Eliminate getpath.c/.h and replace it with functions from stb.h.
#include "getpath.h"
#endif


/* PyInstaller headers. */
#include "stb.h"
#include "pyi_global.h" // PATH_MAX


/*
* Giving a fullpath, it will copy to the buffer a string
* which contains the path without last component.
*/
// TODO use for unix function dirname()
void pyi_path_dirname(char *result, const char *path)
{
size_t len = 0;
char *match = NULL;

/* Copy path to result and then just write '\0' to the place with path separator. */
strncpy(result, path, strlen(path)+1);
/* Remove separator from the end. */
len = strlen(result);
if (result[len] == PYI_SEP) {
result[len] = PYI_NULLCHAR;
}
/* Remove the rest of the string. */
match = strrchr(result, PYI_SEP);
if (match != NULL) {
*match = PYI_NULLCHAR;
}
}


/*
* Returns the last component of the path in filename. Return result
* in new buffer.
*/
// TODO use for unix function basename()
// TODO For now it is win32 implementation only!
void pyi_path_basename(char *result, const char *path)
{
/* Search for the last directory separator in PATH. */
char *basename = strrchr (path, '\\');
if (!basename) basename = strrchr (path, '/');

/* If found, return the address of the following character,
or the start of the parameter passed in. */
strcpy(result, basename ? ++basename : (char*)path);
}


/*
* Join two path components.
* Joined path is returned without slash at the end.
*/
void pyi_path_join(char *result, const char *path1, const char *path2)
{
size_t len = 0;
memset(result, 0, PATH_MAX);
/* Copy path1 to result null string '\0'. */
strncpy(result, path1, strlen(path1));
/* Append trailing slash if missing. */
len = strlen(result);
if (result[len-1] != PYI_SEP) {
result[len] = PYI_SEP;
result[len+1] = PYI_NULLCHAR;
}
/* Remove trailing slash from path2 if present. */
len = strlen(path2);
if (path2[len-1] == PYI_SEP) {
/* Append path2 without slash. */
strncat(result, path2, len-2);
}
else {
/* path2 does not end with slash. */
strcat(result, path2);
}
}


/* Normalize a pathname. Return result in new buffer. */
// TODO implement this function
void pyi_path_normalize(char *result, const char *path)
{
}


/*
* Return full path to the current executable.
* Executable is the .exe created by pyinstaller: path/myappname.exe
*
* execfile - buffer where to put path to executable.
* appname - usually the item argv[0].
*/
int pyi_path_executable(char *execfile, const char *appname)
{
char buffer[PATH_MAX];

#ifdef WIN32
char dos83_buffer[PATH_MAX];
stb__wchar wchar_buffer[PATH_MAX];
stb__wchar wchar_dos83_buffer[PATH_MAX];
char basename[PATH_MAX];
char dirname[PATH_MAX];

/* Windows has special function to obtain path to executable. */
if (!GetModuleFileNameW(NULL, wchar_buffer, PATH_MAX)) {
FATALERROR("System error - unable to load!");
return -1;
}
/* Convert wchar_t to utf8. Just use type char as usual. */
stb_to_utf8(buffer, wchar_buffer, PATH_MAX);

/*
* Use 8.3 filename (dos 8.3 or short filename)
* to overcome the Python and PyInstaller limitation
* to run with foreign characters in directory names.
*
* If 8.3 filename does not exist, original vaule is just copied
* to the supplied buffer. 8.3 filename might not be available
* for some networking file systems.
*
* This is workaround for <http://www.pyinstaller.org/ticket/298>.
*/
GetShortPathNameW(wchar_buffer, wchar_dos83_buffer, PATH_MAX);
/* Convert wchar_t to utf8 just use char as usual. */
stb_to_utf8(dos83_buffer, wchar_dos83_buffer, PATH_MAX);

/*
* Construct proper execfile - 83_DIRNAME + full_basename.
* GetShortPathName() makes also the basename (appname.exe) shorter.
*
* However, bootloader code depends on unmodified basename.
* Using basename from original path should fix this.
* It is supposed that basename does not contain any foreign characters.
*
* Reuse 'buffer' variable.
*/
pyi_path_basename(basename, buffer);
pyi_path_dirname(dirname, dos83_buffer);
pyi_path_join(buffer, dirname, basename);

/* Mac OS X has special function to obtain path to executable. */
// TODO implement
//#elif __APPLE__ _NSGetExecutablePath()
#else
/* Fill in thisfile. */
#ifdef __CYGWIN__
if (strncasecmp(&appname[strlen(appname)-4], ".exe", 4)) {
strcpy(execfile, appname);
strcat(execfile, ".exe");
PI_SetProgramName(execfile);
}
else
#endif /* __CYGWIN__ */
PI_SetProgramName(appname);
strcpy(buffer, PI_GetProgramFullPath());
#endif
/*
* Ensure path to executable is absolute.
* 'execfile' starting with ./ might break some modules when changing
* the CWD.From 'execfile' is constructed 'homepath' and homepath is used
* for LD_LIBRARY_PATH variavle. Relative LD_LIBRARY_PATH is a security
* problem.
*/
if(stb_fullpath(execfile, PATH_MAX, buffer) == false) {
VS("LOADER: executable is %s\n", execfile);
return -1;
}

VS("LOADER: executable is %s\n", execfile);

return 0;
}


/*
* Return absolute path to homepath. It is the directory containing executable.
*/
void pyi_path_homepath(char *homepath, const char *thisfile)
{
/* Fill in here (directory of thisfile). */
pyi_path_dirname(homepath, thisfile);
VS("LOADER: homepath is %s\n", homepath);
}


// TODO What is the purpose of this function and the variable 'archivefile'?
void pyi_path_archivefile(char *archivefile, const char *thisfile)
{
strcpy(archivefile, thisfile);
#ifdef WIN32
strcpy(archivefile + strlen(archivefile) - 3, "pkg");
#else
strcat(archivefile, ".pkg");
#endif
}
@@ -0,0 +1,35 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Path manipulation utilities.
*/


#ifndef PYI_PATH_H
#define PYI_PATH_H


/* Path manipulation. Result is added to the supplied buffer. */
void *pyi_path_basename(char *result, const char *path);
void *pyi_path_dirname(char *result, const char *path);
void *pyi_path_join(char *result, const char *path1, const char *path2);
void *pyi_path_normalize(char *result, const char *path);
// TODO implement.
//void *pyi_path_abspath(char *result, const char *path);


int pyi_path_executable(char *execfile, const char *appname);
void pyi_path_homepath(char *homepath, const char *executable);
void pyi_path_archivefile(char *archivefile, const char *executable);


#endif /* PYI_PATH_H */
@@ -1,34 +1,16 @@
/*
* Python.h replacements.
*
* We use dynamic loading -> one binary can be used with (nearly) any Python
* version. This is the cruft necessary to do dynamic loading.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Python.h replacements.
*/


@@ -1,35 +1,22 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Python.h replacements.
*
* We use dynamic loading -> one binary can be used with (nearly) any Python
* version. This is the cruft necessary to do dynamic loading.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/


#ifndef PYI_PYTHON_H
#define PYI_PYTHON_H

@@ -1,31 +1,16 @@
/*
* Functions to load, initialize and launch Python.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Functions to load, initialize and launch Python.
*/


@@ -35,7 +20,6 @@
#include <io.h> // _setmode
#include <winsock.h> // ntohl
#else
#include <dlfcn.h> // dlopen
#include <limits.h> // PATH_MAX
#include <netinet/in.h> // ntohl
#endif
@@ -58,10 +42,15 @@
int pyi_pylib_load(ARCHIVE_STATUS *status)
{
dylib_t dll;
char dllpath[PATH_MAX + 1];
char dllpath[PATH_MAX];
char dllname[64];
int pyvers = ntohl(status->cookie.pyvers);

/*
* On AIX Append the shared object member to the library path
* to make it look like this:
* libpython2.6.a(libpython2.6.so)
*/
#ifdef AIX
/*
* On AIX 'ar' archives are used for both static and shared object.
@@ -70,33 +59,26 @@ int pyi_pylib_load(ARCHIVE_STATUS *status)
*/
uint32_t pyvers_major;
uint32_t pyvers_minor;
#endif

pyvers_major = pyvers / 10;
pyvers_minor = pyvers % 10;

sprintf(dllname, "(libpython%01d.%01d.so)", pyvers_major, pyvers_minor);
#else
strcpy(dllname, status->cookie.pylibname);
#endif

/*
* Look for Python library in homepath or temppath.
* It depends on the value of mainpath.
*/
strcpy(dllpath, status->mainpath);
pyi_path_join(dllpath, status->mainpath, dllname);

#ifdef AIX
pyvers_major = pyvers / 10;
pyvers_minor = pyvers % 10;

/* Append the shared object member to the library path
* to make it look like this:
* libpython2.6.a(libpython2.6.so)
*/
sprintf(dllpath + strlen(dllpath), "(libpython%01d.%01d.so)", pyvers_major, pyvers_minor);
#endif

/* Append Python library name to dllpath. */
strcat(dllpath, dllname);
VS("Python library: %s\n", dllpath);
VS("LOADER: Python library: %s\n", dllpath);

/* Load the DLL */
dll = pyi_dlopen(dllpath);
dll = pyi_utils_dlopen(dllpath);

/* Check success of loading Python library. */
if (dll == 0) {
@@ -151,7 +133,7 @@ static int pyi_pylib_set_runtime_opts(ARCHIVE_STATUS *status)
TOC *ptoc = status->tocbuff;
while (ptoc < status->tocend) {
if (ptoc->typcd == ARCHIVE_ITEM_RUNTIME_OPTION) {
VS("%s\n", ptoc->name);
VS("LOADER: %s\n", ptoc->name);
switch (ptoc->name[0]) {
case 'v':
*PI_Py_VerboseFlag = 1;
@@ -188,6 +170,7 @@ static int pyi_pylib_set_runtime_opts(ARCHIVE_STATUS *status)
return 0;
}


/*
* Start python - return 0 on success
*/
@@ -205,34 +188,20 @@ int pyi_pylib_start_python(ARCHIVE_STATUS *status, int argc, char *argv[])
PyObject *val;
PyObject *sys;

// TODO set pythonpath by function from Python C API (Python 2.6+)
/* Set the PYTHONPATH */
VS("Manipulating evironment\n");
VS("LOADER: Manipulating evironment\n");
strcpy(pypath, status->mainpath);
/* don't chop off SEP if root directory */
#ifdef WIN32
if (strlen(pypath) > 14)
#else
if (strlen(pypath) > 12)
#endif
pypath[strlen(pypath)-1] = '\0';

VS("LOADER: PYTHONPATH=%s\n", pypath);
pyi_setenv("PYTHONPATH", pypath);
VS("PYTHONPATH=%s\n", pypath);


/* Clear out PYTHONHOME to avoid clashing with any Python installation. */
pyi_unsetenv("PYTHONHOME");

/* Set PYTHONHOME by using function from Python C API. */
strcpy(pypath, status->mainpath);
/* On Windows remove back slash '\\' from the end. */
// TODO remove this hook when path handling is fixed in bootloader.
#ifdef WIN32
/* Remove trailing slash in directory path. */
pypath[strlen(pypath)-1] = '\0';
#endif
VS("LOADER: PYTHONHOME=%s\n", pypath);
PI_Py_SetPythonHome(pypath);
VS("PYTHONHOME=%s\n", pypath);


/* Start python. */
@@ -243,19 +212,18 @@ int pyi_pylib_start_python(ARCHIVE_STATUS *status, int argc, char *argv[])
PI_Py_SetProgramName(status->archivename); /*XXX*/
PI_Py_Initialize();

// TODO set sys.path by function from Python C API (Python 2.6+)
/* Set sys.path */
/* VS("Manipulating Python's sys.path\n"); */
VS("LOADER: Manipulating Python's sys.path\n");
PI_PyRun_SimpleString("import sys\n");
PI_PyRun_SimpleString("del sys.path[:]\n");
if (status->temppath[0] != '\0') {
if (status->temppath[0] != PYI_NULLCHAR) {
strcpy(tmp, status->temppath);
tmp[strlen(tmp)-1] = '\0';
sprintf(cmd, "sys.path.append(r\"%s\")", tmp);
PI_PyRun_SimpleString(cmd);
}

strcpy(tmp, status->homepath);
tmp[strlen(tmp)-1] = '\0';
sprintf(cmd, "sys.path.append(r\"%s\")", tmp);
PI_PyRun_SimpleString (cmd);

@@ -293,7 +261,7 @@ int pyi_pylib_import_modules(ARCHIVE_STATUS *status)
PyObject *co;
PyObject *mod;

VS("importing modules from CArchive\n");
VS("LOADER: importing modules from CArchive\n");

/* Get the Python function marshall.load
* Here we collect some reference to PyObject that we don't dereference
@@ -312,7 +280,7 @@ int pyi_pylib_import_modules(ARCHIVE_STATUS *status)
{
unsigned char *modbuf = pyi_arch_extract(status, ptoc);

VS("extracted %s\n", ptoc->name);
VS("LOADER: extracted %s\n", ptoc->name);

/* .pyc/.pyo files have 8 bytes header. Skip it and load marshalled
* data form the right point.
@@ -370,14 +338,14 @@ int pyi_pylib_install_zlib(ARCHIVE_STATUS *status, TOC *ptoc)
int pyi_pylib_install_zlibs(ARCHIVE_STATUS *status)
{
TOC * ptoc;
VS("Installing import hooks\n");
VS("LOADER: Installing import hooks\n");

/* Iterate through toc looking for zlibs (type 'z') */
ptoc = status->tocbuff;
while (ptoc < status->tocend) {
if (ptoc->typcd == ARCHIVE_ITEM_PYZ)
{
VS("%s\n", ptoc->name);
VS("LOADER: %s\n", ptoc->name);
pyi_pylib_install_zlib(status, ptoc);
}

@@ -386,9 +354,16 @@ int pyi_pylib_install_zlibs(ARCHIVE_STATUS *status)
return 0;
}

void pyi_pylib_finalize(void)
void pyi_pylib_finalize(ARCHIVE_STATUS *status)
{
PI_Py_Finalize();
/*
* Call this function only if Python library was initialized.
*
* Otherwise it should be NULL pointer. If Python library is not properly
* loaded then calling this function might cause some segmentation faults.
*/
if (status->is_pylib_loaded == true) {
VS("LOADER: Cleaning up Python interpreter.\n");
PI_Py_Finalize();
}
}


@@ -1,32 +1,18 @@
/*
* Functions to load, initialize and launch Python.
*
* Copyright (C) 2012, Martin Zibricky
* Copyright (C) 2005-2011, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Functions to load, initialize and launch Python.
*/

#ifndef PYI_PYTHONLIB_H
#define PYI_PYTHONLIB_H

@@ -38,7 +24,7 @@ int pyi_pylib_import_modules(ARCHIVE_STATUS *status);
int pyi_pylib_install_zlibs(ARCHIVE_STATUS *status);
int pyi_pylib_run_scripts(ARCHIVE_STATUS *status);

void pyi_pylib_finalize(void);
void pyi_pylib_finalize(ARCHIVE_STATUS *status);


#endif /* PYI_PYTHONLIB_H */

Large diffs are not rendered by default.

@@ -1,31 +1,20 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Portable wrapper for some utility functions like getenv/setenv,
* file path manipulation and other shared data types or functions.
*
* Copyright (C) 2012, Martin Zibricky
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/


#ifndef HEADER_PYI_UTILS_H
#define HEADER_PYI_UTILS_H

@@ -41,18 +30,14 @@ int pyi_unsetenv(const char *variable);
int pyi_create_temp_path(ARCHIVE_STATUS *status);
void pyi_remove_temp_path(const char *dir);

/* Path manipulation. A new allocated buffer is returned. */
char *pyi_path_basename(const char *path);
char *pyi_path_dirname(const char *fullpath);
char *pyi_path_join(const char *path1, const char *path2);
char *pyi_path_normalize(const char *path);

/* File manipulation. */
FILE *pyi_open_target(const char *path, const char* name_);
int pyi_copy_file(const char *src, const char *dst, const char *filename);

/* Other routines. */
dylib_t pyi_dlopen(const char *dllpath);
dylib_t pyi_utils_dlopen(const char *dllpath);
int pyi_utils_create_child(const char *thisfile, char *const argv[]);
int pyi_utils_set_environment(const ARCHIVE_STATUS *status);


#endif /* HEADER_PY_UTILS_H */
@@ -750,8 +750,10 @@ static void stb__print_one(void *handle, char *s, intptr_t len)
{
if (len)
// Explicitly change 'len' type to int32_t.
if (WriteConsoleA(handle, s, (int32_t) len, NULL,NULL))
fwrite(s, 1, len, stdout); // if it fails, maybe redirected, so do normal
if (WriteConsoleA(handle, s, (int32_t) len, NULL,NULL) == STB_FALSE) {
// Writing to console failed, so do normal. Maybe stdout is redirected.
fwrite(s, 1, len, stdout);
}
}

static void stb__print(char *s)
@@ -823,6 +825,7 @@ static void stb__print(char *s)
s=t;
SetConsoleTextAttribute(handle, 0x07);
}

stb__print_one(handle, t, s-t);
SetConsoleTextAttribute(handle, 0x07);
}
@@ -888,7 +891,7 @@ void stbprint(const char *fmt, ...)
typedef unsigned short stb__wchar;

STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, char *str, int n);
STB_EXTERN char * stb_to_utf8 (char *buffer, stb__wchar *str, int n);
STB_EXTERN char * stb_to_utf8 (char *buffer, const stb__wchar *str, int n);

STB_EXTERN stb__wchar *stb__from_utf8(char *str);
STB_EXTERN stb__wchar *stb__from_utf8_alt(char *str);
@@ -946,7 +949,7 @@ stb__wchar * stb_from_utf8(stb__wchar *buffer, char *ostr, int n)
return buffer;
}

char * stb_to_utf8(char *buffer, stb__wchar *str, int n)
char * stb_to_utf8(char *buffer, const stb__wchar *str, int n)
{
int i=0;
--n;
@@ -5301,23 +5304,7 @@ int stb_fullpath(char *abs, size_t abs_size, const char *rel)
#ifdef _MSC_VER
return _fullpath(abs, rel, abs_size) != NULL;
#else
if (abs[0] == '/' || abs[0] == '~') {
if ((size_t) strlen(rel) >= abs_size)
return 0;
strcpy(abs,rel);
return STB_TRUE;
} else {
size_t n;
getcwd(abs, abs_size);
n = strlen(abs);
if (n+(size_t) strlen(rel)+2 <= abs_size) {
abs[n] = '/';
strcpy(abs+n+1, rel);
return STB_TRUE;
} else {
return STB_FALSE;
}
}
return realpath(rel, abs) != NULL;
#endif
}

@@ -1,44 +1,22 @@
/*
* Bootloader for a packed executable.
* Copyright (C) 2009, Lorenzo Masini
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


void init_launcher(void);
int get_thisfile(char *thisfile, const char *programname);
#ifndef UTILS_H
#define UTILS_H


#ifdef WIN32
int CreateActContext(char *workpath, char *thisfile);
void ReleaseActContext(void);
int get_thisfilew(LPWSTR thisfilew);
#endif
void get_homepath(char *homepath, const char *thisfile);
void get_archivefile(char *archivefile, const char *thisfile);
int set_environment(const ARCHIVE_STATUS *status);
#ifndef WIN32
int spawn(const char *thisfile, char *const argv[]);
#else
int spawn(LPWSTR thisfile);
#endif


#endif /* UTILS_H */
@@ -1,32 +1,17 @@
/*
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/

/*
* A special version for minimal installs, where
* the bootstrap path is the directory in which
* the executable lives.
*
* Copyright (C) 2007, Daniele Varrazzo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

#ifndef PI_GETPATH_H

This file was deleted.

@@ -1,29 +1,16 @@
/*
* Bootloader for a DLL COM server.
* Copyright (C) 2005, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Bootloader for a DLL COM server.
*/


@@ -48,7 +35,8 @@
#include "pyi_archive.h"
#include "pyi_python.h"
#include "pyi_pythonlib.h"
#include "launch.h" // callSimpleEntryPoint
#include "pyi_launch.h" // callSimpleEntryPoint
#include "utils.h" // CreateActContext, ReleaseActContext


typedef int (__stdcall *__PROC__DllCanUnloadNow) (void);
@@ -148,11 +136,11 @@ int launch(ARCHIVE_STATUS *status, char const * archivePath, char const * archi
}
void startUp()
{
ARCHIVE_STATUS *status_list[20];
char thisfile[PATH_MAX + 1];
ARCHIVE_STATUS *archive_status;
char thisfile[PATH_MAX];
char *p;
int len;
memset(status_list, 0, 20 * sizeof(ARCHIVE_STATUS *));
memset(archive_status, 0, sizeof(ARCHIVE_STATUS *));

if (!GetModuleFileNameA(gInstance, thisfile, PATH_MAX)) {
FATALERROR("System error - unable to load!");
@@ -166,8 +154,8 @@ void startUp()
len = p - here;
//VS(here);
//VS(&thisfile[len]);
launch(status_list[SELF], here, &thisfile[len]);
LoadPythonCom(status_list[SELF]);
launch(archive_status, here, &thisfile[len]);
LoadPythonCom(archive_status);
// Now Python is up and running (any scripts have run)
}

@@ -1,31 +1,19 @@
/*
* Resource file for bootloader.
* Copyright (C) 2005, Giovanni Bajo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/


/*
* Resource file for bootloader.
*/


//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by launchw.rc
@@ -1,31 +1,18 @@
/*
* Bootloader for a packed executable.
* Copyright (C) 2009, Lorenzo Masini
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
* ****************************************************************************
* Copyright (c) 2013, PyInstaller Development Team.
* Distributed under the terms of the GNU General Public License with exception
* for distributing bootloader.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* The full license is in the file COPYING.txt, distributed with this software.
* ****************************************************************************
*/



// TODO move this code to file pyi_win32.c.


#define _WIN32_WINNT 0x0500


@@ -40,6 +27,7 @@
#include "stb.h"
#include "pyi_global.h" // PATH_MAX
#include "pyi_archive.h"
#include "pyi_path.h"
#include "pyi_utils.h"


@@ -66,7 +54,8 @@ int IsXPOrLater(void)

int CreateActContext(char *workpath, char *thisfile)
{
char manifestpath[PATH_MAX + 1];
char manifestpath[PATH_MAX];
char basename[PATH_MAX];
ACTCTX ctx;
BOOL activated;
HANDLE k32;
@@ -78,18 +67,18 @@ int CreateActContext(char *workpath, char *thisfile)
return 1;

/* Setup activation context */
strcpy(manifestpath, workpath);
strcat(manifestpath, pyi_path_basename(thisfile));
pyi_path_basename(basename, thisfile);
pyi_path_join(manifestpath, workpath, basename);
strcat(manifestpath, ".manifest");
VS("manifestpath: %s\n", manifestpath);
VS("LOADER: manifestpath: %s\n", manifestpath);

k32 = LoadLibrary("kernel32");
CreateActCtx = (void*)GetProcAddress(k32, "CreateActCtxA");
ActivateActCtx = (void*)GetProcAddress(k32, "ActivateActCtx");

if (!CreateActCtx || !ActivateActCtx)
{
VS("Cannot find CreateActCtx/ActivateActCtx exports in kernel32.dll\n");
VS("LOADER: Cannot find CreateActCtx/ActivateActCtx exports in kernel32.dll\n");
return 0;
}

@@ -100,17 +89,17 @@ int CreateActContext(char *workpath, char *thisfile)
hCtx = CreateActCtx(&ctx);
if (hCtx != INVALID_HANDLE_VALUE)
{
VS("Activation context created\n");
VS("LOADER: Activation context created\n");
activated = ActivateActCtx(hCtx, &actToken);
if (activated)
{
VS("Activation context activated\n");
VS("LOADER: Activation context activated\n");
return 1;
}
}

hCtx = INVALID_HANDLE_VALUE;
VS("Error activating the context\n");
VS("LOADER: Error activating the context\n");
return 0;
}

@@ -128,117 +117,31 @@ void ReleaseActContext(void)
DeactivateActCtx = (void*)GetProcAddress(k32, "DeactivateActCtx");
if (!ReleaseActCtx || !DeactivateActCtx)
{
VS("Cannot find ReleaseActCtx/DeactivateActCtx exports in kernel32.dll\n");
VS("LOADER: Cannot find ReleaseActCtx/DeactivateActCtx exports in kernel32.dll\n");
return;
}
__try
{
VS("Deactivating activation context\n");
VS("LOADER: Deactivating activation context\n");
if (!DeactivateActCtx(0, actToken))
VS("Error deactivating context!\n!");
VS("LOADER: Error deactivating context!\n!");

VS("Releasing activation context\n");
VS("LOADER: Releasing activation context\n");
if (hCtx != INVALID_HANDLE_VALUE)
ReleaseActCtx(hCtx);
VS("Done\n");
VS("LOADER: Done\n");
}
__except (STATUS_SXS_EARLY_DEACTIVATION)
{
VS("XS early deactivation; somebody left the activation context dirty, let's ignore the problem\n");
VS("LOADER: XS early deactivation; somebody left the activation context dirty, let's ignore the problem\n");
}
}

void init_launcher(void)
{
InitCommonControls();
}

int get_thisfile(char *thisfile, const char *programname)
{
if (!GetModuleFileNameA(NULL, thisfile, PATH_MAX)) {
FATALERROR("System error - unable to load!");
return -1;
}

return 0;
}

int get_thisfilew(LPWSTR thisfilew)
{
if (!GetModuleFileNameW(NULL, thisfilew, PATH_MAX)) {
FATALERROR("System error - unable to load!");
return -1;
}

return 0;
}

void get_homepath(char *homepath, const char *thisfile)
{
char *p = NULL;

strcpy(homepath, thisfile);
for (p = homepath + strlen(homepath); *p != '\\' && p >= homepath + 2; --p);
*++p = '\0';
}

void get_archivefile(char *archivefile, const char *thisfile)
// TODO This function is not called anywhere. Do we still need to init common controls? Or is it replaced by CreateActContext() function? Or is it safe to remove that?
static void init_launcher(void)
{
strcpy(archivefile, thisfile);
strcpy(archivefile + strlen(archivefile) - 3, "pkg");
InitCommonControls();
}

int set_environment(const ARCHIVE_STATUS *status)
{
return 0;
}

int spawn(LPWSTR thisfile)
{
SECURITY_ATTRIBUTES sa;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
int rc = 0;

// the parent process should ignore all signals it can
signal(SIGABRT, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGBREAK, SIG_IGN);

VS("Setting up to run child\n");
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
GetStartupInfoW(&si);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_NORMAL;
si.hStdInput = (void*)_get_osfhandle(fileno(stdin));
si.hStdOutput = (void*)_get_osfhandle(fileno(stdout));
si.hStdError = (void*)_get_osfhandle(fileno(stderr));

VS("Creating child process\n");
if (CreateProcessW(
thisfile, // pointer to name of executable module
GetCommandLineW(), // pointer to command line string
&sa, // pointer to process security attributes
NULL, // pointer to thread security attributes
TRUE, // handle inheritance flag
0, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
&si, // pointer to STARTUPINFO
&pi // pointer to PROCESS_INFORMATION
)) {
VS("Waiting for child process to finish...\n");
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, (unsigned long *)&rc);
} else {
FATALERROR("Error creating child process!\n");
rc = -1;
}
return rc;
}
@@ -1,23 +1,17 @@
#! /usr/bin/env python
# encoding: utf-8
#-----------------------------------------------------------------------------
# Copyright (c) 2013, PyInstaller Development Team.
#
# Bootloader building script.
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# Copyright (C) 2010-2012, Martin Zibricky
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------


"""
Bootloader building script.
"""


import os
@@ -50,6 +44,11 @@ def set_options(opt):
help = 'Prevent building LSB (Linux Standard Base) bootloader.',
default = False,
dest = 'nolsb')
opt.add_option('--leak-detector',
action = 'store_true',
help = 'Link with Boehm garbage collector to detect memory leaks.',
default = False,
dest = 'boehmgc')
opt.add_option('--lsbcc-path',
action = 'store',
help = 'Path to lsbcc. By default PATH is searched for lsbcc otherwise is tried file /opt/lsb/bin/lsbcc. [Default: lsbcc]',
@@ -227,6 +226,14 @@ def configure(conf):
if conf.check_cc(function_name='readlink', header_name='unistd.h'):
conf.env.append_value('CCFLAGS', '-DHAVE_READLINK')

# This uses Boehm GC to manage memory - it replaces malloc() / free()
# functions. Some messages are printed if memory is not deallocated.
if opt.boehmgc:
conf.check_cc(lib='gc', mandatory=True)
conf.env.append_value('CCDEFINES', 'PYI_LEAK_DETECTOR')
conf.env.append_value('CCDEFINES', 'GC_FIND_LEAK')
conf.env.append_value('CCDEFINES', 'GC_DEBUG')
conf.env.append_value('CCDEFINES', 'SAVE_CALL_CHAIN')

### ccflags

@@ -341,10 +348,12 @@ def configure(conf):


def build(bld):
opt = Options.options
# Force to run with 1 job (no parallel building).
# There are reported build failures on multicore CPUs
# with some msvc versions.
Options.options.jobs = 1
# TODO revisit parallel building with switch to waf 1.7
opt.jobs = 1

myplatform = Utils.detect_platform()
install_path = '../../PyInstaller/bootloader/' + platform.system() + "-" + bld.env.MYARCH
@@ -405,7 +414,7 @@ def build(bld):
for key, value in dict(release='inprocsrvr', debug='inprocsrvr_d').items():
bld(
features = 'cc cshlib',
source = bld.path.ant_glob('common/pyi_*.c common/launch.c windows/dllmain.c'),
source = bld.path.ant_glob('common/pyi_*.c windows/*.c'),
target = value,
install_path = install_path,
uselib_local = 'staticlib_zlib',
@@ -420,7 +429,7 @@ def build(bld):
for key, value in dict(releasew='inprocsrvrw', debugw='inprocsrvrw_d').items():
bld(
features = 'cc cshlib',
source = bld.path.ant_glob('common/pyi_*.c common/launch.c windows/dllmain.c'),
source = bld.path.ant_glob('common/pyi_*.c windows/*.c'),
target = value,
install_path = install_path,
uselib_local = 'staticlib_zlib',
@@ -432,13 +441,17 @@ def build(bld):

else: # linux, darwin (MacOSX)

libs = ['dl', 'z', 'm'] # 'z' - zlib, 'm' - math,
if opt.boehmgc:
libs.append('gc')

for key, value in targets.items():
bld(
features = 'cc cprogram',
source = bld.path.ant_glob('linux/*.c common/*.c'),
target = value,
install_path = install_path,
lib = ['dl', 'z', 'm'], # 'z' - zlib, 'm' - math,
lib = libs,
env = bld.env_of_name(key).copy(),
includes = ['common', 'linux'],
)
@@ -1,23 +1,17 @@
#! /usr/bin/env python
# encoding: utf-8
#-----------------------------------------------------------------------------
# Copyright (c) 2013, PyInstaller Development Team.
#
# Bootloader building script.
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# Copyright (C) 2010-2012, Martin Zibricky
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------


"""
Bootloader building script.
"""


# TODO Finish migration from waf 1.5 to 1.7 syntax.
@@ -22,9 +22,9 @@ exe = EXE(pyz,
a.datas,
a.dependencies,
name=os.path.join('dist', __testname__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
upx=False,
console=1 )

pyzB = PYZ(b.pure)
@@ -35,8 +35,8 @@ exeB = EXE(pyzB,
b.datas,
b.dependencies,
name=os.path.join('dist', __testdep__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
upx=False,
console=1 )

@@ -23,7 +23,7 @@ exe = EXE(pyz,
a.datas,
a.dependencies,
name=os.path.join('dist', __testname__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -35,7 +35,7 @@ exeB = EXE(pyzB,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testdep__,
__testdep__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -22,7 +22,7 @@ exe = EXE(pyz,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testname__,
__testname__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -43,7 +43,7 @@ exeB = EXE(pyzB,
b.datas,
b.dependencies,
name=os.path.join('dist', __testdep__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -22,7 +22,7 @@ exe = EXE(pyz,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testname__,
__testname__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -42,7 +42,7 @@ exeB = EXE(pyzB,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testdep__,
__testdep__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -27,7 +27,7 @@ exe = EXE(pyz,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testname__,
__testname__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -47,7 +47,7 @@ exeB = EXE(pyzB,
exclude_binaries=1,
name=os.path.join('build', 'pyi.'+sys.platform, __testdep__,
__testdep__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -68,7 +68,7 @@ exeC = EXE(pyzC,
c.datas,
c.dependencies,
name=os.path.join('dist', __testdep2__ + '.exe'),
debug=False,
debug=True,
strip=False,
upx=True,
console=1 )
@@ -321,7 +321,7 @@ def test_building(self):
Return True if build succeded False otherwise.
"""
OPTS = ['--debug']
OPTS = ['--debug', '--noupx']

if self.verbose:
OPTS.extend(['--debug', '--log-level=INFO'])
@@ -60,6 +60,8 @@ please let us know if your name is omitted by accident:

* Don Dwiggins - pyodbc import hook.

* Daniele Varrazzo - various bootloader and OS X fixes.

* Greg Copeland - sqlalchemy import hook.

* Seth Remington - PyGTK hook improvements.