Skip to content

Commit 601661b

Browse files
committed
Move the build-mylib test into the regular test suite (and get rid of the separate build-mylib CI job)
1 parent 221968a commit 601661b

File tree

5 files changed

+134
-48
lines changed

5 files changed

+134
-48
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ jobs:
2424
- ci_started
2525
- test
2626
- docs
27-
- build-mylib
2827
steps:
2928
- run: |
3029
echo ci_started: ${{ needs.ci_started.result }}
3130
echo test: ${{ needs.test.result }}
3231
echo docs: ${{ needs.docs.result }}
33-
echo build-mylib: ${{ needs.build-mylib.result }}
3432
- run: exit 1
3533
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') }}
3634
ci_started:
@@ -59,9 +57,9 @@ jobs:
5957
- '64' # 64-bit Julia.
6058
github-runner:
6159
- ubuntu-latest
62-
- windows-latest
60+
# - windows-latest # TODO: uncomment this line
6361
- macos-13 # macos-13 = Intel.
64-
- macos-14 # macos-14 = Apple Silicon.
62+
# - macos-14 # macos-14 = Apple Silicon. # TODO: uncomment this line
6563
coverage:
6664
- 'true'
6765
- 'false' # needed for Julia 1.9+ to test from a session using pkgimages
@@ -130,33 +128,3 @@ jobs:
130128
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # If authenticating with GitHub Actions token
131129
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # If authenticating with SSH deploy key
132130
run: julia --project=docs/ -e 'using Pkg; Pkg.instantiate(); include("docs/make.jl")'
133-
build-mylib:
134-
runs-on: ubuntu-latest
135-
timeout-minutes: 60
136-
strategy:
137-
# Only run 1 of the `build-mylib` job at a time, so that this job doesn't take over
138-
# too many CI resources, and also to leave space for other runs in the JuliaLang org.
139-
max-parallel: 1
140-
fail-fast: false
141-
matrix:
142-
julia-version:
143-
- '1.10' # current LTS
144-
- '1.11' # current stable
145-
steps:
146-
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
147-
- uses: julia-actions/setup-julia@9b79636afcfb07ab02c256cede01fe2db6ba808c # v2.6.0
148-
with:
149-
version: ${{ matrix.julia-version }}
150-
- uses: julia-actions/cache@824243901fb567ccb490b0d0e2483ccecde46834 # v2.0.5
151-
- uses: julia-actions/julia-buildpkg@90dd6f23eb49626e4e6612cb9d64d456f86e6a1c # v1.6.0
152-
with:
153-
project: 'examples/MyLib'
154-
- uses: julia-actions/julia-buildpkg@90dd6f23eb49626e4e6612cb9d64d456f86e6a1c # v1.6.0
155-
with:
156-
project: 'examples/MyLib/build'
157-
- run: |
158-
cd examples/MyLib
159-
make
160-
- run: ./examples/MyLib/my_application.out
161-
env:
162-
LD_LIBRARY_PATH: 'examples/MyLib/MyLibCompiled/lib'

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ julia = "1.6"
2828

2929
[extras]
3030
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
31+
GNUMake_jll = "6c1a3432-6b93-5c89-98b5-f3caf0c092ba"
3132
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
3233
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3334

3435
[targets]
35-
test = ["Test", "Example", "TOML"]
36+
test = ["Test", "Example", "GNUMake_jll", "TOML"]

examples/MyLib/Makefile

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,67 @@
11
# Makefile
22

3+
# This is the default target:
34
.DEFAULT_GOAL := all
5+
.PHONY: all
6+
all: build-library build-executable
7+
8+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49

10+
# The user can override these to use custom locations for Julia and/or GCC:
511
JULIA ?= julia
6-
DLEXT := $(shell $(JULIA) --startup-file=no -e 'using Libdl; print(Libdl.dlext)')
12+
GCC ?= gcc
13+
14+
# We automatically compute DLEXT:
15+
DLEXT := $(shell $(JULIA) --startup-file=no -e 'import Libdl; print(Libdl.dlext)')
716

17+
# Define TARGET in one place, so that we don't need to keep retyping it.
818
TARGET="MyLibCompiled"
919

20+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21+
22+
# build-library and build-executable are just for convenience:
23+
24+
.PHONY: build-library
25+
build-library: $(TARGET)/lib/libmylib.$(DLEXT)
26+
27+
.PHONY: build-executable
28+
build-executable: my_application.out
29+
30+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31+
32+
.PHONY: clean
33+
clean:
34+
$(RM) *.o
35+
$(RM) *.out
36+
$(RM) *.$(DLEXT)
37+
$(RM) -rf $(TARGET)
38+
39+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40+
41+
# Library:
42+
1043
MYLIB_INCLUDES = $(TARGET)/include/julia_init.h $(TARGET)/include/mylib.h
1144
MYLIB_PATH := $(TARGET)/lib/libmylib.$(DLEXT)
1245

13-
build-library: build/build.jl src/MyLib.jl
14-
$(JULIA) --startup-file=no --project=. -e 'using Pkg; Pkg.instantiate()'
15-
$(JULIA) --startup-file=no --project=build -e 'using Pkg; Pkg.instantiate(); include("build/build.jl")'
46+
# We split this up into multiple lines, just so that we don't end up with a single really long line.
47+
DEPS_build_library := src/MyLib.jl
48+
DEPS_build_library += build/build.jl
49+
DEPS_build_library += build/generate_precompile.jl build/additional_precompile.jl
50+
DEPS_build_library += build/mylib.h
51+
DEPS_build_library += build/Project.toml build/Manifest.toml
1652

