summaryrefslogtreecommitdiff
path: root/cmake/Modules/GrSwig.cmake
blob: 6055c6356920f77f41d39776b0933b905ababae6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Copyright 2010-2011 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio 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 3, or (at your option)
# any later version.
# 
# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.

if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
    return()
endif()
set(__INCLUDED_GR_SWIG_CMAKE TRUE)

include(GrPython)

########################################################################
# Build a swig target for the common gnuradio use case. Usage:
# GR_SWIG_MAKE(target ifile ifile ifile...)
#
# Set the following variables before calling:
#   - GR_SWIG_FLAGS
#   - GR_SWIG_INCLUDE_DIRS
#   - GR_SWIG_LIBRARIES
#   - GR_SWIG_SOURCE_DEPS
#   - GR_SWIG_TARGET_DEPS
########################################################################
macro(GR_SWIG_MAKE name)
    set(ifiles ${ARGN})

    #determine include dependencies for swig file
    execute_process(
        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/get_swig_deps.py
        "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
        OUTPUT_STRIP_TRAILING_WHITESPACE
        OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    )

    #append the specified include directories
    include_directories(${GR_SWIG_INCLUDE_DIRS})
    list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${GR_SWIG_SOURCE_DEPS})

    find_package(PythonLibs)
    include_directories(${PYTHON_INCLUDE_DIRS})

    #setup the swig flags with flags and include directories
    set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
    foreach(dir ${GR_SWIG_INCLUDE_DIRS})
        list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
    endforeach(dir)

    #set the C++ property on the swig .i file so it builds
    set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)

    #setup the actual swig library target to be built
    include(UseSWIG)
    SWIG_ADD_MODULE(${name} python ${ifiles})
    SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
    if(GR_SWIG_TARGET_DEPS)
        add_dependencies(${SWIG_MODULE_${name}_REAL_NAME} ${GR_SWIG_TARGET_DEPS})
    endif(GR_SWIG_TARGET_DEPS)

endmacro(GR_SWIG_MAKE)

########################################################################
# Install swig targets generated by GR_SWIG_MAKE. Usage:
# GR_SWIG_INSTALL(
#   TARGETS target target target...
#   [DESTINATION destination]
#   [COMPONENT component]
# )
########################################################################
macro(GR_SWIG_INSTALL)

    include(CMakeParseArgumentsCopy)
    CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})

    foreach(name ${GR_SWIG_INSTALL_TARGETS})
        install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
            DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
            COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
        )

        include(GrPython)
        GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
            DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
            COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
        )

        find_program(LIBTOOL libtool)
        if(LIBTOOL)
            include(CMakeMacroLibtoolFile)
            CREATE_LIBTOOL_FILE(${SWIG_MODULE_${name}_REAL_NAME} /${GR_SWIG_INSTALL_DESTINATION})
        endif(LIBTOOL)

    endforeach(name)

endmacro(GR_SWIG_INSTALL)

########################################################################
# Generate a python file that can determine swig dependencies.
# Used by the make macro above to determine extra dependencies.
# When you build C++, CMake figures out the header dependencies.
# This code essentially performs that logic for swig includes.
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "

import os, sys, re

include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')

def get_swig_incs(file_path):
    file_contents = open(file_path, 'r').read()
    return include_matcher.findall(file_contents, re.MULTILINE)

def get_swig_deps(file_path, level):
    deps = [file_path]
    if level == 0: return deps
    for inc_file in get_swig_incs(file_path):
        for inc_dir in include_dirs:
            inc_path = os.path.join(inc_dir, inc_file)
            if not os.path.exists(inc_path): continue
            deps.extend(get_swig_deps(inc_path, level-1))
    return deps

if __name__ == '__main__':
    ifiles = sys.argv[1].split(';')
    deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
    #sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
    print(';'.join(set(deps)))
")