scons build both static and shared library - scons

I am trying to build both a static and a shared library using the same sources with SCons.
Everything works fine if I just build one or the other, but as soon as I try to build both, only the static library is built.
My SConscript looks like:
cppflags = SP3_env['CPPFLAGS']
cppflags += ' -fPIC '
SP3_env['CPPFLAGS'] = cppflags
soLibFile = SP3_env.SharedLibrary(
target = "sp3",
source = sources)
installedSoFile = SP3_env.Install(SP3_env['SP3_lib_dir'], soLibFile)
libFile = SP3_env.Library(
target = "sp3",
source = sources)
installedLibFile = SP3_env.Install(SP3_env['SP3_lib_dir'], libFile)
I also tried SharedObject(sources) before the SharedLibrary (passing in the return from SharedObject, rather than sources), but it is no different. Same if I build the .a before the .so.
How do I work around this?

When the installation directory is not in or below the current directory, SCons does not behave as expected, as commented in the SCons Install method docs:
Note, however, that installing a file is still considered a type of
file "build." This is important when you remember that the default
behavior of SCons is to build files in or below the current directory.
If, as in the example above, you are installing files in a directory
outside of the top-level SConstruct file's directory tree, you must
specify that directory (or a higher directory, such as /) for it to
install anything there:
That is, you must invoke SCons with the install directory as a target (SP3_env['SP3_lib_dir'] in your case) in order for the installation to be executed. To simplify this, use env.Alias() as I do below.
When you invoke SCons, you should at least see that both the static and shared libraries are built in the local project dir. I would imagine, however, that SCons does not install them. Here is an example I made on Ubuntu that works:
env = Environment()
sourceFiles = 'ExampleClass.cc'
sharedLib = env.SharedLibrary(target='example', source=sourceFiles)
staticLib = env.StaticLibrary(target='example', source=sourceFiles)
# Notice that installDir is outside of the local project dir
installDir = '/home/notroot/projects/sandbox'
sharedInstall = env.Install(installDir, sharedLib)
staticInstall = env.Install(installDir, staticLib)
env.Alias('install', installDir)
If I execute scons with no targets, I get the following:
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o ExampleClass.o -c ExampleClass.cc
g++ -o ExampleClass.os -c -fPIC ExampleClass.cc
ar rc libexample.a ExampleClass.o
ranlib libexample.a
g++ -o libexample.so -shared ExampleClass.os
scons: done building targets.
Then I can install, executing scons with the install target, as follows:
# scons install
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "libexample.a" as "/home/notroot/projects/sandbox/libexample.a"
Install file: "libexample.so" as "/home/notroot/projects/sandbox/libexample.so"
scons: done building targets.
Or, you could just do it all with one command, first clean everything
# scons -c install
Then, do it all with just one command:
# scons install
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o ExampleClass.o -c ExampleClass.cc
g++ -o ExampleClass.os -c -fPIC ExampleClass.cc
ar rc libexample.a ExampleClass.o
ranlib libexample.a
g++ -o libexample.so -shared ExampleClass.os
Install file: "libexample.a" as "/home/notroot/projects/sandbox/libexample.a"
Install file: "libexample.so" as "/home/notroot/projects/sandbox/libexample.so"
scons: done building targets.

Related

Compile from .o Files to .dll File in Linux

