C++ Why can't the linker see my files? - c++

Building a native module for Node.js under Cygwin / Windows:
I have a monkey.cc file with this:
#include <monkey/monkey.h>
running
node-waf configure build
I get the following
'configure' finished successfully (0.351s)
Waf: Entering directory `/usr/src/build'
[2/2] cxx_link: build/default/monkey_1.o -> build/default/monkey.node build/default/libmonkey.dll.a
Creating library file: default/libmonkey.dll.a
then the following error:
default/monkey_1.o:/usr/src/build/../monkey.cc:144: undefined reference to `_monkeyFoo'
monkeyFoo is defined in monkey.h which is in a directory named monkey. I am running the above command from the directory containing monkey directory and monkey.cc file.
EDIT:
wscript, which is the python script that node-waf runs looks like this:
import os
srcdir = '.'
blddir = './build'
VERSION = '0.0.2'
def set_options(opt):
opt.tool_options('compiler_cxx')
def configure(conf):
conf.check_tool('compiler_cxx')
conf.check_tool('node_addon')
def build(bld):
monkey = bld.new_task_gen('cxx', 'shlib', 'node_addon')
monkey.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-L/usr/lib", "-lssl"]
monkey.chmod = 0755
monkey.target = 'monkey'
monkey.source = 'monkey.cc'
What am I missing???

That's a linker error, not a compiler error. Do you have a definition for the function? (Not just a declaration.) And are you sure it's being linked in?

Add monkey.lib='crypto' in the wscript.

Related

Don't know how to build from a source file with suffix `.yy'. Expected a suffix in this list: ['.lm', '.ll']