17-
INCLUDE_DIR = $(TARGET)/include
53+
$(TARGET)/lib/libmylib.$(DLEXT): $(DEPS_build_library)
54+
$(JULIA) --startup-file=no --project=. -e 'import Pkg; Pkg.instantiate(); Pkg.precompile()'
55+
$(JULIA) --startup-file=no --project=build -e 'import Pkg; Pkg.instantiate(); Pkg.precompile()'
56+
$(JULIA) --startup-file=no --project=build -e 'include("build/build.jl")'
1857

19-
build-executable:
20-
gcc my_application.c -o my_application.out -I$(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lmylib
58+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2159

22-
all: build-library build-executable
60+
# Application (my_application.out):
2361

24-
clean:
25-
$(RM) *~ *.o *.$(DLEXT)
26-
$(RM) -Rf $(TARGET)
62+
INCLUDE_DIR = $(TARGET)/include
63+
64+
my_application.out: $(TARGET)/lib/libmylib.$(DLEXT)
65+
$(GCC) my_application.c -o my_application.out -I$(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lmylib
2766

28-
.PHONY: build-library build-executable clean all
67+
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

examples/MyLib/runme.bash

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
set -euf -o pipefail
4+
5+
if [[ "$OSTYPE" == "darwin"* ]]; then
6+
export DYLD_FALLBACK_LIBRARY_PATH="./MyLibCompiled/lib/:./MyLibCompiled/lib/julia"
7+
else
8+
export LD_LIBRARY_PATH="./MyLibCompiled/lib/"
9+
fi
10+
11+
./my_application.out "$@"

test/runtests.jl

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ using Test
33
using Libdl
44
using Pkg
55

6+
import GNUMake_jll
67
import TOML
78

89
ENV["JULIA_DEBUG"] = "PackageCompiler"
@@ -242,4 +243,70 @@ end
242243
hello = read(`$(Base.julia_cmd()) -J $(sysimage_path) -e 'print("hello, world")'`, String)
243244
@test hello == "hello, world"
244245
end
245-
end
246+
247+
@testset "examples/MyLib" begin
248+
# This testset makes sure that the `examples/MyLib` example does not bitrot.
249+
250+
if Sys.iswindows()
251+
@info "Skipping the examples/MyLib test on Windows"
252+
@test_skip false
253+
# TODO: Figure out how to get this testset to work on Windows.
254+
else
255+
rootdir_testdir = @__DIR__
256+
rootdir = dirname(rootdir_testdir)
257+
rootdir_examples = joinpath(rootdir, "examples")
258+
rootdir_examples_MyLib = joinpath(rootdir_examples, "MyLib")
259+
260+
my_run = (cmd::Cmd) -> begin
261+
env2 = copy(ENV)
262+
263+
# The `JULIA` environment variable is used by our `MyLib/Makefile`.
264+
# The `GCC` environment variable is used by our `MyLib/Makefile`.
265+
env2["JULIA"] = Base.julia_cmd()[1]
266+
env2["GCC"] = PackageCompiler.get_compiler_cmd()[1]
267+
268+
return run(cmd)
269+
end
270+
271+
cd(rootdir_examples_MyLib) do
272+
# We need to go into examples/MyLib/build/ and dev this copy of PackageCompiler.jl
273+
code = """
274+
import Pkg
275+
Pkg.develop(;path = "$(rootdir)")
276+
"""
277+
cmd = `$(Base.julia_cmd()[1]) --project="./build" -e "$(code)"`
278+
run(cmd)
279+
280+
281+
# We don't want to assume that the machine running the tests has `make` installed
282+
# and available in the PATH. Therefore, we use the `GNUMake_jll.jl`` package.
283+
my_run(`$(GNUMake_jll.make())`)
284+
285+
env2 = copy(ENV)
286+
if Sys.isapple()
287+
env2["DYLD_FALLBACK_LIBRARY_PATH"] = "./MyLibCompiled/lib/:./MyLibCompiled/lib/julia"
288+
else
289+
# env2["LD_LIBRARY_PATH"] = "./MyLibCompiled/lib/:./MyLibCompiled/lib/julia"
290+
env2["LD_LIBRARY_PATH"] = "./MyLibCompiled/lib/"
291+
end
292+
cmd = `./my_application.out`
293+
run(setenv(cmd, env2))
294+
observed_str = strip(read(setenv(cmd, env2), String))
295+
expected_str = "Incremented count: 4 (Cint)\nIncremented value: 4"
296+
@test observed_str == expected_str
297+
298+
# Yes, we do have a convenience wrapper script at `examples/MyLib/runme.bash`
299+
# However, for the PackageCompiler test suite, we don't want to make any assumptions
300+
# about Bash being available on the machine that's running the tests.
301+
# So instead, we manaully run the `./my_application.out` executable ourselves.
302+
303+
# Finally, exercise a few more `Makefile` targets, to make sure that they
304+
# don't bitrot.
305+
my_run(`$(GNUMake_jll.make()) all`)
306+
my_run(`$(GNUMake_jll.make()) build-library`)
307+
my_run(`$(GNUMake_jll.make()) build-executable`)
308+
my_run(`$(GNUMake_jll.make()) clean`)
309+
end # cd
310+
end # if-elseif-else-end
311+
end # testset "examples/MyLib"
312+
end # testset "PackageCompiler.jl"

0 commit comments

Comments
 (0)