Im trying to compile/link .o file(s) into a .dll file under Ubuntu...
i get it nearly to work but i have a problem with static linking these .o file(s) ...
Here is what ive done:
First i installed all dependencies ... then i build the following application:
https://github.com/Zeranoe/mingw-w64-build
On my Ubuntu.
After that i create the .o files from the application with normal "sudo make" command...
Now i had all .o file(s) ready ... then i modified the .o files with "dlltool" so now i have the opportunity to link them to a .dll file with "mingw" ... it works only in "shared mode" ... not in "static mode" ...
this is the working command:
sudo /home/robert/Downloads/mingw-32/x86_64/i686/bin/i686-w64-mingw32-g++ -shared -lmsvcrt -Wl,-subsystem,windows *.o -o phpcppdll.dll
and this is not working:
sudo /home/robert/Downloads/mingw-32/x86_64/i686/bin/i686-w64-mingw32-g++ -static -lmsvcrt -Wl,-subsystem,windows *.o -o phpcppdll.dll
and then i get the following error - with this command:
/home/robert/Downloads/mingw-32/x86_64/i686/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/bin/ld: /home/robert/Downloads/mingw-32/x86_64/i686/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o):crt0_c.c:(.text+0x3c): undefined reference to `WinMain#16'
collect2: error: ld returned 1 exit status
but i dont get further maybe you have an idea ...
Okay - i got it to work with the -nostartfiles flag ... but it dont make sense because all .dlls are not static ... but shared ...

Unable to build jsoncpp library in redhat with scons

I'm trying to build jsoncpp library in redhat with scons.
I follow the instructions but get no result.
I first install scons, then download the library source, decompress it and enter the directory.
Once in the library folder I've tried several options:
1)
jsoncpp-src-0.5.0 > scons SConstruct platform=linux-gcc
scons: Reading SConscript files ...
Using platform 'linux-gcc-4.8.1'
LD_LIBRARY_PATH = /work/gcsadm/ext/ACE+TAO/lib/linux:/work/dguerra/tests/lib/linux:/work/dguerra/examples/lib/linux:/work/dguerra/lib/linux:/work/gcsadm/lib/linux:/usr/local/lib64:/usr/lib64:/work/gcsadm/ext/CorbaScript/lib:/usr/local/ostoreBase/ostore/lib:/work/gcsadm/ext/gsl/lib/linux:/work/gcsadm/ext/fitsio/lib/linux:/work/gcsadm/ext/sla/lib/linux:/work/gcsadm/ext/wcs/lib/linux:/work/gcsadm/ext/xpa/lib/linux:/work/gcsadm/ext/tcsPK/lib/linux:/work/gcsadm/ext/jsoncpp/lib/linux:/work/gcsadm/ext/mysql-connector/lib/linux:/usr/local/bin:libs/linux-gcc-4.8.1
Building using PLATFORM = linux-gcc-4.8.1
scons: done reading SConscript files.
scons: Building targets ...
scons: Nothing to be done for `SConstruct'.
scons: done building targets.
2)
jsoncpp-src-0.5.0 > scons platform=linux-gcc
scons: Reading SConscript files ...
Using platform 'linux-gcc-4.8.1'
LD_LIBRARY_PATH = /work/gcsadm/ext/ACE+TAO/lib/linux:/work/dguerra/tests/lib/linux:/work/dguerra/examples/lib/linux:/work/dguerra/lib/linux:/work/gcsadm/lib/linux:/usr/local/lib64:/usr/lib64:/work/gcsadm/ext/CorbaScript/lib:/usr/local/ostoreBase/ostore/lib:/work/gcsadm/ext/gsl/lib/linux:/work/gcsadm/ext/fitsio/lib/linux:/work/gcsadm/ext/sla/lib/linux:/work/gcsadm/ext/wcs/lib/linux:/work/gcsadm/ext/xpa/lib/linux:/work/gcsadm/ext/tcsPK/lib/linux:/work/gcsadm/ext/jsoncpp/lib/linux:/work/gcsadm/ext/mysql-connector/lib/linux:/usr/local/bin:libs/linux-gcc-4.8.1
Building using PLATFORM = linux-gcc-4.8.1
scons: done reading SConscript files.
scons: Building targets ...
g++ -o buildscons/linux-gcc-4.8.1/src/jsontestrunner/main.o -c - W a l l -Iinclude -I. src/jsontestrunner/main.cpp
g++: error: W: No such file or directory
g++: error: a: No such file or directory
g++: error: l: No such file or directory
g++: error: l: No such file or directory
scons: *** [buildscons/linux-gcc-4.8.1/src/jsontestrunner/main.o] Error 1
scons: building terminated because of errors.
Any help would be greatly appreciated.
The '- W a l l' indicates that some string with content '-Wall' should have been passed as a array [ '-Wall' ]

makefile g++: fatal error: no input files