I'm having an issue while building packages from source using scons. I'm getting the below exception. If I change the file extension to ll or lm
I get syntax errors while it compiles.
scons -j ${JOBS_COUNT:-$(grep -c processor /proc/cpuinfo || echo 1)} --without-dpdk
scons: Reading SConscript files ...
('Ubuntu', '20.04', 'focal')
('Ubuntu', '20.04', 'focal')
('Ubuntu', '20.04', 'focal')
scons: *** While building `['sandeshy.cc']' from `['/root/salim/src/contrail-common/sandesh/compiler/sandeshy.yy']': Don't know how to build from a source file with suffix `.yy'. Expected a suffix in this list: ['.lm', '.ll'].
Sconscript file
# -*- mode: python; -*-
#
# Created by Megh Bhatt on 07/16/12.
# Copyright (c) 2012 Contrail Systems. All rights reserved.
#
Import('SandeshEnv')
env = SandeshEnv.Clone();
rmflags = ['-Wsign-compare', '-Werror', '-fno-exceptions',
'--coverage']
cflags = env['CCFLAGS']
for flag in rmflags:
if flag in cflags:
cflags.remove(flag)
env['CCFLAGS'] = cflags
env.Append(CPPPATH = ['#src/contrail-common/sandesh/compiler','#build/include'])
# Lex and Yacc
env.Append(YACCFLAGS = '-d')
env['YACCHXXFILESUFFIX'] = '.hh'
#env.Append(LEXFLAGS = '-DSANDESH')
env.CXXFile(target = 'sandeshy.cc', source = 'sandeshy.yy')
env.CXXFile(target = 'sandeshl.cc', source = 'sandeshl.ll')
sandesh = env.Program(target = 'sandesh',
source = ['main.cc',
'md5.c',
'sandeshy.cc',
'sandeshl.cc',
'generate/t_cpp_generator.cc',
'generate/t_html_generator.cc',
'generate/t_generator.cc',
'generate/t_xsd_generator.cc',
'generate/t_c_generator.cc',
'generate/t_py_generator.cc',
'generate/t_doc_generator.cc',
'parse/parse.cc',
])
env.Install(env['TOP_BIN'], sandesh)
I am trying to build packages from opencontrail source files which is got from github repo
sandeshy.yy file located in github repo
You need to install yacc to fix this error, scons is presumably checking what it is able to process, as it can't process yacc files it doesn't add .yy to the list of supported extensions for CXXFile

output 'external/name/x/lib/lib.so' was not created using bazel make

I was trying to follow the example provided by Building Makefile using bazel
post to build an external package in envoy. In the WORKSPACE file I added the following:
new_git_repository(
name = "name",
remote = "remote.git",
build_file = "//foo/bazel/external:x.BUILD",
)
And foo/bazel/external/x.BUILD has the following contents:
load("#rules_foreign_cc//tools/build_defs:make.bzl", "make")
filegroup(
name = "m_srcs",
srcs = glob(["code/**"]),
)
make(
name = "foo_bar",
make_commands = ["make lib"],
lib_source = ":m_srcs",
shared_libraries = ["lib.so"],
)
and I set the visibility in foo/bazel/BUILD as package(default_visibility = ["//visibility:public"])
On executing bazel build -s #name//:foo_bar, I get the error that external/name/x/lib/lib.so was not created.
I checked the bazel-bin/external/name/x/logs/GNUMake.log and make completes successfully. I see that BUILD_TMPDIR directory has created lib.so. I think it should have been copied to EXT_BUILD_DEPS/lib, but I am not sure why it was not copied. Would appreciate any tips to debug the error.
Edited make command to manually copy the lib to expected folder - make_commands = ["make libs; cp lib.so $INSTALLDIR/lib/lib.so"]

bazel WORKSPACE file for external repository leads to missing #includes

I'm trying to set up a workspace file for a project that uses googletest. I'm following the instructions here: https://docs.bazel.build/versions/master/cpp-use-cases.html#including-external-libraries.
I have a WORKSPACE file that looks like this:
new_http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.7.0.zip",
sha256 = "b58cb7547a28b2c718d1e38aee18a3659c9e3ff52440297e965f5edffe34b6d0",
build_file = "gtest.BUILD",
strip_prefix = "googletest-release-1.7.0",
)
I have a BUILD file that looks like this:
COPTS = [
"-I/usr/local/include",
"-Iexternal/gtest/include",
"-Wno-sign-compare",
]
cc_test(
name = "gaussian_test",
srcs = ["gaussian_test.cc"],
copts = COPTS,
deps = [
"//:boom",
"//:boom_test_utils",
"#gtest//:main",
],
)
The #include section of my gaussian_test.cc file includes the line:
#include "gtest/gtest.h"
When I try to run the test I get
Models/tests/gaussian_test.cc:1:10: fatal error: gtest/gtest.h: No such file or directory
#include "gtest/gtest.h"
In my main repository I solve this problem by manually installing googletest in /usr/local, but I'm looking for a more portable solution, and also looking to clear up a fundamental misunderstanding I seem to have about how the WORKSPACE file is supposed to operate. Thanks.
The missing part of my question was the gtest-BUILD file, which contained the missing path information.

making unit test binaries using scons with g++ and gtest

I am not able sucessfully build the the project using scons, g++ and gtest. I want to use gtest as unit test. My project looks like below:
project
| -SConstruct
| -src
| -name.hh
| -name.cc
| -main.cc
| -gtest
| -/src/gtest_name.hh
| -/src/gtest_name.cc
| -/src/gtest_main.cc
Inside SConstruct for project building, I have following code:
program_srcs = ['name.cc']
cpppath = ['./src']
libpath = ['.', 'path_to_third_party_lib']
libs = ['thirdlib']
pro_env = Environment()
env.Append(CPPPATH = cpppath)
env.Append(LIBS = libs)
env.Append(LIBPATH = libpath)
env.Library('name', program_srcs)
libpath.append('name')
env.Append(LIBPATH = libpath)
env.Program(target = 'NAME', source = [ './src/main.cc']
test_src = ['./gtest/src/gtest_name.cc']
test_env = Environment()
test_env['LIBPATH'] = ['.']
test_env.Program("unit_test", test_src, LIBS=['name'])
Inside gtest_name.cc
include"name.hh"
TEST_F(TESTNAME, testmethod) {
Name name;
ASSERT_EQ(name.get_surname, "MIKE");
}
When I tried to compile and build, it gave following errors for gtest.
g++ -o gtest/src/gtest_name.o -c gtest/src/gtest_name.cc
gtest/src/gtest_name.cc:10:29: error: name.hh: No such file or directory
When I checked for library 'name', it was already constructed. Could you please tell me what the problem is?
You have added the required include search path "src" to the variable CPPPATH, for the environment "env".
But you build the library with the environment "test_env" which doesn't have CPPPATH defined.
That's why the "-I" directive is missing in your compiler call.
Note, that SCons offers a Clone() method for environments. It copies over all current definitions (and builders for example) from one environment to create a new one...this might come in handy here.

SCons: How can I attach a listener?

I need to attach to the SCons build in order to be notified when things happened during it: file compilation, files linkage, etc.
I know similar is possible for ANT builds via -listener option. Could you please tell how to do it for SCons builds?
When targets are built in SCons, you can associate a post action via the AddPostAction(target, action) function as documented here.
Here is a simple example with a python function action:
# Create yourAction here:
# can be a python function or external (shell) command line
def helloWorldAction(target = None, source = None, env = None):
'''
target: a Node object representing the target file
source: a Node object representing the source file
env: the construction environment used for building the target file
The target and source arguments may be lists of Node objects if there
is more than one target file or source file.
'''
print "PostAction for target: %s" % str(target)
# you can get a map of the source files like this:
# source_file_names = map(lambda x: str(x), source)
# compilation options, etc can be retrieved from the env
return 0
env = Environment()
progTarget = env.Program(target = "helloWorld", source = "helloWorld.cc")
env.AddPostAction(progTarget, helloWorldAction)
# Or create the action object like this:
# a = Action(helloWorldAction)
Then, each time helloWorld is built, the helloWorldAction python function will be executed afterwords.
Regarding doing this without modifying the given SConstruct, I dont see how that would be possible.