Is there any way to set environment variables for my system which scons will use, without me having to change the SConstruct file? For example, I would like to use MinGW instead of VC++ for my C++ builds on Windows. I can, of course, do this in my SConstruct file:
env = Environment(tools = ['mingw'])
But if I do that, then I'm editing things into my build files that make it specific to my particular system configuration. That defeats the whole purpose of a portable build system, in my opinion. If I upload that as part of my repository for others to build, they may not be using MinGW. They may want to use VC++, or Clang, and I don't think they should have to modify the build file (or anything else in the repository for that matter) in order to build the program or library. Ideally, anyone with in an environment with a functional C++ toolchain and scons installed should be able to just type scons on the command line, and things should go smoothly for them. Isn't that the (or a) goal of scons? Or am I misunderstanding its purpose?
Another thing is paths. The above line is not even enough, I have to still import the path to the MinGW binaries. I've read the justification for this. But it's just more system specific information which I have to put in my build files, which may be used by others where the chosen paths are not applicable.
I think you have indeed understood the purpose of SCons regarding it being portable and multi-platform :)
The issue here is if you have multiple compilers to choose from on your system, how to tell SCons which one to use. By default SCons will look for and use the compiler specific to your system (VC++ on windows or g++ on linux for example).
I can think of at least 2 ways of telling SCons which compiler to use, both of which will require extra logic in the build scripts, but can be done in a portable manner:
Environment variables
command line arguments
I would consider always using the system-specific compiler unless the user invokes scons with arguments/variables instructing it to use a different one.
If you choose to use Environment variables, you can just use standard python code, as follows, and explained here:
import os
some_var = os.environ['SOME_VAR']
Or, if you choose to use command line arguments, you can find everything you need here.
Personally, I would prefer command line options, as its more explicit than env vars. With env vars, the users may get undesired results due to env vars they didnt realize were set.
Try editing the file site_init.py in one of these directories:
%ALLUSERSPROFILE/Application Data/scons/site_scons
%USERPROFILE%/Local Settings/Application Data/scons/site_scons
%APPDATA%/scons/site_scons
%HOME%/.scons/site_scons
./site_scons
In that file, add a line like this:
DefaultEnvironment(tools = ['mingw'])
or maybe this:
DefaultEnvironment(tools = ['default', 'mingw'])
Related
I know that a lot of GNU applications use a config.h to set arguments for compile time options, like paths to resources with prefix from Autotools or Meson. For example, in some cases it is appropriate to find the location of the executable and load resources from there. Which I do on Windows and Linux. But for packaging on Linux and other UNIX based systems it seems better and usual to store the required paths inside config.h.
When and how to use config.h?
Thank you
It seems config.h is something worth thinking about and debated. There are some discussion here: and there:
Personally, I have not used it. I think the minimum is to rename it to YOURPACKAGE_config.h so that it will not be confused with another config.h from a different package.
I am fairly unused to compilation and building projects so pardon me if my approach to compilation and build seems a bit odd. Any tip is welcome.
I am currently working on a 3D geometry C++ project (Which is a dll). This project uses external dll's such as BOOST. So when building the project I have to define the directories in which the .dll, .lib and .h/.hpp files are.
Currently I am using scons to build the project and define those paths straight in the SConstruct file.
However those paths are later reused for other build operations. (In the present case compiling the C++ code in MEX for matlab but that's not really the point here).
Thus I currently have to define the same path in different places which is inefficient. In addition the project has to be easy to set up for another user. So having to change and update path in many different files is something I would like to avoid.
From where I stand I see two alternatives:
First I could ask the user to define environment variables and read them from inside my various build scripts. However I am not really satisfied with this solution for it asks the user for additional manipulation and, as far as I've understand, I lose the cross-platform portability that scons offers. (I know it might still possible but requires some extra steps and I'd like to keep things as simlpe as possible)
Second I could define all my path in a single .txt (or something similar) file at the root of my project and read it from my various build scripts. However this makes the process sensitive to typos and parsing errors which is not really to my taste.
So my question is the following:
Is there a better way or good practice to have the user input the paths necessary for compilation that satisfies the following:
Has the user only input once every path
Is done within the project folder through a file or something else
Is as foolproof as possible
Does not require too much additional download/installing (I don't really want to have the user install a brand new software for this. However I'm fine with something like a simple light .exe that I can add in my project files)
SCons's Variables are likely your best choice here.
See: https://scons.org/doc/production/HTML/scons-user.html#sect-command-line-variables
It allows reading defaults from a file:
vars = Variables('custom.py')
You'd have to craft some logic to save any variables specified on the command line.
I'm creating a Qt gui application using a library which searches the PATH environment variable for certain executables, namely compilers, make and cmake.
The problem is that std::getenv("PATH") returns something different in the gui and certain executables are missed. I've tried to use the QProcessEnvironment class to the set the PATH, however, the same problem arises. I can set it to specific paths in my machine but it would be great if it could get the PATH of any machine the application is deployed to.
Strangely if I start the gui using the command-line, everything works out fine! Although I find it unreasonable to ask users to open the gui using the command line.
Any help would be greatly appreciated.
This problem has nothing to do with Qt. You've set the PATH using shell initialization scripts and such, in your own user folder. It'd be a terribly bad idea for the graphical shell to use that path, as a mistake in your shell profile would potentially make the entire desktop non-functional. Of course it works from the command line, since your shell profiles take effect then.
You could, as a user configuration option, extract the shell PATH by running the equivalent of user's $SHELL -c 'echo $PATH', and processing the result.
Otherwise, you'll have to defer to what's customary on the platform, and consult package managers if needed. Different package systems tend to install these tools in different directories, but there is just a few common ones. I presume it'd be enough to cover Ubuntu, RedHat, macports and homebrew, and make sure that you check in "pure" FHS (Filesystem Hierarchy Standard) locations as well.
My question is the following:
Is there a way to tell CMakeFiles where to generate it's makefiles, such as cmake_install.cmake, CMakeCache.txt etc.?
More specifically, is there a way to set some commands in the CMakeFiles that specifies where to output these generated files? I have tried to search around the web to find some answers, and most people say there's no explicit way of doing this, while others say I might be able to, using custom commands. Sadly, I'm not very strong in cmake, so I couldn't figure this out.
I'm currently using the CLion IDE and there you can specifically set the output path through the settings, but for flexibility reasons I would like as much as possible to be done through the CMakeFiles such that compiling from different computers isn't that big of a hassle.
I would also like to avoid explicitly adding additional command line arguments etc.
I hope someone might have an answer for me, thanks in advance!
You can't (easily) do this and you shouldn't try to do it.
The build tree is CMake's territory. It allows you some tiny amount of customization there (for instance you can specify where the final build artifacts will be placed through the *_OUTPUT_DIRECTORY target properties), but it does not give you any direct control over where intermediate files, like object files or internal make scripts used for bookkeeping are being placed.
This is a feature. You have no idea how all the build systems supported by CMake work internally. Maybe you can move that internal file to a different location in your build process, which is based on Unix Makefiles. But maybe that will also horribly break my build process, which is using Visual Studio. The bottom line is: You shouldn't have to care about this. CMake should take care of it, and by taking some freedom away from you, it ensures that it can actually do that job on all supported build toolchains.
But this might still be an unsatisfactory answer to you. You're the developer, shouldn't you be in full control of the results produced by your build? Of course you should, which is why CMake again grants you full control over what goes into the install tree. That is, whatever ends up in the install directory when you call make install (or whatever is the equivalent of installing in your build toolchain) is again under your control.
So you do control everything that matters: The source tree, the install tree, and that tiny portion of the build tree where the final build artifacts go. The rest of the build tree is off-limits for you and for good reasons.
I'm trying to design an SConstruct file for an embedded system project. The compiler on my machine is at "C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\bin" I would like the build system to try to locate the toolchain even if there is another verison of Embedded Workbench installed, or if the user has chosen to install it elsewhere.
I'd also be interested in strategies used in makefiles or ant files since they are probably useful here as well.
What are some strategies for doing this? Do I have options other than searching the Windows registry or looking for "C:\Program Files\IAR Systems\Embedded Workbench *\arm\bin"?
The simplest solution is to use an environment variable. You still have to set that up manually for each build host, but the build system need only refer to the environment variable, so can be common for all build hosts.
For example in your case you might have:
EWBARM_V0504="C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\bin"
And similar for other versions installed, and then in your build system you would use %EWBARM_V0504% in place of the path. The worse that will happen is if the variable does not exist the build will fail, which is preferable to using the wrong compiler, and easily fixed.
Since different versions of toolchains may have different bugs and/or features, silently falling back onto different sets of tools is probably a bad idea. When I've supported multiple tools versions on a single project, I usually have the version number assigned via a makefile or the environment. Then you can pass -D TOOLS_VERSION=$(TOOLS_VERSION) to your compiler and use that value to key bugfixes and workarounds you need for particular versions of the tools. This system makes it clear which tools you want to support, while still making it easy for other developers to switch tool versions by making a single edit.
The nice thing about SCons is you have all of python at your disposal. So you can use win32.winreg to look in the registry, or glob around in sets of paths, whatever works for you. And of course you can have a command-line option or an options file to override the autodetection. Then once you've found your tool of choice, you have basically two ways to make SCons use it: either prepend the tool's dir to env['ENV']['PATH'] (you can use env.PrependEnvPath for that), or just use the tool's full path as the value of your $CC (and set $LINK, $SHLINK etc. appropriately too).
I usually make a TOOL_MYCOMPILER function that takes an env and sets it all up for use with the compiler and its toolchain (cpp, linker, whatever). It keeps things cleaner in your SConstruct/SConscript.