I am taking a C++ class right now and in an effort to embrace CS, I installed Linux Mint 15 (Olivia) and have been going through my homework and lectures on the command line and through vim. We recently went over makefile(s) and I am having an issue with g++. My makefile looks like this:
CXX = g++
CXXFLAGS += -pedantic-errors
CXXFLAGS += -g
OBJS =
SRCS = constructors.cpp
HEADERS =
#target: dependencies
# rule to build
#
constructors: ${OBJS} ${HEADERS}
${CXX} ${LDFLAGS} ${OBJS} -o constructors
${OBJS}: ${SRCS}
${CXX} ${CXXFLAGS} -c $(#:.o=.cpp)
When I run:
make constructors
I get the following message:
g++ -o constructors
g++: fatal error: no input files
compilation terminated.
make: *** [constructors] Error 4
I have constructors.cpp in the same folder and if I manually compile it, it works perfect. Any suggestions are greatly appreciated.
OBJS =
You... seem to be missing something here. Like some objects to build.

cmake fortran undefined reference to MAIN__ on linux

I trying to get a cmake build system working on linux. The project contains a bunch of executables and two libraries. One of the executables is first built as a library, then that library is linked with the object file containing the man subroutine. This was done because the rest of the executables depend on that library. The tricky part is that the main subroutine is defined inside a module that the rest of sources depend on so this needs to be compiled before the rest of the sources. The effect is that the main subroutine gets added to the resulting library. This seems to work fine on Mac OS X but, the linking state fails on Linux.
The cmake file for the failing part looks like
cmake_minimum_required (VERSION 2.8)
# Create an empty variable to hold all the source files.
set (vmec_sources "")
# Add subdirectory for all the sources.
add_subdirectory (Sources)
add_library (vmec STATIC ${vmec_sources})
add_dependencies (vmec stell)
# Define an executable and link all libraries.
add_executable (xvmec ${CMAKE_CURRENT_SOURCE_DIR}/Sources/General/vmec_main.f)
add_dependencies (xvmec vmec)
target_link_libraries (xvmec vmec stell)
if ((NOT ${NETCDF_C} STREQUAL "") AND (NOT ${NETCDF_F} STREQUAL ""))
target_link_libraries (xvmec ${NETCDF_C} ${NETCDF_F})
endif ()
When running cmake, everything configures fine and generates a make file when I run make Mac OS X everything works fine. When I run make on Linux it fails.
The output from the make VERBOSE=1 On Linux produces
Linking Fortran executable ../build/bin/xvmec
cd /home/user/reconstruction/VMEC2000 && /usr/bin/cmake -E cmake_link_script CMakeFiles/xvmec.dir/link.txt --verbose=1
/usr/bin/gfortran -cpp -D NETCDF -I /usr/include CMakeFiles/xvmec.dir/Sources/General/vmec_main.f.o -o ../build/bin/xvmec -rdynamic ../build/lib/libvmec.a ../build/lib/libstell.a /usr/lib/libnetcdf.so /usr/lib/libnetcdff.so
/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
make[2]: *** [build/bin/xvmec] Error 1
make[2]: Leaving directory `/home/user/reconstruction'
make[1]: *** [VMEC2000/CMakeFiles/xvmec.dir/all] Error 2
make[1]: Leaving directory `/home/user/reconstruction'
make: *** [all] Error 2
On Mac OS X, I get
Linking Fortran executable ../build/bin/xvmec
cd /Users/user/repo/trunk/VMEC2000 && "/Applications/CMake 2.8-8.app/Contents/bin/cmake" -E cmake_link_script CMakeFiles/xvmec.dir/link.txt --verbose=1
/usr/local/bin/gfortran -framework Accelerate -cpp -D DARWIN -D NETCDF -I /Users/user/NetCDF/include -O3 -ftree-vectorize -m64 -march=native -fomit-frame-pointer -falign-functions -mfpmath=sse CMakeFiles/xvmec.dir/Sources/General/vmec_main.f.o -o ../build/bin/xvmec ../build/lib/libvmec.a ../build/lib/libstell.a /Users/user/NetCDF/lib/libnetcdf.dylib /Users/user/NetCDF/lib/libnetcdff.dylib
"/Applications/CMake 2.8-8.app/Contents/bin/cmake" -E cmake_progress_report /Users/user/repo/trunk/CMakeFiles 100
[100%] Built target xvmec
The link line looks like it is linking all the same stuff in the correct order so I don't understand why this is failing on Linux.
Turns out I had the wrong file listed as containing the main method. It seems that later versions of gfortran can link 'MAIN__' from a inside a library while gfortran-4.4 cannot.

How to make libusb library visible to another program?

I am trying to compile hidapi library. In order to compile that, I need libusb-1.0. I've downloaded that, configured, made and installed to /usr/local/lib. But when I try to compile hidapi, it doesn't see libusb-1.0:
cc -Wall -g -c -I../hidapi pkg-config libusb-1.0 --cflags
hid-libusb.c -o hid-libusb.o -L/usr/local/lib Package libusb-1.0 was
not found in the pkg-config search path. Perhaps you should add the
directory containing `libusb-1.0.pc' to the PKG_CONFIG_PATH
environment variable No package 'libusb-1.0' found /bin/sh: cc: not
found make: * [hid-libusb.o] Error 127
How can I fix that?
(compilation happens on Synology NAS)
Since you installed to /usr/local/lib, pkg-config will not find your installation unless you set PKG_CONFIG_PATH appropriately
Try running:
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"
in your shell and then re-attempting to build your code

Resources