Cross package maker. DEB/RPM generation or conversion. Derived from jordansissel/fpm.

⌈⌋ ⎇ branch:  cross package maker


Check-in [294ea7da2a]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Switch to preprocess.py instead of GNU CPP.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 294ea7da2aa13e549a4181bb394bd15c63ecc4b8
User & Date: mario 2015-02-14 11:02:07
Context
2015-02-25
19:33
Assume src meta fields as UTF-8, fallback to L1 or ASCII. check-in: 0365fe62c5 user: mario tags: trunk
2015-02-14
11:02
Switch to preprocess.py instead of GNU CPP. check-in: 294ea7da2a user: mario tags: trunk
2015-02-13
13:39
Preprocessor filter for source-based packages. check-in: 662bafecd7 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Name change from lib/fpm/package/filter_cpp.rb to lib/fpm/package/filter_preprocess.rb.

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

#
# api: fpm
# title: Preprocessor
# description: Apply preprocessor on packaged source input files.
# version: 0.1


# type: rewrite
# category: source
#




# Note that it isn't meant for C/C++ at all; you'd still package up compiled

# binaries of course.
#
# Instead 'cpp' preprocessing here is intended for scripting languages without








# coherent build processing tools of their own. Allows to merge source files,
# or apply packaging variant settings.
# For instance for just injecting a -D VERSION=1.2.3 constant.

# 
#  → Use `-u cpp=php` to apply it for specific file extensions.
#  → Any `-I dir/file` can be used for including files or header directories.
#  → And `-D CONST=1` to inject custom defines.
#
# A few constants are predefined (__FPM_VERSION, __FPM_PACKAGE).


#

require "fpm/package"
require "fpm/util"
require "fileutils"
require "shellwords"

class FPM::Package::Filter_cpp < FPM::Package

  option "-I", "file/dir", "Preprocessor includes or directories", :asis => true, :hidden => true, :attribute_name => "cpp_include",
    :multivalued => true do |file| next (File.directory?(file = File.expand_path(file)) ? "-I#{file}" : "-i#{file}") end

  option "-D", "CONST=VAL", "Preprocessor definitions", :asis => true, :hidden => true, :attribute_name => "cpp_define",
    :multivalued => true do |d| next ("-D#{d}") end
  
  # run files through cpp
  def update(opts)
    incinc = ["-I/usr/include/php5/main", "-I/usr/include/ruby-2.0.0/"]
    includes = (attributes[:cpp_include] + incinc).join(" ")
    defdef = ["-D__FPM_VERSION=#{version}", "-D__FPM_PACKAGE=#{name}"]
    defines = (attributes[:cpp_define] + defdef).join(" ")

    ::Dir.chdir(staging_path) do
      opts.each do |ext|
        ::Dir.glob("**/*#{ext}") do |fn|
          cpp(fn, includes, defines)
        end
      end
    end
  end # def update

  # apply preprocessor macros
  def cpp(fn, includes, defines)
    # pipe to temparay file
    tmpfn = fn + ".tmp." + rand(36**10).to_s(36)
    %x[cpp -E -P -w -ansi -traditional-cpp -no-integrated-cpp -nostdinc #{includes} #{defines} #{Shellwords.escape(fn)} > #{Shellwords.escape(tmpfn)}]

    # move back to original filename
    if File.exist? tmpfn

      File.rename(tmpfn, fn)
    end
  end # def cpp




end


<

|
|
>
>



>
>
>
>
|
>
|

<
>
>
>
>
>
>
>
>
|
|
|
>





|
>
>







|

|
|

|


|

|

|




|








|
|
|
>

|
>



>
>
>
>
|
>
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
#

# title: Preprocessor
# description: Apply preprocessor on source input files.
# version: 0.2
# depends: bin:preprocess
# api: fpm
# type: rewrite
# category: source
#
# This update filter is intended solely for packaging scripting language apps,
# not as C/C++ build helper. In particular scripting languages without unified
# build processing tool chains can use C-style macros this way.
#
# Note that it utilizes "preprocess.py" instead of CPP (which conflicts with
# the comment syntax of most scripting languages). Therefore macros take the
# forms:
#

#     # #define X Y               (Perl, Python, PHP, Tcl, Ruby, Shell, Text)
#     # #ifdef X
#    // #elif "foo" in BAR        (Java, PHP, C++, C#, IDL)
#    // #include "file.h"
#    /* #undef Y */               (CSS, C, JavaScript)
#    /* #endif */
#  <!-- #if defined(Z) -->        (HTML, XML)
#
# This allows to utilize #include ".." or #ifdef chains to merge sources to
# packaging variants, or simply inject custom constants at generation time.
# One could just supply a -D VERSION=1.2.3 constant. (Two predefined constants
# are `__DIST_VERSION` and `__DIST_PACKAGE` btw.)
# 
#  → Use `-u cpp=php` to apply it for specific file extensions.
#  → Any `-I dir/file` can be used for including files or header directories.
#  → And `-D CONST=1` to inject custom defines.
#
# Obviously this is a workaround for Perl/PHP/Python/Ruby/etc. which could only
# runtime-load dependencies, but don't provide build tools (apart from scripted
# packagers) to conjoin source code etc.
#

require "fpm/package"
require "fpm/util"
require "fileutils"
require "shellwords"

class FPM::Package::Filter_preprocess < FPM::Package

  option "-I", "dir", "Preprocessor include directories", :asis => true, :hidden => true, :attribute_name => "cpp_include",
    :multivalued => true do |file| next ("-I#{File.expand_path(file)}") end

  option "-D", "CONST=VAL", "Preprocessor macro definitions", :asis => true, :hidden => true, :attribute_name => "cpp_define",
    :multivalued => true do |d| next ("-D#{d}") end
  
  # run files through preprocessor of sorts
  def update(opts)
    incinc = ["-I.", "-I#{staging_path}", "-I/usr/include/php5/main", "-I/usr/include/ruby-2.0.0"]
    includes = (attributes[:cpp_include] + incinc).join(" ")
    defdef = ["-D__DIST_VERSION=#{version}", "-D__DIST_PACKAGE=#{name}", "-D__DIST_ARCH=#{architecture}"]
    defines = (attributes[:cpp_define] + defdef).join(" ")

    ::Dir.chdir(staging_path) do
      opts.each do |ext|
        ::Dir.glob("**/*.#{ext}") do |fn|
          cpp(fn, includes, defines)
        end
      end
    end
  end # def update

  # apply preprocessor macros
  def cpp(fn, includes, defines)
    # write to temporary file
    tmpfn = fn + ".i.tmp." + rand(36**10).to_s(36)
       #%x[cpp -E -P -w -ansi -CC -traditional-cpp -no-integrated-cpp -nostdinc #{includes} #{defines} #{sh(fn)} -o #{sh(tmpfn)}]
    r = %x[preprocess -s #{includes} #{defines} -o #{sh(tmpfn)} #{sh(fn)}]
    # move back to original filename
    if File.size(tmpfn) > 0
      File.chmod(File.stat(fn).mode, tmpfn)
      File.rename(tmpfn, fn)
    end
  end # def cpp
  
  # shortcut
  def sh(s)
    Shellwords.escape(s)
  end
end