For example, I've a .c file as below:
$cat hello.c
int main(){
return 0;
}
Then I use scons to build and copy it to some place:
$cat SConstruct
import os,sys
env = Environment()
hello = env.Program('hello.c')
env.InstallAs('/home/admin/hello-new', hello)
run scons under user named 'admin' it prints:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o hello hello.o
scons: done building targets.
Then I tried to "ls /home/admin" there's no such a thing like "hello-new". So I wonder why my "env.InstallAs()" worked at all? How to trouble-shoot and fix it?
Thanks.
Please read the FAQ, this is a common misunderstanding about SCons and thus in the FAQ:
https://scons.org/faq.html#How_do_I_install_files.3F_The_Install.28.29_method_doesn.27t_do_anything._In_general.2C_how_do_I_build_anything_outside_my_current_directory.3F
With your example changing to this should cause it to always build the target in question:
import os,sys
env = Environment()
hello = env.Program('hello.c')
install_target = env.InstallAs('/home/admin/hello-new', hello)
# Always build the install target by default
Default(install_target)
Related
I work with project in which every object files is being built 3 times:
With newest g++ with lots of flags in order to find every possible errors and warnings
With clang in order to do as above and check style.
With g++ compatible with 3rdpart libraries (no newer version, but entire product is based of the libraries)
It works that way: if any object file should be recompiled: the steps 1, if success then 2, if success then 3 is being done. It is done with makefile, but I'm planning to use scons to do its. The problem is that in current solution object file from 1 and 2 is being saved into /dev/null.
I've tried something line this:
3 files in the same directory: hello.cc, Sconstruct, Sconscript
SConstruct
#!python
warningFlags = ' -Wall -Wextra -Werror' # and many more
env = Environment(CXX = 'g++-4.8', parse_flags = warningFlags, CPPPATH = '.')
builtObjects = env.SConscript('SConscript', variant_dir='built', duplicate=0, exports='env')
env.Program(target = 'hello', source = builtObjects)
SConscript
#!python
Import('env')
builtObjects = env.Object(source = 'hello.cc')
checkWithClang = env.Command('/dev/null', builtObjects, 'clang -o $TARGET -Wall -Werror')
env.Depends(checkWithClang, builtObjects)
Return('builtObjects')
The output from scons is:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: built
g++-4.8 -o built/hello.o -c -Wall -Wextra -Werror -Ibuilt -I. hello.cc
g++-4.8 -o hello built/hello.o
scons: done building targets.
EDIT:
Is it possible to somehow check in scons:
if object file should be rebuilt?
Pseudo code:
src = 'hello.cc'
if shouldObjectFileBeRebuilt(src):
checkWithClang = env.Command('/dev/null', builtObjects, 'clang -o $TARGET -Wall -Werror')
builtObjects = env.Object(source = src)
env.Depends(checkWithClang, builtObjects)
try
src = "hello.cc"
builtObjects = env.Object(source = src)
checkWithClang = env.Command('/dev/null', src, 'clang -o $TARGET -Wall -Werror')
env.Depends(builtObjects, checkWithClang)
buildobjects represent '.o' files, so you should put '.c' files to clang
you want buildObjects to be built after clang objects - change the order
Still - building into /dev/null will probably break dependency tree, you might consider something like:
checkWithClang = env.Object(source = src, CC="clang", OBJPREFIX="clang-")
this will build all .c files with clang and store extra .o files, allowing scons to rebuild only what is necessarry
I am trying to build a "hello world" D project with SConstruct and getting this output:
D:\projects\test>scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: warning: No version of Visual Studio compiler found - C/C++ compilers most likely not set correctly
File "C:\Python27\Scripts\scons.py", line 192, in <module>
scons: Building targets ...
dmd -I. -c -ofsrc\main.o src\main.d
dmd -ofhello.exe src\main.o
Error: unrecognized file extension o
scons: *** [hello.exe] Error 1
scons: building terminated because of errors.
Further I discovered that dmd compiler generates object files with the *.obj extension, rather then *.o and it is not able to handle with *.o files.
Is there a way to make SCons to use default output for dmd object files or to pass *.obj files extension for them? Or this is just a bug?
My SConstruct file:
import os
env = Environment(ENV=os.environ)
env.Object(target = 'hello', source = 'src/main.d')
My platform is Windows 7 x86_64.
dmd vervion is 2.064.2.
You need to tell SCons to use the D compiler, as I dont believe it does so by default. This does more than just load the compiler, it also sets the corresponding Construction Variables, which among other things sets the object file extension that you are asking about.
If you create your environment as follows, then the D compiler and related construction variables will be loaded.
env=Environment(tools=['default', 'dmd'])
i am trying to compile a c++ program in scons.
the scons works fine for c program but for c++ its giving the following error.
please can anybody help me about this, who knows about this?
first.cpp
#include <iostream>
int main()
{
std::cout << "hellooo" << std::endl;
return 0;
}
SConstructor
Program('first','first.cpp')
the error:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
o first.o -c first.cpp
sh: o: command not found
o first.exe first.o
sh: o: command not found
scons: done building targets.
what could be the problem in this?
You dont have a compiler for C++ installed, or at least SCons cant find it. Although you would expect SCons to explicitly tell you it cant find the compiler, I think what actually happens is it has a Construction Variable for the compiler that is actually empty, and it uses that to create the command line.
If you do indeed have it installed, you can fix this problem as follows:
env = Environment()
env.Replace(CXX = "/path/to/the/c++/compiler")
I have boost installed under /home/username/local/include. I want to compile a library with this set under CPPPATH.
SConstruct:
env = Environment(CPPPATH = '/home/username/local/include')
env.Library('MyLib', 'library.cpp')
library.cpp:
#include <boost/shared_ptr.hpp> // library.cpp:1:32: error: boost/shared_ptr.hpp: No such file or directory
void foo() { }
However, when I run scons, it gives the error error: boost/shared_ptr.hpp: No such file or directory.
Doing the same thing for a program works just fine.
SConstruct:
env = Environment(CPPPATH = '/home/username/local/include')
env.Program('program.cpp')
program.cpp:
#include <boost/shared_ptr.hpp> // works
int main() { return 0; }
What am I missing here?
EDIT
Here is the output:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o library.o -c -I/home/m/local/include library.cpp
library.cpp:1:32: error: boost/shared_ptr.hpp: No such file or directory
scons: *** [library.o] Error 1
scons: building terminated because of errors.
I can't reproduce your error on my system. Everything you have there looks right to me.
I created a faked out boost include setup, and used a different filename so it wouldn't accidentally reach into my real boost includes in /usr. I'm using SCons 2.0.1.
$ find /home/acm/local/include -type f
/home/acm/local/include/boost/not_a_boost_header.hpp
library.cpp:
#include <boost/not_a_boost_header.hpp>
void foo() { }
program.cpp:
#include <boost/not_a_boost_header.hpp>
int main() { return 0; }
SConstruct:
env1 = Environment(CPPPATH = '/home/acm/local/include')
env1.Library('MyLib', 'library.cpp')
env2 = Environment(CPPPATH = '/home/acm/local/include')
env2.Program('program.cpp')
Build results:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o library.o -c -I/home/acm/local/include library.cpp
ar rc libMyLib.a library.o
ranlib libMyLib.a
g++ -o program.o -c -I/home/acm/local/include program.cpp
g++ -o program program.o
scons: done building targets.
Can you post the complete SCons output?
I am going to write a Hello World module in Ubuntu 10.10 (with the kernel 2.6.35-28-generic). Headers are located:
/usr/src/linux-headers-2.6.35-28-generic
hello.c:
#include <linux/kernel.h>
#include <linux/module.h>
int init_module(void)
{
printk("Hello, world\n");
return 0;
}
void cleanup_module(void)
{
printk("Goodbye\n");
}
and Makefile:
CC = gcc
CFLAGS = -Wall -DMODULE -D__KERNEL__
hello.o: hello.c
$(CC) $(CFLAGS) -c hello.c
echo insmod hello.o to install
echo rmmod to delete
There is an error while make:
hello.c:1: fatal error: linux/kernel.h : No such file or directory
compilation terminated.
How do I solve this?
You can't just use a traditional-style Makefile with Linux kernel modules; while you might be able to force something to work, it'll be a painful experience.
Start by reading the Documentation/kbuild/modules.txt file; it'll describe exactly what you need to do when writing a module Makefile so that it can hook neatly into the kernel's Kbuild environment. Your Makefile will probably look something like this:
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := 8123.o
8123-y := 8123_if.o 8123_pci.o 8123_bin.o
else
# normal makefile
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
# Module specific targets
genbin:
echo "X" > 8123_bin.o_shipped
endif
Please trust me on this; while you might think you're "just one small change" from getting your own Makefile to work, even minor changes in kernel version will completely destroy your build all over again. Just take the hour now to write a Kbuild-compatible Makefile for your module. I wasted weeks of my life trying to maintain a pre-existing Makefile when the Kbuild infrastructure was introduced. Every new kernel caused me to lose hours of productivity.
For me this file ("linux/kernel.h") is in the package linux-libc-dev (Kubuntu 10.10).
Do you have /usr/src/linux symbolic link to your /usr/src/linux-headers-2.6.35-28-generic ?
If not then create one using following commands
# cd /usr/src
# ln -sfn linux-headers-2.6.35-28-generic linux
just as what #sarnold said , you should use the different Makefile.Just as following:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
and use the command:
insmod hello.ko
to install this module.