Skip to content

Commit

Permalink
structure change: fixed build
Browse files Browse the repository at this point in the history
also did some further improvements/fixes all over the buildsystem
  • Loading branch information
mic-e committed Oct 8, 2014
1 parent b7af79f commit ee20ac0
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 49 deletions.
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
*.orig
__pycache__
resources
CMakeFiles
cmake_install.cmake
CMakeCache.txt
/bin
/.bin
lib
data/age
callgrind.out.*
perf.data*
.gdb_history
/Makefile
/Doxyfile
Makefile
CTestTestfile.cmake
CMakeFiles
cmake_install.cmake
CMakeCache.txt
23 changes: 13 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ project(openage C CXX)
# text art: figlet -f rounded "[SFT] openage" | sed -e 's/\\/\\\\/g'
message("")
message("==============================================================================")
message(" ___ ______ _______ _______ ___")
message(" ___ ______ _______ _______ ___")
message("| _)/ _____|_______|_______|_ |")
message("| | ( (____ _____ _ | | ___ ____ _____ ____ _____ ____ _____")
message("| | \\____ \\| ___) | | | | / _ \\| _ \\| ___ | _ \\(____ |/ _ | ___ |")
Expand All @@ -29,29 +29,32 @@ message(" * IRC: #sfttech at freenode.org")
message("==============================================================================")
message("")

set(BUILDSYSTEM_DIR "${CMAKE_SOURCE_DIR}/buildsystem")

# include build configuration modules
include("CTest")
include("buildsystem/python.cmake")
include("${BUILDSYSTEM_DIR}/python.cmake")
include("${BUILDSYSTEM_DIR}/cpp.cmake")
include("${BUILDSYSTEM_DIR}/version.cmake")
include("${BUILDSYSTEM_DIR}/doxygen.cmake")
include("${BUILDSYSTEM_DIR}/testing.cmake")

python_init()
include("buildsystem/cpp.cmake")
include("buildsystem/version.cmake")
include("buildsystem/doxygen.cmake")
include("buildsystem/testing.cmake")

# include source subdirectories
add_subdirectory("src")
add_subdirectory("convert")
add_subdirectory("cpp")
add_subdirectory("py")


# process the included python sources, generate setup.py
process_python_modules()

# generate Makefile
configure_file(${CMAKE_SOURCE_DIR}/Makefile.in ${CMAKE_SOURCE_DIR}/Makefile @ONLY)
configure_file(${BUILDSYSTEM_DIR}/templates/Makefile.in ${CMAKE_SOURCE_DIR}/Makefile @ONLY)

# show build configuration overview
message("CFLAGS = ${CMAKE_C_FLAGS}")
message("CXXFLAGS = ${CMAKE_CXX_FLAGS}")
message("LDFLAGS = ${CMAKE_EXE_LINKER_FLAGS}")
message("PREFIX = ${CMAKE_INSTALL_PREFIX}")
message("BUILDDIR = ${CMAKE_BINARY_DIR}")
# TODO add more messages
16 changes: 16 additions & 0 deletions Makefile.empty
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
all: error

install: error

clean: help

help: error
@echo "use 'make mrproper' to remove all traces of previous builds."

error:
@echo "error: you need to invoke ./configure first."

mrproper:
@buildsystem/wipe

.PHONY: all install clean help error mrproper
4 changes: 1 addition & 3 deletions buildsystem/cpp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ else() #"Intel", "MSVC", etc..
endif()

# these environment variables are used by the python C extension builder
set(CCENV "CC=${CMAKE_C_COMPILER}")
set(CXXENV "CXX=${CMAKE_CXX_COMPILER}")

set(COMPILERENV "CXX=${CMAKE_CXX_COMPILER} CC=${CMAKE_C_COMPILER}")

# output binary definition helpers.
# allows to add sources to a binary from anywhere.
Expand Down
2 changes: 1 addition & 1 deletion buildsystem/doxygen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if(DOXYGEN_FOUND)
endif()

# adapt doxygen config
configure_file(${CMAKE_SOURCE_DIR}/buildsystem/templates/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY)
configure_file(${BUILDSYSTEM_DIR}/templates/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile @ONLY)

