// -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. #include "configure.h" #include #include #include #include #include "settings.h" #include "execute.h" #include "libcppbuild.h" #include "tasks.h" std::filesystem::path configurationFile("configuration.cc"); std::filesystem::path configHeaderFile("config.h"); const std::map default_configuration{}; const std::map& __attribute__((weak)) configuration() { return default_configuration; } bool hasConfiguration(const std::string& key) { const auto& c = configuration(); return c.find(key) != c.end(); } const std::string& getConfiguration(const std::string& key, const std::string& defaultValue) { const auto& c = configuration(); if(hasConfiguration(key)) { return c.at(key); } return defaultValue; } /* Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print `checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for `--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or `..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/drumgizmo] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --enable-gui=backend Use specified gui backend. Can be x11, win32, cocoa, pugl-x11, pugl-win32, pugl-cocoa or auto [default=auto] --enable-custom-channel-count=count Compile with specified number of output channels [default=16] --enable-lv2 Compile the LV2 plugin [default=no] --enable-vst Compile the VST plugin [default=no] --enable-cli Compile the command line interface [default=yes] --disable-input-dummy Disable input dummy plugin [default=enabled] --disable-input-test Disable input test plugin [default=enabled] --disable-input-jackmidi Disable input jackmidi plugin [default=enabled] --disable-input-alsamidi Disable input alsamidi plugin [default=enabled] --disable-input-midifile Disable input midifile plugin [default=enabled] --disable-input-oss Disable input oss plugin [enabled by default on FreeBSD, disabled otherwise] --disable-output-dummy Disable output dummy plugin [default=enabled] --disable-output-jackaudio Disable output jack plugin [default=enabled] --disable-output-alsa Disable output alsa plugin [default=enabled] --disable-output-wavfile Disable output wavfile plugin [default=enabled] --disable-output-oss Disable output oss plugin [enabled by default on FreeBSD, disabled otherwise] --enable-sse=level Enable SSE Level 1, 2, 3 or auto [default=auto] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-debug Build with debug support --with-nls Build with nls support (default nls enabled) --with-test Build unit tests --with-lv2dir=DIR Use DIR as the lv2 plugin directory [default=LIBDIR/lv2] --with-vst-sources Point this to the vstsdk24 directory Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory OBJC Objective C compiler command OBJCFLAGS Objective C compiler flags OBJCXX Objective C++ compiler command OBJCXXFLAGS Objective C++ compiler flags CC C compiler command CFLAGS C compiler flags LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path X11_CFLAGS C compiler flags for X11, overriding pkg-config X11_LIBS linker flags for X11, overriding pkg-config XEXT_CFLAGS C compiler flags for XEXT, overriding pkg-config XEXT_LIBS linker flags for XEXT, overriding pkg-config LV2_CFLAGS C compiler flags for LV2, overriding pkg-config LV2_LIBS linker flags for LV2, overriding pkg-config SMF_CFLAGS C compiler flags for SMF, overriding pkg-config SMF_LIBS linker flags for SMF, overriding pkg-config SNDFILE_CFLAGS C compiler flags for SNDFILE, overriding pkg-config SNDFILE_LIBS linker flags for SNDFILE, overriding pkg-config JACK_CFLAGS C compiler flags for JACK, overriding pkg-config JACK_LIBS linker flags for JACK, overriding pkg-config ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config ALSA_LIBS linker flags for ALSA, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. */ int configure(int argc, char* argv[]) { Settings settings; settings.builddir = "build"; std::string cmd_str; for(int i = 0; i < argc; ++i) { if(i > 0) { cmd_str += " "; } cmd_str += argv[i]; } dg::Options opt; int key{256}; std::string build_arch; std::string build_path; std::string host_arch; std::string host_path; opt.add("build-dir", required_argument, 'b', "Set output directory for build files (default: '" + settings.builddir + "').", [&]() { settings.builddir = optarg; return 0; }); opt.add("verbose", no_argument, 'v', "Be verbose. Add multiple times for more verbosity.", [&]() { settings.verbose++; return 0; }); opt.add("build", required_argument, key++, "Configure for building on specified architecture.", [&]() { build_arch = optarg; return 0; }); opt.add("build-path", required_argument, key++, "Set path to build tool-chain.", [&]() { build_path = optarg; return 0; }); opt.add("host", required_argument, key++, "Cross-compile to build programs to run on specified architecture.", [&]() { host_arch = optarg; return 0; }); opt.add("host-path", required_argument, key++, "Set path to cross-compile tool-chain.", [&]() { host_path = optarg; return 0; }); opt.add("help", no_argument, 'h', "Print this help text.", [&]() { std::cout << "configure usage stuff\n"; opt.help(); exit(0); return 0; }); opt.process(argc, argv); if(host_arch.empty()) { host_arch = build_arch; } auto tasks = getTasks(settings); bool needs_cpp{false}; bool needs_c{false}; bool needs_ar{false}; bool needs_asm{false}; for(const auto& task :tasks) { switch(task->sourceLanguage()) { case Language::Auto: std::cerr << "TargetLanguage not deduced!\n"; exit(1); break; case Language::C: needs_cpp = false; break; case Language::Cpp: needs_c = true; break; case Language::Asm: needs_asm = true; break; } } // CC=clang // CXX=clang++ std::string path_env = std::getenv("PATH"); std::cout << path_env << "\n"; std::vector paths; { std::stringstream ss(path_env); std::string path; while (std::getline(ss, path, ':')) { paths.push_back(path); } } for(const auto& path_str : paths) { std::filesystem::path path(path_str); auto gcc = path / "gcc"; if(std::filesystem::exists(gcc)) { std::cout << "Found file gcc in path: " << path << "\n"; auto perms = std::filesystem::status(gcc).permissions(); if((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none) { std::cout << " - executable by owner\n"; } if((perms & std::filesystem::perms::group_exec) != std::filesystem::perms::none) { std::cout << " - executable by group\n"; } if((perms & std::filesystem::perms::others_exec) != std::filesystem::perms::none) { std::cout << " - executable by others\n"; } } } exit(0); { std::ofstream istr(configurationFile); istr << "#include \"libcppbuild.h\"\n\n"; istr << "const std::map& configuration()\n"; istr << "{\n"; istr << " static std::map c =\n"; istr << " {\n"; istr << " { \"cmd\", \"" << cmd_str << "\" },\n"; istr << " { \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; istr << " { \"" << cfg::target_cc << "\", \"/usr/bin/gcc\" },\n"; istr << " { \"" << cfg::target_cpp << "\", \"/usr/bin/g++\" },\n"; istr << " { \"" << cfg::target_ar << "\", \"/usr/bin/ar\" },\n"; istr << " { \"" << cfg::target_ld << "\", \"/usr/bin/ld\" },\n"; istr << " { \"" << cfg::host_cc << "\", \"/usr/bin/gcc\" },\n"; istr << " { \"" << cfg::host_cpp << "\", \"/usr/bin/g++\" },\n"; istr << " { \"" << cfg::host_ar << "\", \"/usr/bin/ar\" },\n"; istr << " { \"" << cfg::host_ld << "\", \"/usr/bin/ld\" },\n"; istr << " };\n"; istr << " return c;\n"; istr << "}\n"; } { std::ofstream istr(configHeaderFile); istr << "#pragma once\n\n"; istr << "#define HAS_FOO 1\n"; istr << "//#define HAS_BAR 1\n"; } return 0; }