Skip to content

Commit

Permalink
Fix issue with virtualenv being locked to specific system Python vers…
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrusdaboo committed Jul 22, 2015
1 parent 3381087 commit c1bc9c2
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 8 deletions.
23 changes: 15 additions & 8 deletions support/Apple.make
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ CS_GROUP = _calendar

build:: $(BuildDirectory)/$(Project)

build:: build-wrapper
build-wrapper: $(BuildDirectory)/python-wrapper

$(BuildDirectory)/python-wrapper: $(Sources)/support/python-wrapper.c
$(CC) $(Sources)/support/python-wrapper.c -o $(BuildDirectory)/python-wrapper

install:: install-python
install-python:: build
@#
Expand Down Expand Up @@ -85,18 +91,15 @@ install-python:: build
@#
@# Set up a virtual environment in Server.app; we'll install into that.
@# That creates a self-contained environment which has specific version of
@# (almost) all of our dependancies in it.
@# (almost) all of our dependencies in it.
@# Use --system-site-packages so that we use the packages provided by the
@# OS, such as PyObjC.
@# Use --always-copy because we want copies of, not links to, the system
@# python, as Server.app is an independent product train.
@#
@echo "Creating virtual environment...";
$(_v) $(RMDIR) "$(DSTROOT)$(CS_VIRTUALENV)";
$(_v) PYTHONPATH="$(BuildDirectory)/pytools/lib" \
"$(PYTHON)" -m virtualenv \
--system-site-packages \
--always-copy \
"$(DSTROOT)$(CS_VIRTUALENV)";
@#
@# Use the pip in the virtual environment (as opposed to pip in the OS) to
Expand Down Expand Up @@ -135,14 +138,18 @@ install-python:: build
$(_v) perl -i -pe "s|#PATH|export PYTHON=$(CS_VIRTUALENV)/bin/python;|" "$(DSTROOT)$(CS_VIRTUALENV)/bin/caldavd";
@echo "Stripping binaries...";
$(_v) find "$(DSTROOT)$(CS_VIRTUALENV)" -type f -name "*.so" -print0 | xargs -0 $(STRIP) -Sx;
@echo "Updating install location of Python library...";
$(_v) find "$(DSTROOT)$(CS_VIRTUALENV)/bin" -type f -name "python*" -print0 | \
xargs -0 -n 1 install_name_tool -change "@executable_path/../.Python" "$(CS_VIRTUALENV)/.Python";
$(_v) install_name_tool -id "$(CS_VIRTUALENV)/.Python" "$(DSTROOT)$(CS_VIRTUALENV)/.Python";
@echo "Putting comments into empty files...";
$(_v) find "$(DSTROOT)$(CS_VIRTUALENV)" -type f -size 0 -name "*.py" -exec sh -c 'printf "# empty\n" > {}' ";";
$(_v) find "$(DSTROOT)$(CS_VIRTUALENV)" -type f -size 0 -name "*.h" -exec sh -c 'printf "/* empty */\n" > {}' ";";

@#
@# Undo virtualenv so we use the python-wrapper
@#
@echo "Undo virtualenv...";
$(_v) cp "$(BuildDirectory)/python-wrapper" "$(DSTROOT)$(CS_VIRTUALENV)/bin"
$(_v) $(STRIP) -Sx "$(DSTROOT)$(CS_VIRTUALENV)/bin/python-wrapper"
$(_v) "$(Sources)/support/undo-virtualenv" "$(DSTROOT)$(CS_VIRTUALENV)"

install:: install-config
install-config::
$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)$(SIPP)$(ETCDIR)$(CALDAVDSUBDIR)";
Expand Down
47 changes: 47 additions & 0 deletions support/python-wrapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// python-wrapper.c
//
// Copyright © 2015 Apple Inc. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

const char* python = "/usr/bin/python2.7";
const char* bin = "/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer/bin";
const char* site = "/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer/lib/python2.7/site-packages";

// Prepend a path to the named environment variable
int prependToPath(const char* name, const char* prepend) {
const char* old_value = getenv(name);
char* new_value = NULL;
if (old_value == NULL) {
// No existing value - set to the prepend value
size_t max_length = strlen(prepend) + 1;
new_value = malloc(max_length);
strlcpy(new_value, prepend, max_length);
} else {
// Existing value - so prepend with a ":" in between
size_t max_length = strlen(old_value) + strlen(prepend) + 2;
new_value = malloc(max_length);
strlcpy(new_value, prepend, max_length);
strlcat(new_value, ":", max_length);
strlcat(new_value, old_value, max_length);
}
setenv(name, new_value, 1);
free(new_value);
return 0;
}

int main(int argc, const char * argv[]) {

// Update PATH and PYTHONPATH
prependToPath("PATH", bin);
prependToPath("PYTHONPATH", site);

// Launch real python
argv[0] = python;
return execvp(python, (char* const*)argv);
}
48 changes: 48 additions & 0 deletions support/undo-virtualenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh

##
# Copyright (c) 2015 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##

set -e
set -u

base="${1}";
if [ $# == 1 ]; then
appbase="/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer";
else
appbase="${2}";
fi;

# Remove python binaries
rm -f "${base}/bin/python";
rm -f "${base}/bin/python2";
rm -f "${base}/bin/python2.7";

# Remove unused virtualenv files
rm -f "${base}/.Python";
rm -f "${base}/include/python2.7";
rm -f "${base}/lib/python2.7/"*.py*;
rm -f "${base}/lib/python2.7/config";
rm -rf "${base}/lib/python2.7/distutils";
rm -f "${base}/lib/python2.7/encodings";
rm -f "${base}/lib/python2.7/lib-dynload";
rm -f "${base}/lib/python2.7/orig-prefix.txt";

# Create links
cd "${base}/bin"
ln -s "python-wrapper" "python";
ln -s "python-wrapper" "python2";
ln -s "python-wrapper" "python2.7";

0 comments on commit c1bc9c2

Please sign in to comment.