# add doc target
add_custom_target(doc
Expand Down
36 changes: 20 additions & 16 deletions buildsystem/python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ function(python_init)
# that will contain the python source files for each package and C++ source files for each ext module.
# all of those lists will be used to generate setup.py in the generator function TODO

set(PYTHON3 ${PYTHON_EXECUTABLE} PARENT_SCOPE)
set(PYTHON_SOURCE_DIR "${CMAKE_SOURCE_DIR}/py")
set(PYTHON_SOURCE_DIR ${PYTHON_SOURCE_DIR} PARENT_SCOPE)

set(PYTHON3 ${PYTHON_EXECUTABLE})
set(PYTHON3 ${PYTHON3} PARENT_SCOPE)

set(PYTHON_INVOCATION ${PYTHON3} ${BUILDSYSTEM_DIR}/runinenv "PYTHONPATH=prependpath:${PYTHON_SOURCE_DIR}" -- ${PYTHON3})
set(PYTHON_INVOCATION ${PYTHON_INVOCATION} PARENT_SCOPE)
endfunction()


Expand All @@ -39,10 +46,9 @@ function(add_py_package name)
# this list of sourcefiles is not used directly for building,
# just for determining whether a re-build is neccesary.
string(REPLACE "." "/" package_path ${name})
file(GLOB package_sources "${CMAKE_SOURCE_DIR}/${package_path}/*.py")
file(GLOB package_sources "${PYTHON_SOURCE_DIR}/${package_path}/*.py")
set_property(GLOBAL PROPERTY SFT_PY_PACKAGE_${name})
foreach(sourcefile_abs ${package_sources})
file(RELATIVE_PATH sourcefile "${CMAKE_SOURCE_DIR}" "${sourcefile_abs}")
foreach(sourcefile ${package_sources})
message("\t${sourcefile}")
set_property(GLOBAL APPEND PROPERTY SFT_PY_PACKAGE_${name} "${sourcefile}")
endforeach()
Expand All @@ -63,12 +69,8 @@ function(add_pyext_module name)

# process the user-supplied list of C++ source files
set_property(GLOBAL PROPERTY SFT_PY_EXT_MODULE_${name})
file(RELATIVE_PATH current_path "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
foreach(sourcefile ${ARGN})
if(NOT ${current_path} EQUAL "")
set(sourcefile "${current_path}/${sourcefile}")
endif()

set(sourcefile "${CMAKE_CURRENT_SOURCE_DIR}/${sourcefile}")
message("\t${sourcefile}")
set_property(GLOBAL APPEND PROPERTY SFT_PY_EXT_MODULE_${name} "${sourcefile}")
endforeach()
Expand Down Expand Up @@ -122,26 +124,28 @@ function(process_python_modules)
set(ext_src "${ext_src}],\n")
endforeach()

set(SETUP_PY_IN "${CMAKE_SOURCE_DIR}/buildsystem/templates/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
set(PY_TIMEFILE "${CMAKE_CURRENT_BINARY_DIR}/build/py_mods")
set(SETUP_PY_IN "${BUILDSYSTEM_DIR}/templates/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/py/setup.py")
set(PY_TIMEFILE "${CMAKE_CURRENT_BINARY_DIR}/py/timefile")

set(SETUP_INVOCATION ${PYTHON3} ${BUILDSYSTEM_DIR}/runinenv ${COMPILER_ENV} -- ${PYTHON3} ${SETUP.PY})

# create setup.py file for python module creation
#
# * the time stamp file is used for rebuilding
# * all python-C extensions are built inplace
# * all python-C extensions are built in-place
# so they can be used for imports in the development tree
# * the pure python modules are compiled to pyc
configure_file(${SETUP_PY_IN} ${SETUP_PY})
add_custom_command(OUTPUT ${PY_TIMEFILE}
COMMAND ${CXXENV} ${CCENV} ${PYTHON3} ${SETUP_PY} build_ext --inplace
COMMAND ${CXXENV} ${CCENV} ${PYTHON3} ${SETUP_PY} build
COMMAND ${SETUP_INVOCATION} build_ext --inplace
COMMAND ${SETUP_INVOCATION} build
COMMAND ${CMAKE_COMMAND} -E touch ${PY_TIMEFILE}
DEPENDS ${all_sourcefiles})
add_custom_target(python_modules ALL DEPENDS ${PY_TIMEFILE})

# create call to setup.py when installing
# * set the install prefix at configure time
# * evaluate the temporary install destination parameter DESTDIR at 'make install'-time
install(CODE "execute_process(COMMAND ${PYTHON3} ${SETUP_PY} install --prefix=${CMAKE_INSTALL_PREFIX} --root=\$ENV{DESTDIR})")
install(CODE "execute_process(COMMAND ${SETUP_INVOCATION} install --prefix=${CMAKE_INSTALL_PREFIX} --root=\$ENV{DESTDIR})")
endfunction()
84 changes: 84 additions & 0 deletions buildsystem/runinenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python3
#
# simple wrapper helper script that will run programs in a modified
# environment
#
# basic usage:
# runinenv X=3 Y=eval:env['USER'].upper() PATH=appendpath:/sbin -- ls -la
#
# see the relevant code in lines 45... for details.

import os
import sys
import subprocess
import collections


def msg(msg, fail=False):
print("%s: %s" % (sys.argv[0], msg))
if fail:
exit(fail)


class KVPair:
def parse(self, s, *seps):
for sep in seps:
try:
k, v = s.split(sep, maxsplit=1)
except ValueError:
continue

if not k:
continue

self.k, self.v = k, v
return True

return False

# one of the rare cases where argparse is not the way to go
env = collections.defaultdict(lambda: "", os.environ)
invocation = []
parsing_done, verbose = False, False

kv = KVPair()
for pos, a in enumerate(sys.argv[1:]):
if parsing_done:
invocation.append(a)
elif a == '-v':
verbose = True
elif a == '--':
parsing_done = True
elif kv.parse(a, '=append:', '+='):
env[kv.k] = env[kv.k] + kv.v
elif kv.parse(a, '=prepend:'):
env[kv.k] = kv.v + env[kv.k]
elif kv.parse(a, '=eval:'):
env[kv.k] = eval(kv.v)
elif kv.parse(a, '=appendpath:'):
if not env[kv.k]:
env[kv.k] = kv.v
else:
env[kv.k] = env[kv.k] + os.pathsep + kv.v
elif kv.parse(a, '=prependpath:'):
if not env[kv.k]:
env[kv.k] = kv.v
else:
env[kv.k] = env[kv.k] + os.pathsep + kv.v
elif kv.parse(a, '=set:', '='):
env[kv.k] = kv.v
else:
msg("unexpected argument at position %d: %s " % (pos, a) +
"(expected assignment or '--')", fail=1)

if not invocation:
msg("expected command", fail=2)

if verbose:
msg("env=%s" % dict(env))
msg("invocation=%s" % invocation)

result = subprocess.call(invocation, env=dict(env))

if verbose and result > 0:
msg("failure (exit code == %d)" % result, fail=result)
2 changes: 1 addition & 1 deletion Makefile.in → buildsystem/templates/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ clean:

.PHONY: mrproper
mrproper:
rm -rf .bin bin data/age Makefile
@@BUILDSYSTEM_DIR@/wipe

.PHONY: help
help: bin/Makefile
Expand Down
26 changes: 17 additions & 9 deletions buildsystem/templates/setup.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,27 @@ py_packages = {${pkg_src}}
# a dict containing C++ extension module name: [c++ sources]
pyext_modules = {${ext_src}}

sourcedir = "${CMAKE_SOURCE_DIR}"
py_sourcedir = "${PYTHON_SOURCE_DIR}"

settings = {
"name": '${PROJECT_NAME}',
"version": '${PROJECT_VERSION}',
"description": '${PROJECT_NAME} python components',
"author": '[SFT]Tech',
"url": 'http://${PROJECT_NAME}.sft.mx',
"license": 'GPLv3+',
"package_dir": {'': '${CMAKE_SOURCE_DIR}'},
"package_dir": {'': py_sourcedir},
"packages": list(py_packages),
"ext_modules": [Extension(name=modname,
sources=['${CMAKE_SOURCE_DIR}/%s' % f for f in sources],
sources=sources,
extra_compile_args=pyext_cxxflags,
extra_link_args=pyext_linkflags,
language='c++')
for modname, sources in pyext_modules.items()]
}


def is_cmake_update_needed():
"""
check whether sources were added to or removed from any of the
Expand All @@ -45,29 +49,33 @@ def is_cmake_update_needed():
"""
result = False
for pkgname, knownsources in py_packages.items():
relsourcedir = pkgname.replace('.', '/')
sourcedir = "${CMAKE_SOURCE_DIR}/%s" % relsourcedir
actualsources = {relsourcedir + "/" + x for x in os.listdir(sourcedir) if x.endswith('.py')}
pkg_sourcedir = "%s/%s" % (py_sourcedir, pkgname.replace('.', '/'))
actualsources = {"%s/%s" % (pkg_sourcedir, f)
for f in os.listdir(pkg_sourcedir)
if f.endswith('.py')}
knownsources = set(knownsources)

if actualsources != knownsources:
if actualsources - knownsources:
print("the following sources have been added to %s: %s"
% (pkgname, ", ".join(actualsources - knownsources)))
print("the following sources have been added to %s:\n\t%s"
% (pkgname, "\n\t".join(actualsources - knownsources)))
if knownsources - actualsources:
print("the following sources have been removed from %s: %s"
% (pkgname, ", ".join(knownsources - actualsources)))
print("the following sources have been removed from %s:\n\t%s"
% (pkgname, "\n\t".join(knownsources - actualsources)))

result = True

return result


def trigger_cmake_update():
print("triggering cmake update")
try:
os.utime('${CMAKE_CURRENT_LIST_FILE}')
except FileNotFoundError:
print('error: file does not exist: ${CMAKE_CURRENT_LIST_FILE}')


if __name__ == '__main__':
if is_cmake_update_needed():
trigger_cmake_update()
Expand Down
9 changes: 9 additions & 0 deletions buildsystem/wipe
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
RM="rm -rf .bin bin data/age CMakeCache.txt CMakeFiles cmake_install.cmake"
MAKEFILE="cp Makefile.empty Makefile"

echo $RM
$RM

echo $MAKEFILE
$MAKEFILE
Loading

0 comments on commit ee20ac0

Please sign in to comment.