Build.PL 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use Devel::CheckLib;
  5. use ExtUtils::CppGuess;
  6. use Module::Build::WithXSpp;
  7. my $cpp_guess = ExtUtils::CppGuess->new;
  8. my $mswin = $^O eq 'MSWin32';
  9. # _GLIBCXX_USE_C99 : to get the long long type for g++
  10. # HAS_BOOL : stops Perl/lib/CORE/handy.h from doing "# define bool char" for MSVC
  11. # NOGDI : prevents inclusion of wingdi.h which defines functions Polygon() and Polyline() in global namespace
  12. # BOOST_ASIO_DISABLE_KQUEUE : prevents a Boost ASIO bug on OS X: https://svn.boost.org/trac/boost/ticket/5339
  13. my @cflags = qw(-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DSLIC3RXS -DBOOST_ASIO_DISABLE_KQUEUE -DGLEW_STATIC);
  14. my @ldflags = ();
  15. if ($^O eq 'darwin') {
  16. push @ldflags, qw(-framework IOKit -framework CoreFoundation);
  17. }
  18. if ($mswin) {
  19. # In case windows.h is included, we don't want the min / max macros to be active.
  20. # If <math.h> is included, we want the #defines to be active (M_PI etc.)
  21. push @cflags, qw(-D_WIN32 -DNOMINMAX -D_USE_MATH_DEFINES);
  22. }
  23. if (! $cpp_guess->is_msvc) {
  24. # Don't use the version flag on MS Visual Studio, as it starts to recognize them up to 2015 and it uses different syntax.
  25. push @cflags, qw(-std=c++11);
  26. }
  27. my @early_includes = ();
  28. my @INC = qw(-Isrc/libslic3r -Isrc/glew/include);
  29. my @LIBS = $cpp_guess->is_msvc ? qw(-LIBPATH:src/libslic3r) : qw(-Lsrc/libslic3r);
  30. if ($ENV{SLIC3R_GUI})
  31. {
  32. print "Slic3r will be built with GUI support\n";
  33. require Alien::wxWidgets;
  34. Alien::wxWidgets->load;
  35. push @INC, Alien::wxWidgets->include_path;
  36. push @cflags, qw(-DSLIC3R_GUI -DUNICODE), Alien::wxWidgets->defines, Alien::wxWidgets->c_flags;
  37. my $alienwx_libraries = Alien::wxWidgets->libraries(qw(gl html));
  38. $alienwx_libraries =~ s/-L/-LIBPATH:/g if ($cpp_guess->is_msvc);
  39. push @ldflags, Alien::wxWidgets->link_flags, $alienwx_libraries;
  40. # push @early_includes, qw(slic3r/GUI/wxinit.h);
  41. }
  42. if ($ENV{SLIC3R_PROFILE})
  43. {
  44. print "Slic3r will be built with a Shiny invasive profiler\n";
  45. push @cflags, qw(-DSLIC3R_PROFILE);
  46. }
  47. if ($ENV{SLIC3R_HAS_BROKEN_CROAK})
  48. {
  49. # Some Strawberry Perl builds (mainly the latest 64bit builds) have a broken mechanism
  50. # for emiting Perl exception after handling a C++ exception. Perl interpreter
  51. # simply hangs. Better to show a message box in that case and stop the application.
  52. push @cflags, qw(-DSLIC3R_HAS_BROKEN_CROAK)
  53. }
  54. # search for Boost in a number of places
  55. my @boost_include = ();
  56. if (defined $ENV{BOOST_INCLUDEDIR}) {
  57. push @boost_include, $ENV{BOOST_INCLUDEDIR}
  58. } elsif (defined $ENV{BOOST_DIR}) {
  59. my $subdir = $ENV{BOOST_DIR} . (($mswin == 1) ? '\include' : '/include');
  60. if (-d $subdir) {
  61. push @boost_include, $subdir;
  62. } else {
  63. push @boost_include, $ENV{BOOST_DIR};
  64. }
  65. } else {
  66. # Boost library was not defined by the environment.
  67. # Try to guess at some default paths.
  68. if ($mswin) {
  69. for my $path (glob('C:\dev\boost*\include'), glob ('C:\boost*\include')) {
  70. push @boost_include, $path;
  71. }
  72. if (! @boost_include) {
  73. # No boost\include. Try to include the boost root.
  74. for my $path (glob('C:\dev\boost*'), glob ('C:\boost*')) {
  75. push @boost_include, $path;
  76. }
  77. }
  78. } else {
  79. push @boost_include, grep { -d $_ }
  80. qw(/opt/local/include /usr/local/include /opt/include /usr/include);
  81. }
  82. }
  83. my @boost_libs = ();
  84. if (defined $ENV{BOOST_LIBRARYDIR}) {
  85. push @boost_libs, $ENV{BOOST_LIBRARYDIR}
  86. } elsif (defined $ENV{BOOST_DIR}) {
  87. my $subdir = $ENV{BOOST_DIR} . ($mswin ? '\stage\lib' : '/stage/lib');
  88. if (-d $subdir) {
  89. push @boost_libs, $subdir;
  90. } else {
  91. push @boost_libs, $ENV{BOOST_DIR};
  92. }
  93. } else {
  94. # Boost library was not defined by the environment.
  95. # Try to guess at some default paths.
  96. if ($mswin) {
  97. for my $path (
  98. glob('C:\dev\boost*\lib'), glob ('C:\boost*\lib'),
  99. glob('C:\dev\boost*\stage\lib'), glob ('C:\boost*\stage\lib')) {
  100. push @boost_libs, $path;
  101. }
  102. } else {
  103. push @boost_libs, grep { -d $_ }
  104. qw(/opt/local/lib /usr/local/lib /opt/lib /usr/lib /lib);
  105. }
  106. }
  107. # In order to generate the -l switches we need to know how Boost libraries are named
  108. my $have_boost = 0;
  109. my @boost_libraries = qw(system thread log); # we need these
  110. # check without explicit lib path (works on Linux)
  111. if (! $mswin) {
  112. $have_boost = 1
  113. if check_lib(
  114. lib => [ map "boost_${_}", @boost_libraries ],
  115. );
  116. }
  117. if (!$ENV{SLIC3R_STATIC} && $have_boost) {
  118. # The boost library was detected by check_lib on Linux.
  119. push @LIBS, map "-lboost_${_}", @boost_libraries;
  120. } else {
  121. # Either static linking, or check_lib could not be used to find the boost libraries.
  122. my $lib_prefix = 'libboost_';
  123. my $lib_ext = ${$cpp_guess}{config}{lib_ext};
  124. PATH: foreach my $path (@boost_libs) {
  125. # Try to find the boost system library.
  126. my @files = glob "$path/${lib_prefix}system*$lib_ext";
  127. next if !@files;
  128. if ($files[0] =~ /${lib_prefix}system([^.]+)$lib_ext$/) {
  129. # Suffix contains the version number, the build type etc.
  130. my $suffix = $1;
  131. # Verify existence of all required boost libraries at $path.
  132. for my $lib (map "${lib_prefix}${_}${suffix}${lib_ext}", @boost_libraries) {
  133. # If the library file does not exist, try next library path.
  134. -f "$path/$lib" or next PATH;
  135. }
  136. if (! $cpp_guess->is_msvc) {
  137. # Test the correctness of boost libraries by linking them to a minimal C program.
  138. check_lib(
  139. lib => [ map "boost_${_}${suffix}", @boost_libraries ],
  140. INC => join(' ', map "-I$_", @INC, @boost_include),
  141. LIBS => "-L$path",
  142. ) or next;
  143. }
  144. push @INC, (map " -I$_", @boost_include); # TODO: only use the one related to the chosen lib path
  145. if ($ENV{SLIC3R_STATIC} || $cpp_guess->is_msvc) {
  146. push @LIBS, map "${path}/${lib_prefix}$_${suffix}${lib_ext}", @boost_libraries;
  147. } else {
  148. push @LIBS, " -L$path", (map " -lboost_$_$suffix", @boost_libraries);
  149. }
  150. $have_boost = 1;
  151. last;
  152. }
  153. }
  154. }
  155. push @cflags, '-DBOOST_LIBS' if $have_boost;
  156. die <<'EOF' if !$have_boost;
  157. Slic3r requires the Boost libraries. Please make sure they are installed.
  158. If they are installed, this script should be able to locate them in several
  159. standard locations. If this is not the case, you might want to supply their
  160. path through the BOOST_DIR environment variable:
  161. BOOST_DIR=/path/to/boost perl Build.PL
  162. Or you may specify BOOST_INCLUDEPATH and BOOST_LIBRARYPATH separatly, which
  163. is handy, if you have built Boost libraries with mutliple settings.
  164. EOF
  165. # Add the OpenGL and GLU libraries.
  166. if ($ENV{SLIC3R_GUI}) {
  167. if ($mswin) {
  168. if ($cpp_guess->is_msvc) {
  169. push @LIBS, qw(OpenGL32.Lib GlU32.Lib);
  170. } else {
  171. push @LIBS, qw(-lopengl32);
  172. }
  173. } else {
  174. push @LIBS, qw(-lGL -lGLU);
  175. }
  176. }
  177. if ($ENV{SLIC3R_DEBUG}) {
  178. # only on newer GCCs: -ftemplate-backtrace-limit=0
  179. push @cflags, '-DSLIC3R_DEBUG';
  180. push @cflags, $cpp_guess->is_msvc ? '-Gd' : '-g';
  181. } else {
  182. # Disable asserts in the release builds.
  183. push @cflags, '-DNDEBUG';
  184. }
  185. if ($cpp_guess->is_gcc) {
  186. # check whether we're dealing with a buggy GCC version
  187. # see https://github.com/alexrj/Slic3r/issues/1965
  188. if (`cc --version` =~ m/ 4\.7\.[012]/) {
  189. # Workaround suggested by Boost devs:
  190. # https://svn.boost.org/trac/boost/ticket/8695
  191. push @cflags, qw(-fno-inline-small-functions);
  192. }
  193. }
  194. my $build = Module::Build::WithXSpp->new(
  195. module_name => 'Slic3r::XS',
  196. dist_abstract => 'XS code for Slic3r',
  197. build_requires => {qw(
  198. ExtUtils::ParseXS 3.18
  199. ExtUtils::Typemaps 1.00
  200. ExtUtils::Typemaps::Default 1.05
  201. ExtUtils::XSpp 0.17
  202. Module::Build 0.3601
  203. Test::More 0
  204. )},
  205. configure_requires => {qw(
  206. ExtUtils::CppGuess 0.07
  207. Module::Build 0.38
  208. Module::Build::WithXSpp 0.13
  209. )},
  210. extra_compiler_flags => [ @INC, @cflags ],
  211. extra_linker_flags => [ @LIBS, @ldflags ],
  212. # Provides extra C typemaps that are auto-merged
  213. extra_typemap_modules => {
  214. 'ExtUtils::Typemaps::Basic' => '1.05',
  215. },
  216. # for MSVC builds
  217. early_includes => [qw(
  218. cstring
  219. cstdlib
  220. ostream
  221. sstream
  222. libslic3r/GCodeSender.hpp
  223. ), @early_includes]
  224. );
  225. $build->create_build_script;
  226. __END__