1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 15 июл. 2019 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <core/types.h>
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 
29 #include <metadata/metadata.h>
30 #include <plugins/plugins.h>
31 #include <utils/common.h>
32 
33 namespace lsp
34 {
gen_cpp_file(const char * path,const plugin_metadata_t * meta,const char * plugin_name,const char * cpp_name)35     static int gen_cpp_file(const char *path, const plugin_metadata_t *meta, const char *plugin_name, const char *cpp_name)
36     {
37         char fname[PATH_MAX], cppfile[PATH_MAX];
38 
39         // Replace all underscores
40         strncpy(cppfile, cpp_name, PATH_MAX);
41         cppfile[PATH_MAX-1] = '\0';
42         for (char *p=cppfile; *p != '\0'; ++p)
43             if (*p == '_')
44                 *p = '-';
45 
46         snprintf(fname, PATH_MAX, "%s/%s", path, cppfile);
47 
48         printf("Generating source file %s\n", fname);
49 
50         // Generate file
51         FILE *out = fopen(fname, "w");
52         if (out == NULL)
53         {
54             int code = errno;
55             fprintf(stderr, "Error creating file %s, code=%d\n", fname, code);
56             return -1;
57         }
58 
59         // Write to file
60         fprintf(out,   "//------------------------------------------------------------------------------\n");
61         fprintf(out,   "// File:            %s\n", cpp_name);
62         fprintf(out,   "// JACK Plugin:     %s %s - %s [JACK]\n", LSP_ACRONYM, meta->name, meta->description);
63         fprintf(out,   "// JACK UID:        '%s'\n", meta->lv2_uid);
64         fprintf(out,   "// Version:         %d.%d.%d\n",
65                 LSP_VERSION_MAJOR(meta->version),
66                 LSP_VERSION_MINOR(meta->version),
67                 LSP_VERSION_MICRO(meta->version)
68             );
69         fprintf(out,   "//------------------------------------------------------------------------------\n\n");
70 
71         // Write code
72         fprintf(out,   "// Pass Plugin UID for factory function\n");
73         fprintf(out,   "#define JACK_PLUGIN_UID     \"%s\"\n\n", meta->lv2_uid);
74 
75         fprintf(out,   "// Include factory function implementation\n");
76         fprintf(out,   "#include <container/jack/main.h>\n\n");
77 
78         // Close file
79         fclose(out);
80 
81         return 0;
82     }
83 
gen_makefile(const char * path)84     int gen_makefile(const char *path)
85     {
86         char fname[PATH_MAX];
87         snprintf(fname, PATH_MAX, "%s/Makefile", path);
88         printf("Generating makefile %s\n", fname);
89 
90         // Generate file
91         FILE *out = fopen(fname, "w");
92         if (out == NULL)
93         {
94             int code = errno;
95             fprintf(stderr, "Error creating file %s, code=%d\n", fname, code);
96             return -2;
97         }
98 
99         fprintf(out, "# Auto generated makefile, do not edit\n\n");
100         fprintf(out, "MAKE_OPTS              += VERBOSE=$(VERBOSE)\n");
101         fprintf(out, "ifneq ($(VERBOSE),1)\n");
102         fprintf(out, ".SILENT:\n");
103         fprintf(out, "endif\n");
104         fprintf(out, "\n");
105 
106         fprintf(out, "FILES                   = $(patsubst %%.cpp, %%, $(wildcard *.cpp))\n");
107         fprintf(out, "FILE                    = $(@:%%=%%.cpp)\n");
108         fprintf(out, "\n");
109 
110         fprintf(out, ".PHONY: all\n\n");
111 
112         fprintf(out, "all: $(FILES)\n\n");
113 
114         fprintf(out, "$(FILES):\n");
115         fprintf(out, "\techo \"  $(CXX) $(FILE)\"\n");
116         fprintf(out, "\t$(CXX) -o $(@) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDE) $(FILE) $(EXE_FLAGS) $(DL_LIBS)\n\n");
117 
118         fprintf(out, "install: $(FILES)\n");
119         fprintf(out, "\t$(INSTALL) $(FILES) $(TARGET_PATH)/");
120 
121         // Close file
122         fclose(out);
123 
124         return 0;
125     }
126 
gen_make(const char * path)127     int gen_make(const char *path)
128     {
129         // Generate list of plugins as CPP-files
130         int code = 0;
131 
132         #define MOD_PLUGIN(plugin, ui)  \
133             if (code == 0) \
134             { \
135                 if (plugin::metadata.ui_resource != NULL) \
136                   code = gen_cpp_file(path, &plugin::metadata, #plugin, LSP_ARTIFACT_ID "-" #plugin ".cpp"); \
137             }
138 
139         #include <metadata/modules.h>
140 
141         // Generate makefile
142         if (code == 0)
143             code = gen_makefile(path);
144 
145         return code;
146     }
147 }
148 
149 #ifndef LSP_IDE_DEBUG
main(int argc,const char ** argv)150 int main(int argc, const char **argv)
151 {
152     if (argc <= 0)
153         fprintf(stderr, "required destination path");
154     return lsp::gen_make(argv[1]);
155 }
156 #endif /* LSP_IDE_DEBUG */
157