CMake: add WITH_LINKER_LLD option for unix platforms
[blender-staging.git] / source / creator / creator.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup creator
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #ifdef WIN32
28 #  include "utfconv.h"
29 #  include <windows.h>
30 #endif
31
32 #if defined(WITH_TBB_MALLOC) && defined(_MSC_VER) && defined(NDEBUG)
33 #  pragma comment(lib, "tbbmalloc_proxy.lib")
34 #  pragma comment(linker, "/include:__TBB_malloc_proxy")
35 #endif
36
37 #include "MEM_guardedalloc.h"
38
39 #include "CLG_log.h"
40
41 #include "DNA_genfile.h"
42
43 #include "BLI_args.h"
44 #include "BLI_string.h"
45 #include "BLI_system.h"
46 #include "BLI_threads.h"
47 #include "BLI_utildefines.h"
48
49 /* mostly init functions */
50 #include "BKE_appdir.h"
51 #include "BKE_blender.h"
52 #include "BKE_brush.h"
53 #include "BKE_cachefile.h"
54 #include "BKE_callbacks.h"
55 #include "BKE_context.h"
56 #include "BKE_font.h"
57 #include "BKE_global.h"
58 #include "BKE_gpencil_modifier.h"
59 #include "BKE_idtype.h"
60 #include "BKE_image.h"
61 #include "BKE_material.h"
62 #include "BKE_modifier.h"
63 #include "BKE_node.h"
64 #include "BKE_particle.h"
65 #include "BKE_shader_fx.h"
66 #include "BKE_sound.h"
67 #include "BKE_volume.h"
68
69 #include "DEG_depsgraph.h"
70
71 #include "IMB_imbuf.h" /* for IMB_init */
72
73 #include "RE_engine.h"
74 #include "RE_render_ext.h"
75
76 #include "ED_datafiles.h"
77
78 #include "WM_api.h"
79 #include "WM_toolsystem.h"
80
81 #include "RNA_define.h"
82
83 #ifdef WITH_FREESTYLE
84 #  include "FRS_freestyle.h"
85 #endif
86
87 #include <signal.h>
88
89 #ifdef __FreeBSD__
90 #  include <floatingpoint.h>
91 #endif
92
93 #ifdef WITH_BINRELOC
94 #  include "binreloc.h"
95 #endif
96
97 #ifdef WITH_LIBMV
98 #  include "libmv-capi.h"
99 #endif
100
101 #ifdef WITH_CYCLES_LOGGING
102 #  include "CCL_api.h"
103 #endif
104
105 #ifdef WITH_SDL_DYNLOAD
106 #  include "sdlew.h"
107 #endif
108
109 #include "creator_intern.h" /* own include */
110
111 /* Local Function prototypes. */
112 #ifdef WITH_PYTHON_MODULE
113 int main_python_enter(int argc, const char **argv);
114 void main_python_exit(void);
115 #endif
116
117 #ifdef WITH_USD
118 /**
119  * Workaround to make it possible to pass a path at runtime to USD.
120  *
121  * USD requires some JSON files, and it uses a static constructor to determine the possible
122  * file-system paths to find those files. This made it impossible for Blender to pass a path to the
123  * USD library at runtime, as the constructor would run before Blender's main() function. We have
124  * patched USD (see usd.diff) to avoid that particular static constructor, and have an
125  * initialization function instead.
126  *
127  * This function is implemented in the USD source code, pxr/base/lib/plug/initConfig.cpp.
128  */
129 void usd_initialise_plugin_path(const char *datafiles_usd_path);
130 #endif
131
132 /* written to by 'creator_args.c' */
133 struct ApplicationState app_state = {
134     .signal =
135         {
136             .use_crash_handler = true,
137             .use_abort_handler = true,
138         },
139     .exit_code_on_error =
140         {
141             .python = 0,
142         },
143 };
144
145 /* -------------------------------------------------------------------- */
146 /** \name Application Level Callbacks
147  *
148  * Initialize callbacks for the modules that need them.
149  *
150  * \{ */
151
152 static void callback_mem_error(const char *errorStr)
153 {
154   fputs(errorStr, stderr);
155   fflush(stderr);
156 }
157
158 static void main_callback_setup(void)
159 {
160   /* Error output from the alloc routines: */
161   MEM_set_error_callback(callback_mem_error);
162 }
163
164 /* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
165 struct CreatorAtExitData {
166   bArgs *ba;
167 #ifdef WIN32
168   const char **argv;
169   int argv_num;
170 #endif
171 };
172
173 static void callback_main_atexit(void *user_data)
174 {
175   struct CreatorAtExitData *app_init_data = user_data;
176
177   if (app_init_data->ba) {
178     BLI_argsFree(app_init_data->ba);
179     app_init_data->ba = NULL;
180   }
181
182 #ifdef WIN32
183   if (app_init_data->argv) {
184     while (app_init_data->argv_num) {
185       free((void *)app_init_data->argv[--app_init_data->argv_num]);
186     }
187     free((void *)app_init_data->argv);
188     app_init_data->argv = NULL;
189   }
190 #endif
191 }
192
193 static void callback_clg_fatal(void *fp)
194 {
195   BLI_system_backtrace(fp);
196 }
197
198 /** \} */
199
200 /* -------------------------------------------------------------------- */
201 /** \name Main Function
202  * \{ */
203
204 #ifdef WITH_PYTHON_MODULE
205 /* allow python module to call main */
206 #  define main main_python_enter
207 static void *evil_C = NULL;
208
209 #  ifdef __APPLE__
210 /* environ is not available in mac shared libraries */
211 #    include <crt_externs.h>
212 char **environ = NULL;
213 #  endif
214 #endif
215
216 /**
217  * Blender's main function responsibilities are:
218  * - setup subsystems.
219  * - handle arguments.
220  * - run #WM_main() event loop,
221  *   or exit immediately when running in background-mode.
222  */
223 int main(int argc,
224 #ifdef WIN32
225          const char **UNUSED(argv_c)
226 #else
227          const char **argv
228 #endif
229 )
230 {
231   bContext *C;
232
233 #ifndef WITH_PYTHON_MODULE
234   bArgs *ba;
235 #endif
236
237 #ifdef WIN32
238   char **argv;
239   int argv_num;
240 #endif
241
242   /* --- end declarations --- */
243
244   /* ensure we free data on early-exit */
245   struct CreatorAtExitData app_init_data = {NULL};
246   BKE_blender_atexit_register(callback_main_atexit, &app_init_data);
247
248   /* Unbuffered stdout makes stdout and stderr better synchronized, and helps
249    * when stepping through code in a debugger (prints are immediately
250    * visible). */
251   setvbuf(stdout, NULL, _IONBF, 0);
252
253 #ifdef WIN32
254   /* We delay loading of openmp so we can set the policy here. */
255 #  if defined(_MSC_VER)
256   _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
257 #  endif
258
259   /* Win32 Unicode Args */
260   /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
261    *       (it depends on the args passed in, which is what we're getting here!)
262    */
263   {
264     wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
265     argv = malloc(argc * sizeof(char *));
266     for (argv_num = 0; argv_num < argc; argv_num++) {
267       argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
268     }
269     LocalFree(argv_16);
270
271     /* free on early-exit */
272     app_init_data.argv = argv;
273     app_init_data.argv_num = argv_num;
274   }
275 #endif /* WIN32 */
276
277   /* NOTE: Special exception for guarded allocator type switch:
278    *       we need to perform switch from lock-free to fully
279    *       guarded allocator before any allocation happened.
280    */
281   {
282     int i;
283     for (i = 0; i < argc; i++) {
284       if (STR_ELEM(argv[i], "-d", "--debug", "--debug-memory", "--debug-all")) {
285         printf("Switching to fully guarded memory allocator.\n");
286         MEM_use_guarded_allocator();
287         break;
288       }
289       else if (STREQ(argv[i], "--")) {
290         break;
291       }
292     }
293   }
294
295 #ifdef BUILD_DATE
296   {
297     time_t temp_time = build_commit_timestamp;
298     struct tm *tm = gmtime(&temp_time);
299     if (LIKELY(tm)) {
300       strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
301       strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
302     }
303     else {
304       const char *unknown = "date-unknown";
305       BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
306       BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
307     }
308   }
309 #endif
310
311 #ifdef WITH_SDL_DYNLOAD
312   sdlewInit();
313 #endif
314
315   /* Initialize logging */
316   CLG_init();
317   CLG_fatal_fn_set(callback_clg_fatal);
318
319   C = CTX_create();
320
321 #ifdef WITH_PYTHON_MODULE
322 #  ifdef __APPLE__
323   environ = *_NSGetEnviron();
324 #  endif
325
326 #  undef main
327   evil_C = C;
328 #endif
329
330 #ifdef WITH_BINRELOC
331   br_init(NULL);
332 #endif
333
334 #ifdef WITH_LIBMV
335   libmv_initLogging(argv[0]);
336 #elif defined(WITH_CYCLES_LOGGING)
337   CCL_init_logging(argv[0]);
338 #endif
339
340   main_callback_setup();
341
342 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) && !defined(WITH_HEADLESS)
343   /* patch to ignore argument finder gives us (pid?) */
344   if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
345     extern int GHOST_HACK_getFirstFile(char buf[]);
346     static char firstfilebuf[512];
347
348     argc = 1;
349
350     if (GHOST_HACK_getFirstFile(firstfilebuf)) {
351       argc = 2;
352       argv[1] = firstfilebuf;
353     }
354   }
355 #endif
356
357 #ifdef __FreeBSD__
358   fpsetmask(0);
359 #endif
360
361   /* initialize path to executable */
362   BKE_appdir_program_path_init(argv[0]);
363
364   BLI_threadapi_init();
365   BLI_thread_put_process_on_fast_node();
366
367   DNA_sdna_current_init();
368
369   BKE_blender_globals_init(); /* blender.c */
370
371   BKE_idtype_init();
372   IMB_init();
373   BKE_cachefiles_init();
374   BKE_images_init();
375   BKE_modifier_init();
376   BKE_gpencil_modifier_init();
377   BKE_shaderfx_init();
378   BKE_volumes_init();
379   DEG_register_node_types();
380
381   BKE_brush_system_init();
382   RE_texture_rng_init();
383
384   BKE_callback_global_init();
385
386   /* First test for background-mode (#Global.background) */
387 #ifndef WITH_PYTHON_MODULE
388   ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
389
390   /* Ensure we free on early exit. */
391   app_init_data.ba = ba;
392
393   main_args_setup(C, ba);
394
395   BLI_argsParse(ba, 1, NULL, NULL);
396
397   main_signal_setup();
398
399 #else
400   /* Using preferences or user startup makes no sense for #WITH_PYTHON_MODULE. */
401   G.factory_startup = true;
402 #endif
403
404 #ifdef WITH_FFMPEG
405   IMB_ffmpeg_init();
406 #endif
407
408   /* After level 1 arguments, this is so #WM_main_playanim skips #RNA_init. */
409   RNA_init();
410
411   RE_engines_init();
412   init_nodesystem();
413   psys_init_rng();
414   /* end second init */
415
416 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
417   /* Python module mode ALWAYS runs in background-mode (for now). */
418   G.background = true;
419 #else
420   if (G.background) {
421     main_signal_setup_background();
422   }
423 #endif
424
425   /* Background render uses this font too. */
426   BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
427
428   /* Initialize ffmpeg if built in, also needed for background-mode if videos are
429    * rendered via ffmpeg. */
430   BKE_sound_init_once();
431
432   BKE_materials_init();
433
434 #ifdef WITH_USD
435   /* Tell USD which directory to search for its JSON files. If 'datafiles/usd'
436    * does not exist, the USD library will not be able to read or write any files. */
437   usd_initialise_plugin_path(BKE_appdir_folder_id(BLENDER_DATAFILES, "usd"));
438 #endif
439
440   if (G.background == 0) {
441 #ifndef WITH_PYTHON_MODULE
442     BLI_argsParse(ba, 2, NULL, NULL);
443     BLI_argsParse(ba, 3, NULL, NULL);
444 #endif
445     WM_init(C, argc, (const char **)argv);
446
447     /* This is properly initialized with user-preferences,
448      * but this is default.
449      * Call after loading the #BLENDER_STARTUP_FILE so we can read #U.tempdir */
450     BKE_tempdir_init(U.tempdir);
451   }
452   else {
453 #ifndef WITH_PYTHON_MODULE
454     BLI_argsParse(ba, 3, NULL, NULL);
455 #endif
456
457     WM_init(C, argc, (const char **)argv);
458
459     /* Don't use user preferences #U.tempdir */
460     BKE_tempdir_init(NULL);
461   }
462 #ifdef WITH_PYTHON
463   /**
464    * \note the #U.pythondir string is NULL until #WM_init() is executed,
465    * so we provide the BPY_ function below to append the user defined
466    * python-dir to Python's `sys.path` at this point.  Simply putting
467    * #WM_init() before #BPY_python_start() crashes Blender at startup.
468    */
469
470   /* TODO - U.pythondir */
471 #else
472   printf(
473       "\n* WARNING * - Blender compiled without Python!\n"
474       "this is not intended for typical usage\n\n");
475 #endif
476
477   CTX_py_init_set(C, true);
478   WM_keyconfig_init(C);
479
480 #ifdef WITH_FREESTYLE
481   /* Initialize Freestyle. */
482   FRS_initialize();
483   FRS_set_context(C);
484 #endif
485
486   /* OK we are ready for it */
487 #ifndef WITH_PYTHON_MODULE
488   main_args_setup_post(C, ba);
489 #endif
490
491   /* Explicitly free data allocated for argument parsing:
492    * - 'ba'
493    * - 'argv' on WIN32.
494    */
495   callback_main_atexit(&app_init_data);
496   BKE_blender_atexit_unregister(callback_main_atexit, &app_init_data);
497
498   /* Paranoid, avoid accidental re-use. */
499 #ifndef WITH_PYTHON_MODULE
500   ba = NULL;
501   (void)ba;
502 #endif
503
504 #ifdef WIN32
505   argv = NULL;
506   (void)argv;
507 #endif
508
509 #ifdef WITH_PYTHON_MODULE
510   /* Keep blender in background-mode running. */
511   return 0;
512 #endif
513
514   if (G.background) {
515     /* Using window-manager API in background-mode is a bit odd, but works fine. */
516     WM_exit(C);
517   }
518   else {
519     if (!G.file_loaded) {
520       WM_init_splash(C);
521     }
522   }
523
524   WM_main(C);
525
526   return 0;
527 } /* end of int main(argc, argv) */
528
529 #ifdef WITH_PYTHON_MODULE
530 void main_python_exit(void)
531 {
532   WM_exit_ex((bContext *)evil_C, true);
533   evil_C = NULL;
534 }
535 #endif
536
537 /** \} */