env.Clone() in scons doesn't do a deep-copy - scons

In a SCons script I create a base environment from which I derived others environments. Something like this :
base = Environment()
base['CXXFLAGS'] += ['-DBOOST_HAS_PTHREAD', '-D__STDC_CONSTANT_MACROS', '-DFILELOG_MAX_LEVEL=4', '-Wall']
opt = base.Clone()
opt['CXXFLAGS'] += ['-DNDEBUG', '-O3']
This way, I can create more environment (release/debug/instrumented/pgo) from the base environment. In the SCons documentation it's said that env.Clone() does a deep copy of env. But in fact it doesn't seem to work. because in the example, the base environment would have the -DNDEBUG and -O3 flags applied.
A I doing something wrong?
edit : Here is the real code. There is two print statements in this code and I think they should print the same things, but they don't. The output follows:
# -*- coding: utf-8 -*-
import os.path
import glob
local_env = Environment()
local_env['CXXFLAGS'] += ['-DBOOST_HAS_PTHREAD', '-D__STDC_CONSTANT_MACROS', '-DFILELOG_MAX_LEVEL=4', '-Wall']
local_env.Append(LIBS = ['pthread', 'boost_thread', 'boost_filesystem', 'boost_program_options', 'boost_iostreams'])
opt = local_env.Clone()
opt['CXXFLAGS'] += ['-DNDEBUG', '-O3']
print opt['CXXFLAGS']
instr = opt.Clone()
instr['CXXFLAGS'] += ['-fprofile-arcs']
instr['LIBS'] += ['gcov']
print opt['CXXFLAGS']
The output :
|| scons: Reading SConscript files ...
|| -DBOOST_HAS_PTHREAD -D__STDC_CONSTANT_MACROS -DFILELOG_MAX_LEVEL=4 -Wall -DNDEBUG -O3
|| -DBOOST_HAS_PTHREAD -D__STDC_CONSTANT_MACROS -DFILELOG_MAX_LEVEL=4 -Wall -DNDEBUG -O3 -fprofile-arcs
|| scons: done reading SConscript files.
|| scons: Building targets ...
|| scons: `.' is up to date.
|| scons: done building targets.
Edit 2:
It's a bug with SCons http://scons.tigris.org/issues/show_bug.cgi?id=2390
Edit 3:
Will be fixed in 1.3.1 and 2.0.1

I faced this today, and it seems like an SCons bug. Things used to work.
Facing this on: Ubuntu 9.04 x64, Python 2.6.2, SCons v1.2.0.r3842
Presuming it is a change of API between 0.9.8 and 1.2.0 here is how to overcome it.
Was:
e2= env.Clone()
e2["CXXFLAGS"].remove( "-Werror" )
e2["CXXFLAGS"].append( "-Wno-error" )
Now (1.2.0):
import copy
...
e2= env.Clone( CXXFLAGS= copy.deepcopy(env["CXXFLAGS"]) )
e2["CXXFLAGS"].remove( "-Werror" )
e2.AppendUnique( CXXFLAGS= "-Wno-error" )
Note that using the .Append() or .AppendUnique() methods treats the lists separately, not changing the original source. However, there does not seem to be such a method to remove a particular item from a list. This is why the '.remove()' is needed and that causes the headache.
Suggestions for easier methods or a pointer to knowing wheather this is a bug or feature of SCons 1.2.0 would be welcome.

Assuming this is a Scons issue (code/docs discrepancy), what about adding
import copy
at the script's head, and using
opt = copy.deepcopy(Base)
i.e exploiting the fact that Scons is in Python...?

Related

Qt no such file or directory 'atomic' on linux bullseye

Im having problem when i build a fresh project , nothing was added/ remove; i get an error no such file or directory 'atomic'
So i investigate a bit and i kind of found the culprit on the makefile. on line 43
line 43: LIBS = $(SUBLIBS) /opt/Qt/6.2.3-armv7l/lib/libQt6Quick.so /opt/Qt/6.2.3-armv7l/lib/libQt6OpenGL.so /opt/Qt/6.2.3-armv7l/lib/libQt6Gui.so -lEGL /opt/Qt/6.2.3-armv7l/lib/libQt6QmlModels.so /opt/Qt/6.2.3-armv7l/lib/libQt6Qml.so -pthread /opt/Qt/6.2.3-armv7l/lib/libQt6Network.so /opt/Qt/6.2.3-armv7l/lib/libQt6Core.so -latomic -lpthread -lGLESv2 atomic
removing word "atomic" at the end removes the error but im not sure if this is the right thing to do as it might cause some weird bugs under the hood. Qt says the line causing the error is line 228
line 227: untitled: $(OBJECTS)
line 228: $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
How do i properly solve this issue?
I am using qt 6.2
Since this is a fresh unmodified project the .pro is also at default
QT += quick
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
It seems that you are building Qt6 on a Raspberry PI, which isn't an official supported platform.
Does removing atomic may result in some weird bugs?
No, that shouldn't be the case. A missing needed libraries would result in a link time error, not a runtime error.
Off course, since Raspberry PI isn't a supported platform, weird things may happen because it is not (well) tested on this platform, but this will not be related to removing the atomic library.
It seems to me a bug in the Makefile generation code, as library are normally specified using the -l option (which searches for the lib in the specified library search path), instead of providing the relative path to the library. As pointed out in the comments -latomic is also specified. So, atomic seems to be unneeded.
Why does Qt report the error at line 228?
Because this is the line that generates the full linker statement that is being executed. Line 43 is included by $(LIBS).
Tracking the root cause
Searching for atomic inside your (modified) source code of Qt may point you why this library is added to the LIBS variable. The best solution is to remove it at that place.
Relevant resources
Note that this issue is already discussed here.

Cmake vcpkg and Bullet

I am very much lost here and could really use some help.
I'm working on an Honours project for next year that involves a physics simulation using Bullet and Vulkan for rendering. After a few months of work I have most of the project functioning. It needs a lot of refactoring and cleaning which will be the next stage.
I have been using a makefile but wish to migrate to CMake for a few reasons. Mainly because it seems to be the standard and because I want to compile for different OS's in the future (I'm running Linux but may need to deploy on Windows or Mac). Finally, I was recompiling the whole project for even a small change, which was beginning to become a problem as I started Unit Testing more.
The old makefile is as follows :
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
OWN_INCLUDES = \
-I$(ROOT_DIR)/src/Domain \
-I$(ROOT_DIR)/src/Vk \
-I$(ROOT_DIR)/src/Ui \
-I$(ROOT_DIR)/src/Service
ADD_INCLUDES = \
-I/opt/bullet3-master/src \
-I/opt/vk_mem_alloc \
-I/opt/stb_image \
-I/opt/tiny_obj_loader/ \
-I/opt/imgui-vulkan/
BULLET_INCLUDE_PATHS_LIBS = -L/opt/bullet3-master/src/BulletCollision/ \
-L/opt/bullet3-master/src/BulletDynamics/ \
-L/opt/bullet3-master/src/LinearMath/ \
-lBulletDynamics -lBulletCollision -lLinearMath
VULKAN_SDK_PATH = /opt/Vulkan_SDK/1.2.162.1/x86_64
CFLAGS = -std=c++17 -I$(VULKAN_SDK_PATH)/include $(OWN_INCLUDES) $(ADD_INCLUDES)
LDFLAGS = -L$(VULKAN_SDK_PATH)/lib `pkg-config --static --libs glfw3` -lvulkan $(BULLET_INCLUDE_PATHS_LIBS)
IMGUI_CPP_PATHS = /opt/imgui-vulkan/*.cpp
OWN_CPP_PATHS = src/*.cpp src/Domain/*.cpp src/Vk/*.cpp src/Ui/*.cpp src/Service/*.cpp
###### Unit Testing Paths
UNIT_TEST_INCLUDE = -I/opt/catch-header/
UNIT_TESTS_PATH = $(ROOT_DIR)/unit_tests/*.cpp
VulkanRun: $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS)
g++ $(CFLAGS) -o VulkanRun $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS) $(LDFLAGS)
Unit_Test: $(UNIT_TESTS_PATH) src/Domain/*.cpp src/Vk/*.cpp src/Ui/*.cpp src/Service/*.cpp $(IMGUI_CPP_PATHS)
g++ $(UNIT_TEST_INCLUDE) $(CFLAGS) -o Unit_Test $(UNIT_TESTS_PATH) src/Domain/*.cpp src/Vk/*.cpp src/Ui/*.cpp src/Service/*.cpp $(IMGUI_CPP_PATHS) $(LDFLAGS)
VulkanDebug: $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS)
g++ $(CFLAGS) -g -o VulkanDebug $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS) $(LDFLAGS)
VulkanOpt: $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS)
g++ $(CFLAGS) -O3 -o VulkanOpt $(OWN_CPP_PATHS) $(IMGUI_CPP_PATHS) $(LDFLAGS)
.PHONY: test clean
run: VulkanRun
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib
VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/vulkan/explicit_layer.d
./VulkanRun
test: Unit_Test
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib
VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/vulkan/explicit_layer.d
./Unit_Test
debug: VulkanDebug
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib
VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/vulkan/explicit_layer.d
optimise: VulkanOpt
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib
VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/vulkan/explicit_layer.d
./VulkanOpt
7 clean:
rm -f VulkanRun
rm -f Unit_Test
rm -f VulkanDebug
rm -f VulkanOpt
I installed cmake using the latest install script for 3.21.0.
I created a CMakeLists.txt in the root of the project as follows :
cmake_minimum_required(VERSION 3.21.0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
project(LanderSim)
file(GLOB_RECURSE SOURCES "src/**.cpp")
add_executable(main ${SOURCES})
find_package(Bullet CONFIG REQUIRED)
if (BULLET_FOUND)
include_directories(${BULLET_INCLUDE_DIRS})
target_link_libraries(main PRIVATE LinearMath Bullet3Common BulletDynamics BulletSoftBody)
endif (BULLET_FOUND)
After many hours of trying I decided to try vcpkg. Following the install instructions from bullet :
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install bullet3
This resulted in errors of
CMake Error at CMakeLists.txt:11 (find_package):
Could not find a package configuration file provided by "Bullet" with any
of the following names: BulletConfig.cmake bullet-config.cmake
Looking in CMakeCache.txt i see "Bullet_DIR:PATH=Bullet_DIR-NOTFOUND"
I found the BulletConfig.make file in "/home/ash/vcpkg/installed/x64-linux/share/bullet3" and in "/home/ash/vcpkg/packages/bullet3_x64-linux/share/bullet3" and set the MakeCache.txt var Bullet_DIR:PATH to these variables (tested one at a time).
Running again I get CMake set_and_check() function not recognised. Or something to that effect. Looking in the BulletConfig.make file I see these set_and_check() functions aren't recognised by the linter. I cant find any information about them being deprecated online but I assume this is the case. So I change to set() and CMake then succeeds and builds its files.
Running make I then get an error.
fatal error: btBulletDynamicsCommon.h: No such file or directory,
#include <btBulletDynamicsCommon.h>
I tried prepending bullet/ to the include path as others had this issue but it causes the same error.
So I must be doing something wrong and I'm obviously not understanding the process that CMake uses to add includes and link libraries. I'm sure, given the popularity of CMake, that there must be something obvious. But I've spent about 10 hours over a few days searching and trying different variations and I'm starting to get very frustrated.
I've bounced off CMake before (hence why I was working with a makefile for months), but I'm determined to do this properly. I just could really use some help if anyone knows how to get CMake to generate a makefile that can see a package installed with vcpkg.
Or indeed if the vcpkg of Bullet is out of date, then a way to link and include it with CMake alone would be great. I just thought vcpkg would be easier as it provides a cleaner file structure by default as well as a CMake config file.
Thanks.
EDIT1
I've used 'cmake .' and 'cmake . -DCMAKE_TOOLCHAIN_FILE=/home/ash/vcpkg/scripts/buildsystems/vcpkg.cmake' to build the makefile. Both result in the same missing headers errors when calling make.
EDIT2
All CMake files were removed from the project (except CMakeLists.txt) before each call to cmake to ensure no values were stored there.
EDIT3
Poked around a bit more. Here is the BulletConfig.cmake file :
#
# BulletConfig.cmake(.in)
#
# Use the following variables to compile and link against Bullet:
# BULLET_FOUND - True if Bullet was found on your system
# BULLET_USE_FILE - The file making Bullet usable
# BULLET_DEFINITIONS - Definitions needed to build with Bullet
# BULLET_INCLUDE_DIR - Directory where Bullet-C-Api.h can be found
# BULLET_INCLUDE_DIRS - List of directories of Bullet and it's dependencies
# BULLET_LIBRARIES - List of libraries to link against Bullet library
# BULLET_LIBRARY_DIRS - List of directories containing Bullet' libraries
# BULLET_ROOT_DIR - The base directory of Bullet
# BULLET_VERSION_STRING - A human-readable string containing the version
set(PACKAGE_PREFIX_DIR /home/ash/installed/x64-linux)
set ( BULLET_FOUND 1 )
set ( BULLET_USE_FILE "${PACKAGE_PREFIX_DIR}/share/bullet3/UseBullet.cmake" )
set ( BULLET_DEFINITIONS "" )
set ( BULLET_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/bullet" )
set ( BULLET_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/bullet" )
set ( BULLET_LIBRARIES "LinearMath;Bullet3Common;BulletInverseDynamics;BulletCollision;BulletDynamics;BulletSoftBody" )
set ( BULLET_LIBRARY_DIRS "${PACKAGE_PREFIX_DIR}/lib" )
set ( BULLET_ROOT_DIR "${PACKAGE_PREFIX_DIR}" )
set ( BULLET_VERSION_STRING "3.17" )
# Load targets
if(NOT TARGET Bullet3Common)
file(GLOB CONFIG_FILES "${PACKAGE_PREFIX_DIR}/share/bullet3/*Targets.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
set(_DIR)
endif()
As stated before a few of the set functions were set_and_check(). So I changed to set() as apparently cmake 3.21 has no set_and_check() function. After a little testing by printing message(), i found that PACKAGE_PREFIX_DIR was not being set anywhere. So that is why I've set it explicitly in this file. The variables are now set correctly as reported by message() in the CMakeLists.txt file. But still it make cannot find the header files.
EDIT4
I created an empty project and ran through each library I wanted to include. Everything works except for Bullet3. However it does now see the header files. What changed between the two CMakeFiles? Nothing as far as I can tell. I'll need to find out because I have to port this project over but in the meantime this is another issue with the package.
from /home/ash/projects/C++/CMakeImportTests/src/main.cpp:22:
/home/ash/vcpkg/installed/x64-linux/include/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h:77:10:
fatal error: LinearMath/btVector3.h: No such file or directory
77 | #include "LinearMath/btVector3.h"
I think this is the same issue as described #7877
If i remove all includes of Bullet but leave the CMakeList.txt untouched, we get this error:
[ 50%] Building CXX object CMakeFiles/main.dir/src/main.cpp.o
[100%] Linking CXX executable main
/usr/bin/ld: cannot find -lLinearMath
/usr/bin/ld: cannot find -lBullet3Common
/usr/bin/ld: cannot find -lBulletDynamics
/usr/bin/ld: cannot find -lBulletSoftBody
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:104: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Is this a clue that some environment variable is not set?
EDIT5
There seems to be an ordering dependency for the target_link_library call. The suggested usage is:
target_link_libraries(main PRIVATE LinearMath Bullet3Common BulletDynamics BulletSoftBody)
Checking bullet.pc in the libs/ directory i found
Libs: -L${libdir} -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
So I tried rearranging and following the pattern:
target_link_libraries(main PRIVATE BulletSoftBody BulletDynamics BulletCollision Bullet3Common LinearMath)
Additionally there was also a need to manually link directories.
target_link_directories(main PRIVATE ${BULLET_LIBRARY_DIRS})
This now compiles without error in my test project. It seems LinearMath must be after most of the other libraries (although it can be before Bullet3Common it seems).
For some reason it's still not finding the header files when I copy the exact same CMake commands over to my main project. So I'm not free of this yet.
I should say that I was able to remove the change I made to BulletConfig.cmake of setting PACKAGE_PREFIX_DIR statically.
So just to recap my issue. A small test project works and I can use bullet and number of other libraries that I use in my main project. But if i copy this working CMakeLists.txt to my main project it can no longer find the headers and throws this error :
btBulletDynamicsCommon.h: No such file or directory
8 | #include <btBulletDynamicsCommon.h>
Bullet_DIR:PATH=/home/ash/vcpkg/installed/x64-linux/share/bullet3 is the same in both cases.
After all that.
The set_and_include() error is a known issue and mathisloge over at vcpkg git said the Bullet package needs to be updated. The workaround is to change the calls to set().
The ordering of the target libraries is important. The suggested way in the Bullet vcpkg package is :
target_link_libraries(main PRIVATE LinearMath Bullet3Common BulletDynamics BulletSoftBody)
But this fails to compile. It should be:
target_link_libraries(main PRIVATE BulletSoftBody BulletDynamics BulletCollision Bullet3Common LinearMath)
Also had to tell cmake the link directories using :
target_link_directories(main PRIVATE ${BULLET_LIBRARY_DIRS})
Then I still had header missing errors. But after a restart things just started working again. Hopefully there is enough here to help someone if they hit similar problems.

Scons Explicit Dependency

I have a simple .cpp file that depends on jsoncpp. As a part of my build process I want Scons to untar jsoncpp (if it isn't already) and build it (if it isn't already) before attempting to compile app.cpp since app.cpp depends on some .h files that are zipped up inside of jsoncpp.tar.gz.
This is what I've tried so far:
env = Environment()
env.Program('app', 'app.cpp')
env.Depends('app.cpp', 'jsoncpp')
def build_jsoncpp(target, source, env):
shutil.rmtree("jsoncpp", ignore_errors=True)
mytar = tarfile.open(str(source[0]))
mytar.extractall()
print("Extracted jsoncpp")
env.Command("jsoncpp", ['jsoncpp.tar.gz'], build_jsoncpp)
However, Scons never prints "Extracted jsoncpp"... it always attempts to compile app.cpp and then promptly fails.
If I were using make, I could simply do something like:
app: jsoncpp.tar.gz
# Build app
jsoncpp.tar.gz:
# Extract and build here
And the order would be guaranteed.
You should take a look at the UnTarBuilder, as a means to extract a tarfile and have all of the extracted files be properly inserted into the dependency tree. But the following will get what you have working.
You want to avoid explicit dependencies, if possible. One of the many joys of SCons is letting it take care of your dependencies for you. So just list the source file you are depending on as one of the targets of your untar command builder.
To test this I created a tar file called jsoncpp.tar.gz containing just one file, app.cpp, with the following contents.
#include <iostream>
int main() {
std::cout << "Hello World" << std::endl;
return 0;
}
And updated your SConstruct to the following.
import shutil
import tarfile
env = Environment()
env.Program('app', 'app.cpp')
def build_jsoncpp(target, source, env):
shutil.rmtree("jsoncpp", ignore_errors=True)
mytar = tarfile.open(str(source[0]))
mytar.extractall()
print("Extracted jsoncpp")
env.Command(["app.cpp"], ['jsoncpp.tar.gz'], build_jsoncpp)
Because you list the required source file you depend on as a target of your command builder, it will handle the dependencies for you.
And when you run, you will see the following.
>> scons --version
SCons by Steven Knight et al.:
script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation
>> tree
.
├── jsoncpp.tar.gz
└── SConstruct
0 directories, 2 files
>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
build_jsoncpp(["app.cpp"], ["jsoncpp.tar.gz"])
Extracted jsoncpp
g++ -o app.o -c app.cpp
g++ -o app app.o
scons: done building targets.
>> tree
.
├── app
├── app.cpp
├── app.o
├── jsoncpp.tar.gz
└── SConstruct
0 directories, 5 files
>> ./app
Hello World
The reason why your code does not work is because you are listing jsoncpp as the target of your untar command builder. Which is not a file that compiling app.cpp will depend on, even if you list that action as an explicit dependency.
While this doesn't exactly answer your question, I hope it provides a solution to what you are trying to accomplish.
It might help if you aligned the name of your builder function with your argument to the Command() method. ;)

Linking GSL library to RcppGSL on Windows machine

I try to link the GSL library to the RcppGSL package. The following is my test function:
# colNorm.cpp
// [[Rcpp::depends(RcppGSL)]]
#include <RcppGSL.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
extern "C" SEXP colNorm(SEXP sM) {
try {
RcppGSL::matrix<double> M = sM; // create gsl data structures from SEXP
int k = M.ncol();
Rcpp::NumericVector n(k); // to store results
for (int j = 0; j < k; j++) {
RcppGSL::vector_view<double> colview = gsl_matrix_column (M, j);
n[j] = gsl_blas_dnrm2(colview);
}
M.free() ;
return n; // return vector
} catch( std::exception &ex ) {
forward_exception_to_r( ex );
} catch(...) {
::Rf_error( "c++ exception (unknown reason)" );
}
return R_NilValue; // -Wall
}
The GSL library is succesfully linked to the RcppGSL if the following command does not throw a compiler error:
sourceCpp("colNorm.cpp")
Since I am using Windows machine, I need to define environment variables such that RcppGSL knows where the GSL library is located.
I tried editing the environment variable, but the following compiler error shows that the package is still unable to find the GSL library:
g++ -m64 -I"C:/PROGRA~1/R/R-31~1.1/include" -DNDEBUG -I"C:/CodeLibrary/lib"/include - I"C:/PROGRA~1/R/R-31~1.1/library/Rcpp/include" -I"C:/PROGRA~1/R/R-31~1.1/library/RcppGSL/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c colNorm.cpp -o colNorm.o
g++ -m64 -shared -s -static-libgcc -o sourceCpp_38624.dll tmp.def colNorm.o -LC:/CodeLibrary/lib/lib -lgsl -lgslcblas -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRblas -lgfortran -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lR
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgsl
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgslcblas
collect2: ld returned 1 exit status
I set an environment variable LIB_GSL equal to "C:/CodeLibrary/lib". In the first line, the compiler takes my environment variable and adds /include. In the second line, the compiler adds /lib. Those locations do not exist on my C drive, maybe that's the reason why it cannot find the library.
I would be really happy, if someone with a lot of compiler experience could show how to successfully link a 3rd party library to a package on Windows machine.
Maybe more environment variables need to be defined?
Thanks Dirk for your handholding! I got it finally up and running.
Three things have to be done:
1) Download the local300 folder from your link and allocate folder on your drive. The path cannot contain any whitespaces, i.e. C:/Program Files/local300 will not work but
C:/local300 will work
2) Set the environment variable LIB_GSL equal to this path, e.g. LIB_GSL to C:/local300
3) The compiler looks at LIB_GSL/lib for libgsl.a and libgslcblas.a (-lgsl and -lgslcblas). However, in LIB_GSL/lib are subfolders i386 and x64. I didn't know how to change the place the compiler looks for the files, thus I copied everything from inside x64 and put it into LIB_GSL/lib folder (one folder level above).
This allows RcppGSL to compile code without errors.
Look at this page which is (after a link or two) pointed to from the R Installation and Administration manual, appendix D for Windows.
Expand that, see where it puts headers and the library for GSL and adjust LIB_GSL accordingly.
This is what CRAN itself uses, so we know it works.

Raspberry Pi bcm_host include directories

I'm trying to write a simple program that uses EGL, but when I include bcm_host.h, gcc says it doesn't exist, so I add /opt/vc/include to the makefile, it says that another header is missing, I add another directory, and now, after 6 folders, I don't really want to do it anymore but gcc wants more. I have looked at the /opt/vc/src/hello_pi/Makefile.include file, and it adds just 3 folders. So the question is: what am I doing wrong?
Here's the makefile:
LIB_DIR = -L/opt/vc/lib
INCLUDE_DIRS = -I/opt/vc/include -I/opt/vc/include/interface/vcos/ -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmc_host/linux -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vchi -I/usr/include/SDL -I-
LIBS = -lSDL
bin:
gcc $(LIB_DIRS) $(INCLUDE_DIRS) $(LIBS) main.c
I included bcm_host.h in a project where I was using code from the dispmax example. I have very similar makefile settings, with the exception that I added -lbcm_host as a library:
# Include the Broadcom hardware interface library
XINCDIR += /opt/vc/include
XINCDIR += /opt/vc/include/interface/vcos/pthreads
XLIBS += -L/opt/vc/lib/ -lbcm_host
That worked for me, although I wasn't trying to use EGL specifically. You probably need -lEGL instead or in addition.

Resources